~sinzui/ubuntu/vivid/juju-core/vivid-1.24.6

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/apiserver/uniter/uniter_base.go

  • Committer: Curtis Hovey
  • Date: 2015-09-30 14:14:54 UTC
  • mfrom: (1.1.34)
  • Revision ID: curtis@hovey.name-20150930141454-o3ldf23dzyjio6c0
Backport of 1.24.6 from wily. (LP: #1500916)

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
        "fmt"
10
10
        "net/url"
11
11
        "path"
12
 
        "time"
13
12
 
14
13
        "github.com/juju/errors"
15
14
        "github.com/juju/names"
16
 
        "gopkg.in/juju/charm.v4"
 
15
        "gopkg.in/juju/charm.v5"
17
16
 
18
17
        "github.com/juju/juju/apiserver/common"
 
18
        leadershipapiserver "github.com/juju/juju/apiserver/leadership"
19
19
        "github.com/juju/juju/apiserver/params"
 
20
        "github.com/juju/juju/leadership"
20
21
        "github.com/juju/juju/network"
21
22
        "github.com/juju/juju/state"
22
23
        "github.com/juju/juju/state/multiwatcher"
27
28
// and it's intended for embedding.
28
29
type uniterBaseAPI struct {
29
30
        *common.LifeGetter
30
 
        *common.StatusSetter
 
31
        *StatusAPI
31
32
        *common.DeadEnsurer
32
33
        *common.AgentEntityWatcher
33
34
        *common.APIAddresser
34
35
        *common.EnvironWatcher
35
36
        *common.RebootRequester
 
37
        *leadershipapiserver.LeadershipSettingsAccessor
36
38
 
37
39
        st            *state.State
38
40
        auth          common.Authorizer
93
95
 
94
96
        accessUnitOrService := common.AuthEither(accessUnit, accessService)
95
97
        return &uniterBaseAPI{
96
 
                LifeGetter:         common.NewLifeGetter(st, accessUnitOrService),
97
 
                StatusSetter:       common.NewStatusSetter(st, accessUnit),
98
 
                DeadEnsurer:        common.NewDeadEnsurer(st, accessUnit),
99
 
                AgentEntityWatcher: common.NewAgentEntityWatcher(st, resources, accessUnitOrService),
100
 
                APIAddresser:       common.NewAPIAddresser(st, resources),
101
 
                EnvironWatcher:     common.NewEnvironWatcher(st, resources, authorizer),
102
 
                RebootRequester:    common.NewRebootRequester(st, accessMachine),
 
98
                LifeGetter:                 common.NewLifeGetter(st, accessUnitOrService),
 
99
                DeadEnsurer:                common.NewDeadEnsurer(st, accessUnit),
 
100
                AgentEntityWatcher:         common.NewAgentEntityWatcher(st, resources, accessUnitOrService),
 
101
                APIAddresser:               common.NewAPIAddresser(st, resources),
 
102
                EnvironWatcher:             common.NewEnvironWatcher(st, resources, authorizer),
 
103
                RebootRequester:            common.NewRebootRequester(st, accessMachine),
 
104
                LeadershipSettingsAccessor: leadershipSettingsAccessorFactory(st, resources, authorizer),
 
105
 
 
106
                // TODO(fwereade): so *every* unit should be allowed to
 
107
                // get/set its own status *and* its service's? FFS.
 
108
                StatusAPI: NewStatusAPI(st, accessUnitOrService),
103
109
 
104
110
                st:            st,
105
111
                auth:          authorizer,
825
831
        return results, nil
826
832
}
827
833
 
 
834
// BeginActions marks the actions represented by the passed in Tags as running.
 
835
func (u *uniterBaseAPI) BeginActions(args params.Entities) (params.ErrorResults, error) {
 
836
        nothing := params.ErrorResults{}
 
837
 
 
838
        actionFn, err := u.authAndActionFromTagFn()
 
839
        if err != nil {
 
840
                return nothing, err
 
841
        }
 
842
 
 
843
        results := params.ErrorResults{Results: make([]params.ErrorResult, len(args.Entities))}
 
844
 
 
845
        for i, arg := range args.Entities {
 
846
                action, err := actionFn(arg.Tag)
 
847
                if err != nil {
 
848
                        results.Results[i].Error = common.ServerError(err)
 
849
                        continue
 
850
                }
 
851
 
 
852
                _, err = action.Begin()
 
853
                if err != nil {
 
854
                        results.Results[i].Error = common.ServerError(err)
 
855
                        continue
 
856
                }
 
857
        }
 
858
 
 
859
        return results, nil
 
860
}
 
861
 
828
862
// FinishActions saves the result of a completed Action
829
863
func (u *uniterBaseAPI) FinishActions(args params.ActionExecutionResults) (params.ErrorResults, error) {
830
864
        nothing := params.ErrorResults{}
1027
1061
 
1028
1062
// ReadSettings returns the local settings of each given set of
1029
1063
// relation/unit.
1030
 
func (u *uniterBaseAPI) ReadSettings(args params.RelationUnits) (params.RelationSettingsResults, error) {
1031
 
        result := params.RelationSettingsResults{
1032
 
                Results: make([]params.RelationSettingsResult, len(args.RelationUnits)),
 
1064
func (u *uniterBaseAPI) ReadSettings(args params.RelationUnits) (params.SettingsResults, error) {
 
1065
        result := params.SettingsResults{
 
1066
                Results: make([]params.SettingsResult, len(args.RelationUnits)),
1033
1067
        }
1034
1068
        canAccess, err := u.accessUnit()
1035
1069
        if err != nil {
1036
 
                return params.RelationSettingsResults{}, err
 
1070
                return params.SettingsResults{}, err
1037
1071
        }
1038
1072
        for i, arg := range args.RelationUnits {
1039
1073
                unit, err := names.ParseUnitTag(arg.Unit)
1056
1090
 
1057
1091
// ReadRemoteSettings returns the remote settings of each given set of
1058
1092
// relation/local unit/remote unit.
1059
 
func (u *uniterBaseAPI) ReadRemoteSettings(args params.RelationUnitPairs) (params.RelationSettingsResults, error) {
1060
 
        result := params.RelationSettingsResults{
1061
 
                Results: make([]params.RelationSettingsResult, len(args.RelationUnitPairs)),
 
1093
func (u *uniterBaseAPI) ReadRemoteSettings(args params.RelationUnitPairs) (params.SettingsResults, error) {
 
1094
        result := params.SettingsResults{
 
1095
                Results: make([]params.SettingsResult, len(args.RelationUnitPairs)),
1062
1096
        }
1063
1097
        canAccess, err := u.accessUnit()
1064
1098
        if err != nil {
1065
 
                return params.RelationSettingsResults{}, err
 
1099
                return params.SettingsResults{}, err
1066
1100
        }
1067
1101
        for i, arg := range args.RelationUnitPairs {
1068
1102
                unit, err := names.ParseUnitTag(arg.LocalUnit)
1178
1212
        return result, nil
1179
1213
}
1180
1214
 
1181
 
// AddMetrics adds the metrics for the specified unit.
1182
 
func (u *uniterBaseAPI) AddMetrics(args params.MetricsParams) (params.ErrorResults, error) {
1183
 
        result := params.ErrorResults{
1184
 
                Results: make([]params.ErrorResult, len(args.Metrics)),
1185
 
        }
1186
 
        canAccess, err := u.accessUnit()
1187
 
        if err != nil {
1188
 
                return params.ErrorResults{}, common.ErrPerm
1189
 
        }
1190
 
        for i, unitMetrics := range args.Metrics {
1191
 
                tag, err := names.ParseUnitTag(unitMetrics.Tag)
1192
 
                if err != nil {
1193
 
                        result.Results[i].Error = common.ServerError(common.ErrPerm)
1194
 
                        continue
1195
 
                }
1196
 
                err = common.ErrPerm
1197
 
                if canAccess(tag) {
1198
 
                        var unit *state.Unit
1199
 
                        unit, err = u.getUnit(tag)
1200
 
                        if err == nil {
1201
 
                                metricBatch := make([]state.Metric, len(unitMetrics.Metrics))
1202
 
                                for j, metric := range unitMetrics.Metrics {
1203
 
                                        // TODO (tasdomas) 2014-08-26: set credentials for metrics when available
1204
 
                                        metricBatch[j] = state.Metric{
1205
 
                                                Key:   metric.Key,
1206
 
                                                Value: metric.Value,
1207
 
                                                Time:  metric.Time,
1208
 
                                        }
1209
 
                                }
1210
 
                                _, err = unit.AddMetrics(time.Now(), metricBatch)
1211
 
                        }
1212
 
                }
1213
 
                result.Results[i].Error = common.ServerError(err)
1214
 
        }
1215
 
        return result, nil
1216
 
}
1217
 
 
1218
1215
// GetMeterStatus returns meter status information for each unit.
1219
1216
func (u *uniterBaseAPI) GetMeterStatus(args params.Entities) (params.MeterStatusResults, error) {
1220
1217
        result := params.MeterStatusResults{
1231
1228
                        continue
1232
1229
                }
1233
1230
                err = common.ErrPerm
1234
 
                var code string
1235
 
                var info string
 
1231
                var status state.MeterStatus
1236
1232
                if canAccess(unitTag) {
1237
1233
                        var unit *state.Unit
1238
1234
                        unit, err = u.getUnit(unitTag)
1239
1235
                        if err == nil {
1240
 
                                code, info, err = unit.GetMeterStatus()
 
1236
                                status, err = unit.GetMeterStatus()
1241
1237
                        }
 
1238
                        result.Results[i].Code = status.Code.String()
 
1239
                        result.Results[i].Info = status.Info
1242
1240
                }
1243
 
                result.Results[i].Code = code
1244
 
                result.Results[i].Info = info
1245
1241
                result.Results[i].Error = common.ServerError(err)
1246
1242
        }
1247
1243
        return result, nil
1473
1469
                return "", common.ErrPerm
1474
1470
        }
1475
1471
        remoteUnitName := tag.Id()
1476
 
        remoteServiceName := names.UnitService(remoteUnitName)
 
1472
        remoteServiceName, err := names.UnitService(remoteUnitName)
 
1473
        if err != nil {
 
1474
                return "", common.ErrPerm
 
1475
        }
1477
1476
        rel := relUnit.Relation()
1478
1477
        _, err = rel.RelatedEndpoints(remoteServiceName)
1479
1478
        if err != nil {
1519
1518
        }, nil
1520
1519
}
1521
1520
 
1522
 
func convertRelationSettings(settings map[string]interface{}) (params.RelationSettings, error) {
1523
 
        result := make(params.RelationSettings)
 
1521
func convertRelationSettings(settings map[string]interface{}) (params.Settings, error) {
 
1522
        result := make(params.Settings)
1524
1523
        for k, v := range settings {
1525
1524
                // All relation settings should be strings.
1526
1525
                sval, ok := v.(string)
1543
1542
        }
1544
1543
        return tags, nil
1545
1544
}
 
1545
 
 
1546
func leadershipSettingsAccessorFactory(
 
1547
        st *state.State,
 
1548
        resources *common.Resources,
 
1549
        auth common.Authorizer,
 
1550
) *leadershipapiserver.LeadershipSettingsAccessor {
 
1551
        registerWatcher := func(serviceId string) (string, error) {
 
1552
                service, err := st.Service(serviceId)
 
1553
                if err != nil {
 
1554
                        return "", err
 
1555
                }
 
1556
                w := service.WatchLeaderSettings()
 
1557
                if _, ok := <-w.Changes(); ok {
 
1558
                        return resources.Register(w), nil
 
1559
                }
 
1560
                return "", watcher.EnsureErr(w)
 
1561
        }
 
1562
        getSettings := func(serviceId string) (map[string]string, error) {
 
1563
                service, err := st.Service(serviceId)
 
1564
                if err != nil {
 
1565
                        return nil, err
 
1566
                }
 
1567
                return service.LeaderSettings()
 
1568
        }
 
1569
        writeSettings := func(token leadership.Token, serviceId string, settings map[string]string) error {
 
1570
                service, err := st.Service(serviceId)
 
1571
                if err != nil {
 
1572
                        return err
 
1573
                }
 
1574
                return service.UpdateLeaderSettings(token, settings)
 
1575
        }
 
1576
        return leadershipapiserver.NewLeadershipSettingsAccessor(
 
1577
                auth,
 
1578
                registerWatcher,
 
1579
                getSettings,
 
1580
                st.LeadershipChecker().LeadershipCheck,
 
1581
                writeSettings,
 
1582
        )
 
1583
}