// New creates a Facade backed by backend and resources. If auth // doesn't identity the client as a machine agent or a unit agent, // it will return common.ErrPerm. func New(backend Backend, resources *common.Resources, auth common.Authorizer) (*Facade, error) { if !auth.AuthMachineAgent() && !auth.AuthUnitAgent() { return nil, common.ErrPerm } return &Facade{ backend: backend, resources: resources, }, nil }
// NewAPIWithBacking creates a new server-side API facade with the given Backing. func NewAPIWithBacking(st Backend, resources *common.Resources, authorizer common.Authorizer) (*ProxyUpdaterAPI, error) { if !(authorizer.AuthMachineAgent() || authorizer.AuthUnitAgent()) { return &ProxyUpdaterAPI{}, common.ErrPerm } return &ProxyUpdaterAPI{ backend: st, resources: resources, authorizer: authorizer, }, nil }
// NewLoggerAPI creates a new server-side logger API end point. func NewLoggerAPI( st *state.State, resources *common.Resources, authorizer common.Authorizer, ) (*LoggerAPI, error) { if !authorizer.AuthMachineAgent() && !authorizer.AuthUnitAgent() { return nil, common.ErrPerm } return &LoggerAPI{state: st, resources: resources, authorizer: authorizer}, nil }
// NewLeadershipService constructs a new LeadershipService. func NewLeadershipService( claimer leadership.Claimer, authorizer common.Authorizer, ) (LeadershipService, error) { if !authorizer.AuthUnitAgent() { return nil, errors.Unauthorizedf("permission denied") } return &leadershipService{ claimer: claimer, authorizer: authorizer, }, nil }
// NewRsyslogAPI creates a new instance of the Rsyslog API. func NewRsyslogAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*RsyslogAPI, error) { if !authorizer.AuthMachineAgent() && !authorizer.AuthUnitAgent() { return nil, common.ErrPerm } return &RsyslogAPI{ EnvironWatcher: common.NewEnvironWatcher(st, resources, authorizer), st: st, authorizer: authorizer, resources: resources, canModify: authorizer.AuthEnvironManager(), StateAddresser: common.NewStateAddresser(st), }, nil }
// NewMetricsAdderAPI creates a new API endpoint for adding metrics to state. func NewMetricsAdderAPI( st *state.State, resources *common.Resources, authorizer common.Authorizer, ) (*MetricsAdderAPI, error) { // TODO(cmars): remove unit agent auth, once worker/metrics/sender manifold // can be righteously relocated to machine agent. if !authorizer.AuthMachineAgent() && !authorizer.AuthUnitAgent() { return nil, common.ErrPerm } return &MetricsAdderAPI{ state: st, }, nil }
// NewAPI returns an object implementing an agent API // with the given authorizer representing the currently logged in client. func NewAPI(st *state.State, resources *common.Resources, auth common.Authorizer) (*API, error) { // Agents are defined to be any user that's not a client user. if !auth.AuthMachineAgent() && !auth.AuthUnitAgent() { return nil, common.ErrPerm } getCanChange := func() (common.AuthFunc, error) { return auth.AuthOwner, nil } return &API{ PasswordChanger: common.NewPasswordChanger(st, getCanChange), st: st, auth: auth, }, nil }
// NewAPI creates a new API server endpoint for the model migration // master worker. func NewAPI( st *state.State, resources *common.Resources, authorizer common.Authorizer, ) (*API, error) { if !(authorizer.AuthMachineAgent() || authorizer.AuthUnitAgent()) { return nil, common.ErrPerm } return &API{ backend: getBackend(st), authorizer: authorizer, resources: resources, }, nil }
// NewRetryStrategyAPI creates a new API endpoint for getting retry strategies. func NewRetryStrategyAPI( st *state.State, resources *common.Resources, authorizer common.Authorizer, ) (*RetryStrategyAPI, error) { if !authorizer.AuthUnitAgent() { return nil, common.ErrPerm } return &RetryStrategyAPI{ st: st, accessUnit: func() (common.AuthFunc, error) { return authorizer.AuthOwner, nil }, resources: resources, }, nil }
// NewLeadershipService constructs a new LeadershipService. func NewLeadershipService( state *state.State, resources *common.Resources, authorizer common.Authorizer, leadershipMgr leadership.LeadershipManager, ) (LeadershipService, error) { if !authorizer.AuthUnitAgent() { return nil, common.ErrPerm } return &leadershipService{ state: state, authorizer: authorizer, LeadershipManager: leadershipMgr, }, nil }
// NewUnitUpgraderAPI creates a new server-side UnitUpgraderAPI facade. func NewUnitUpgraderAPI( st *state.State, resources *common.Resources, authorizer common.Authorizer, ) (*UnitUpgraderAPI, error) { if !authorizer.AuthUnitAgent() { return nil, common.ErrPerm } getCanWrite := func() (common.AuthFunc, error) { return authorizer.AuthOwner, nil } return &UnitUpgraderAPI{ ToolsSetter: common.NewToolsSetter(st, getCanWrite), st: st, resources: resources, authorizer: authorizer, }, nil }
func newMigrationStatusWatcher( st *state.State, resources *common.Resources, auth common.Authorizer, id string, ) (interface{}, error) { if !(auth.AuthMachineAgent() || auth.AuthUnitAgent()) { return nil, common.ErrPerm } w, ok := resources.Get(id).(state.NotifyWatcher) if !ok { return nil, common.ErrUnknownWatcher } return &srvMigrationStatusWatcher{ watcher: w, id: id, resources: resources, st: getMigrationBackend(st), }, nil }
// NewUniterAPI creates a new instance of the Uniter API. func NewUniterAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*UniterAPI, error) { if !authorizer.AuthUnitAgent() { return nil, common.ErrPerm } 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) } } accessUnitOrService := common.AuthEither(accessUnit, accessService) return &UniterAPI{ LifeGetter: common.NewLifeGetter(st, accessUnitOrService), StatusSetter: common.NewStatusSetter(st, accessUnit), DeadEnsurer: common.NewDeadEnsurer(st, accessUnit), AgentEntityWatcher: common.NewAgentEntityWatcher(st, resources, accessUnitOrService), APIAddresser: common.NewAPIAddresser(st, resources), EnvironWatcher: common.NewEnvironWatcher(st, resources, authorizer), st: st, auth: authorizer, resources: resources, accessUnit: accessUnit, accessService: accessService, }, nil }
// NewUniterAPIV3 creates a new instance of the Uniter API, version 3. func NewUniterAPIV3(st *state.State, resources *common.Resources, authorizer common.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) } 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) { 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 }
func isAgent(auth common.Authorizer) bool { return auth.AuthMachineAgent() || auth.AuthUnitAgent() }
// 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), StatusAPI: NewStatusAPI(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), st: st, auth: authorizer, resources: resources, accessUnit: accessUnit, accessService: accessService, unit: unit, }, nil }