14
13
"github.com/juju/errors"
15
14
"github.com/juju/names"
16
"gopkg.in/juju/charm.v4"
15
"gopkg.in/juju/charm.v5"
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"
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),
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),
105
111
auth: authorizer,
825
831
return results, nil
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{}
838
actionFn, err := u.authAndActionFromTagFn()
843
results := params.ErrorResults{Results: make([]params.ErrorResult, len(args.Entities))}
845
for i, arg := range args.Entities {
846
action, err := actionFn(arg.Tag)
848
results.Results[i].Error = common.ServerError(err)
852
_, err = action.Begin()
854
results.Results[i].Error = common.ServerError(err)
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{}
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)),
1034
1068
canAccess, err := u.accessUnit()
1035
1069
if err != nil {
1036
return params.RelationSettingsResults{}, err
1070
return params.SettingsResults{}, err
1038
1072
for i, arg := range args.RelationUnits {
1039
1073
unit, err := names.ParseUnitTag(arg.Unit)
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)),
1063
1097
canAccess, err := u.accessUnit()
1064
1098
if err != nil {
1065
return params.RelationSettingsResults{}, err
1099
return params.SettingsResults{}, err
1067
1101
for i, arg := range args.RelationUnitPairs {
1068
1102
unit, err := names.ParseUnitTag(arg.LocalUnit)
1178
1212
return result, nil
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)),
1186
canAccess, err := u.accessUnit()
1188
return params.ErrorResults{}, common.ErrPerm
1190
for i, unitMetrics := range args.Metrics {
1191
tag, err := names.ParseUnitTag(unitMetrics.Tag)
1193
result.Results[i].Error = common.ServerError(common.ErrPerm)
1196
err = common.ErrPerm
1198
var unit *state.Unit
1199
unit, err = u.getUnit(tag)
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{
1206
Value: metric.Value,
1210
_, err = unit.AddMetrics(time.Now(), metricBatch)
1213
result.Results[i].Error = common.ServerError(err)
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{
1233
1230
err = common.ErrPerm
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()
1238
result.Results[i].Code = status.Code.String()
1239
result.Results[i].Info = status.Info
1243
result.Results[i].Code = code
1244
result.Results[i].Info = info
1245
1241
result.Results[i].Error = common.ServerError(err)
1247
1243
return result, nil
1473
1469
return "", common.ErrPerm
1475
1471
remoteUnitName := tag.Id()
1476
remoteServiceName := names.UnitService(remoteUnitName)
1472
remoteServiceName, err := names.UnitService(remoteUnitName)
1474
return "", common.ErrPerm
1477
1476
rel := relUnit.Relation()
1478
1477
_, err = rel.RelatedEndpoints(remoteServiceName)
1479
1478
if err != nil {
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)
1544
1543
return tags, nil
1546
func leadershipSettingsAccessorFactory(
1548
resources *common.Resources,
1549
auth common.Authorizer,
1550
) *leadershipapiserver.LeadershipSettingsAccessor {
1551
registerWatcher := func(serviceId string) (string, error) {
1552
service, err := st.Service(serviceId)
1556
w := service.WatchLeaderSettings()
1557
if _, ok := <-w.Changes(); ok {
1558
return resources.Register(w), nil
1560
return "", watcher.EnsureErr(w)
1562
getSettings := func(serviceId string) (map[string]string, error) {
1563
service, err := st.Service(serviceId)
1567
return service.LeaderSettings()
1569
writeSettings := func(token leadership.Token, serviceId string, settings map[string]string) error {
1570
service, err := st.Service(serviceId)
1574
return service.UpdateLeaderSettings(token, settings)
1576
return leadershipapiserver.NewLeadershipSettingsAccessor(
1580
st.LeadershipChecker().LeadershipCheck,