// NewRebootAPI creates a new server-side RebootAPI facade. func NewRebootAPI(st *state.State, resources *common.Resources, auth common.Authorizer) (*RebootAPI, error) { if !auth.AuthMachineAgent() { return nil, common.ErrPerm } tag, ok := auth.GetAuthTag().(names.MachineTag) if !ok { return nil, errors.Errorf("Expected names.MachineTag, got %T", auth.GetAuthTag()) } machine, err := st.Machine(tag.Id()) if err != nil { return nil, errors.Trace(err) } canAccess := func() (common.AuthFunc, error) { return auth.AuthOwner, nil } return &RebootAPI{ RebootActionGetter: common.NewRebootActionGetter(st, canAccess), RebootRequester: common.NewRebootRequester(st, canAccess), RebootFlagClearer: common.NewRebootFlagClearer(st, canAccess), st: st, machine: machine, resources: resources, auth: auth, }, nil }
// NewUniterAPIV4 creates a new instance of the Uniter API, version 3. func NewUniterAPIV4(st *state.State, resources facade.Resources, authorizer facade.Authorizer) (*UniterAPIV3, error) { if !authorizer.AuthUnitAgent() { return nil, common.ErrPerm } var unit *state.Unit var err error switch tag := authorizer.GetAuthTag().(type) { case names.UnitTag: unit, err = st.Unit(tag.Id()) if err != nil { return nil, errors.Trace(err) } default: return nil, errors.Errorf("expected names.UnitTag, got %T", tag) } accessUnit := func() (common.AuthFunc, error) { return authorizer.AuthOwner, nil } accessService := func() (common.AuthFunc, error) { switch tag := authorizer.GetAuthTag().(type) { case names.UnitTag: entity, err := st.Unit(tag.Id()) if err != nil { return nil, errors.Trace(err) } applicationName := entity.ApplicationName() applicationTag := names.NewApplicationTag(applicationName) return func(tag names.Tag) bool { return tag == applicationTag }, nil default: return nil, errors.Errorf("expected names.UnitTag, got %T", tag) } } accessMachine := func() (common.AuthFunc, error) { switch tag := authorizer.GetAuthTag().(type) { case names.UnitTag: entity, err := st.Unit(tag.Id()) if err != nil { return nil, errors.Trace(err) } machineId, err := entity.AssignedMachineId() if err != nil { return nil, errors.Trace(err) } machineTag := names.NewMachineTag(machineId) return func(tag names.Tag) bool { return tag == machineTag }, nil default: return nil, errors.Errorf("expected names.UnitTag, got %T", tag) } } storageAPI, err := newStorageAPI(getStorageState(st), resources, accessUnit) if err != nil { return nil, err } msAPI, err := meterstatus.NewMeterStatusAPI(st, resources, authorizer) if err != nil { return nil, errors.Annotate(err, "could not create meter status API handler") } accessUnitOrService := common.AuthEither(accessUnit, accessService) return &UniterAPIV3{ LifeGetter: common.NewLifeGetter(st, accessUnitOrService), DeadEnsurer: common.NewDeadEnsurer(st, accessUnit), AgentEntityWatcher: common.NewAgentEntityWatcher(st, resources, accessUnitOrService), APIAddresser: common.NewAPIAddresser(st, resources), ModelWatcher: common.NewModelWatcher(st, resources, authorizer), RebootRequester: common.NewRebootRequester(st, accessMachine), LeadershipSettingsAccessor: leadershipSettingsAccessorFactory(st, resources, authorizer), MeterStatus: msAPI, // TODO(fwereade): so *every* unit should be allowed to get/set its // own status *and* its service's? This is not a pleasing arrangement. StatusAPI: NewStatusAPI(st, accessUnitOrService), st: st, auth: authorizer, resources: resources, accessUnit: accessUnit, accessService: accessService, accessMachine: accessMachine, unit: unit, StorageAPI: *storageAPI, }, nil }
// newUniterBaseAPI creates a new instance of the uniter base API. func newUniterBaseAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*uniterBaseAPI, error) { if !authorizer.AuthUnitAgent() { return nil, common.ErrPerm } var unit *state.Unit var err error switch tag := authorizer.GetAuthTag().(type) { case names.UnitTag: unit, err = st.Unit(tag.Id()) if err != nil { return nil, errors.Trace(err) } default: return nil, errors.Errorf("expected names.UnitTag, got %T", tag) } accessUnit := func() (common.AuthFunc, error) { return authorizer.AuthOwner, nil } accessService := func() (common.AuthFunc, error) { switch tag := authorizer.GetAuthTag().(type) { case names.UnitTag: entity, err := st.Unit(tag.Id()) if err != nil { return nil, errors.Trace(err) } serviceName := entity.ServiceName() serviceTag := names.NewServiceTag(serviceName) return func(tag names.Tag) bool { return tag == serviceTag }, nil default: return nil, errors.Errorf("expected names.UnitTag, got %T", tag) } } accessMachine := func() (common.AuthFunc, error) { machineId, err := unit.AssignedMachineId() if err != nil { return nil, errors.Trace(err) } machine, err := st.Machine(machineId) if err != nil { return nil, errors.Trace(err) } return func(tag names.Tag) bool { return tag == machine.Tag() }, nil } accessUnitOrService := common.AuthEither(accessUnit, accessService) return &uniterBaseAPI{ LifeGetter: common.NewLifeGetter(st, accessUnitOrService), DeadEnsurer: common.NewDeadEnsurer(st, accessUnit), AgentEntityWatcher: common.NewAgentEntityWatcher(st, resources, accessUnitOrService), APIAddresser: common.NewAPIAddresser(st, resources), EnvironWatcher: common.NewEnvironWatcher(st, resources, authorizer), RebootRequester: common.NewRebootRequester(st, accessMachine), LeadershipSettingsAccessor: leadershipSettingsAccessorFactory(st, resources, authorizer), // TODO(fwereade): so *every* unit should be allowed to get/set its // own status *and* its service's? This is not a pleasing arrangement. StatusAPI: NewStatusAPI(st, accessUnitOrService), st: st, auth: authorizer, resources: resources, accessUnit: accessUnit, accessService: accessService, unit: unit, }, nil }