// NewKeyManagerAPI creates a new server-side keyupdater API end point. func NewKeyManagerAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*KeyManagerAPI, error) { // Only clients and environment managers can access the key manager service. if !authorizer.AuthClient() && !authorizer.AuthEnvironManager() { return nil, common.ErrPerm } // TODO(wallyworld) - replace stub with real canRead function // For now, only admins can read authorised ssh keys. canRead := func(_ string) bool { return authorizer.GetAuthTag() == adminUser } // TODO(wallyworld) - replace stub with real canWrite function // For now, only admins can write authorised ssh keys for users. // Machine agents can write the juju-system-key. canWrite := func(user string) bool { // Are we a machine agent writing the Juju system key. if user == config.JujuSystemKey { _, ismachinetag := authorizer.GetAuthTag().(names.MachineTag) return ismachinetag } // Are we writing the auth key for a user. if _, err := st.User(user); err != nil { return false } return authorizer.GetAuthTag() == adminUser } return &KeyManagerAPI{ state: st, resources: resources, authorizer: authorizer, canRead: canRead, canWrite: canWrite}, nil }
// NewAPI creates a new instance of the Backups API facade. func NewAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*API, error) { if !authorizer.AuthClient() { return nil, errors.Trace(common.ErrPerm) } // Get the backup paths. dataDir, err := extractResourceValue(resources, "dataDir") if err != nil { return nil, errors.Trace(err) } logsDir, err := extractResourceValue(resources, "logDir") if err != nil { return nil, errors.Trace(err) } paths := backups.Paths{ DataDir: dataDir, LogsDir: logsDir, } // Build the API. machineID, err := extractResourceValue(resources, "machineID") if err != nil { return nil, errors.Trace(err) } b := API{ st: st, paths: &paths, machineID: machineID, } return &b, nil }
// NewControllerAPI creates a new api server endpoint for managing // environments. func NewControllerAPI( st *state.State, resources *common.Resources, authorizer common.Authorizer, ) (*ControllerAPI, error) { if !authorizer.AuthClient() { return nil, errors.Trace(common.ErrPerm) } // Since we know this is a user tag (because AuthClient is true), // we just do the type assertion to the UserTag. apiUser, _ := authorizer.GetAuthTag().(names.UserTag) isAdmin, err := st.IsControllerAdministrator(apiUser) if err != nil { return nil, errors.Trace(err) } // The entire end point is only accessible to controller administrators. if !isAdmin { return nil, errors.Trace(common.ErrPerm) } return &ControllerAPI{ state: st, authorizer: authorizer, apiUser: apiUser, resources: resources, }, nil }
// NewAddresserAPI creates a new server-side Addresser API facade. func NewAddresserAPI( st *state.State, resources *common.Resources, authorizer common.Authorizer, ) (*AddresserAPI, error) { isEnvironManager := authorizer.AuthEnvironManager() if !isEnvironManager { // Addresser must run as environment manager. return nil, common.ErrPerm } getAuthFunc := func() (common.AuthFunc, error) { return func(tag names.Tag) bool { return isEnvironManager }, nil } sti := getState(st) return &AddresserAPI{ EnvironWatcher: common.NewEnvironWatcher(sti, resources, authorizer), LifeGetter: common.NewLifeGetter(sti, getAuthFunc), Remover: common.NewRemover(sti, false, getAuthFunc), st: sti, resources: resources, authorizer: authorizer, }, nil }
func newUndertakerAPI(st State, resources *common.Resources, authorizer common.Authorizer) (*UndertakerAPI, error) { if !authorizer.AuthMachineAgent() || !authorizer.AuthModelManager() { return nil, common.ErrPerm } model, err := st.Model() if err != nil { return nil, errors.Trace(err) } getCanModifyModel := func() (common.AuthFunc, error) { return func(tag names.Tag) bool { if st.IsController() { return true } // Only the agent's model can be modified. modelTag, ok := tag.(names.ModelTag) if !ok { return false } return modelTag.Id() == model.UUID() }, nil } return &UndertakerAPI{ st: st, resources: resources, StatusSetter: common.NewStatusSetter(st, getCanModifyModel), }, nil }
func NewUserManagerAPI( st *state.State, resources *common.Resources, authorizer common.Authorizer, ) (*UserManagerAPI, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } resource, ok := resources.Get("createLocalLoginMacaroon").(common.ValueResource) if !ok { return nil, errors.NotFoundf("userAuth resource") } createLocalLoginMacaroon, ok := resource.Value.(func(names.UserTag) (*macaroon.Macaroon, error)) if !ok { return nil, errors.NotValidf("userAuth resource") } return &UserManagerAPI{ state: st, authorizer: authorizer, createLocalLoginMacaroon: createLocalLoginMacaroon, check: common.NewBlockChecker(st), }, nil }
func newUndertakerAPI(st State, resources *common.Resources, authorizer common.Authorizer) (*UndertakerAPI, error) { if !authorizer.AuthMachineAgent() || !authorizer.AuthModelManager() { return nil, common.ErrPerm } return &UndertakerAPI{ st: st, resources: resources, }, nil }
// NewFacade creates a new authorized Facade. func NewFacade(backend Backend, res *common.Resources, auth common.Authorizer) (*Facade, error) { if !auth.AuthModelManager() { return nil, common.ErrPerm } return &Facade{ backend: backend, resources: res, }, nil }
// NewProvisionerAPI creates a new server-side ProvisionerAPI facade. func NewProvisionerAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*ProvisionerAPI, error) { if !authorizer.AuthMachineAgent() && !authorizer.AuthEnvironManager() { return nil, common.ErrPerm } getAuthFunc := func() (common.AuthFunc, error) { isEnvironManager := authorizer.AuthEnvironManager() isMachineAgent := authorizer.AuthMachineAgent() authEntityTag := authorizer.GetAuthTag() return func(tag names.Tag) bool { if isMachineAgent && tag == authEntityTag { // A machine agent can always access its own machine. return true } switch tag := tag.(type) { case names.MachineTag: parentId := state.ParentId(tag.Id()) if parentId == "" { // All top-level machines are accessible by the // environment manager. return isEnvironManager } // All containers with the authenticated machine as a // parent are accessible by it. // TODO(dfc) sometimes authEntity tag is nil, which is fine because nil is // only equal to nil, but it suggests someone is passing an authorizer // with a nil tag. return isMachineAgent && names.NewMachineTag(parentId) == authEntityTag default: return false } }, nil } env, err := st.Environment() if err != nil { return nil, err } urlGetter := common.NewToolsURLGetter(env.UUID(), st) return &ProvisionerAPI{ Remover: common.NewRemover(st, false, getAuthFunc), StatusSetter: common.NewStatusSetter(st, getAuthFunc), StatusGetter: common.NewStatusGetter(st, getAuthFunc), DeadEnsurer: common.NewDeadEnsurer(st, getAuthFunc), PasswordChanger: common.NewPasswordChanger(st, getAuthFunc), LifeGetter: common.NewLifeGetter(st, getAuthFunc), StateAddresser: common.NewStateAddresser(st), APIAddresser: common.NewAPIAddresser(st, resources), EnvironWatcher: common.NewEnvironWatcher(st, resources, authorizer), EnvironMachinesWatcher: common.NewEnvironMachinesWatcher(st, resources, authorizer), InstanceIdGetter: common.NewInstanceIdGetter(st, getAuthFunc), ToolsFinder: common.NewToolsFinder(st, st, urlGetter), st: st, resources: resources, authorizer: authorizer, getAuthFunc: getAuthFunc, }, nil }
// NewResumerAPI creates a new instance of the Resumer API. func NewResumerAPI(st *state.State, _ *common.Resources, authorizer common.Authorizer) (*ResumerAPI, error) { if !authorizer.AuthModelManager() { return nil, common.ErrPerm } return &ResumerAPI{ st: getState(st), auth: authorizer, }, nil }
// 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 }
// 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 }
// NewFacade returns a singular-controller API facade, backed by the supplied // state, so long as the authorizer represents a controller machine. func NewFacade(backend Backend, auth common.Authorizer) (*Facade, error) { if !auth.AuthModelManager() { return nil, common.ErrPerm } return &Facade{ auth: auth, model: backend.ModelTag(), claimer: backend.SingularClaimer(), }, nil }
func NewDiscoverSpacesAPIWithBacking(st networkingcommon.NetworkBacking, resources *common.Resources, authorizer common.Authorizer) (*DiscoverSpacesAPI, error) { if !authorizer.AuthModelManager() { return nil, common.ErrPerm } return &DiscoverSpacesAPI{ st: st, authorizer: authorizer, 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 }
// NewClient creates a new instance of the Client Facade. func NewClient(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*Client, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } return &Client{api: &API{ state: st, auth: authorizer, resources: resources, statusSetter: common.NewStatusSetter(st, common.AuthAlways()), }}, nil }
// NewMetricsManagerAPI creates a new API endpoint for calling metrics manager functions. func NewMetricsManagerAPI( st *state.State, resources *common.Resources, authorizer common.Authorizer, ) (*MetricsManagerAPI, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } return &MetricsManagerAPI{state: st}, nil }
// NewCharmRevisionUpdaterAPI creates a new server-side charmrevisionupdater API end point. func NewCharmRevisionUpdaterAPI( st *state.State, resources *common.Resources, authorizer common.Authorizer, ) (*CharmRevisionUpdaterAPI, error) { if !authorizer.AuthMachineAgent() && !authorizer.AuthEnvironManager() { return nil, common.ErrPerm } return &CharmRevisionUpdaterAPI{ state: st, resources: resources, authorizer: authorizer}, nil }
// NewInstancePollerAPI creates a new server-side InstancePoller API // facade. func NewInstancePollerAPI( st *state.State, resources *common.Resources, authorizer common.Authorizer, ) (*InstancePollerAPI, error) { if !authorizer.AuthModelManager() { // InstancePoller must run as environment manager. return nil, common.ErrPerm } accessMachine := common.AuthFuncForTagKind(names.MachineTagKind) sti := getState(st) // Life() is supported for machines. lifeGetter := common.NewLifeGetter( sti, accessMachine, ) // ModelConfig() and WatchForModelConfigChanges() are allowed // with unrestriced access. modelWatcher := common.NewModelWatcher( sti, resources, authorizer, ) // WatchModelMachines() is allowed with unrestricted access. machinesWatcher := common.NewModelMachinesWatcher( sti, resources, authorizer, ) // InstanceId() is supported for machines. instanceIdGetter := common.NewInstanceIdGetter( sti, accessMachine, ) // Status() is supported for machines. statusGetter := common.NewStatusGetter( sti, accessMachine, ) return &InstancePollerAPI{ LifeGetter: lifeGetter, ModelWatcher: modelWatcher, ModelMachinesWatcher: machinesWatcher, InstanceIdGetter: instanceIdGetter, StatusGetter: statusGetter, st: sti, resources: resources, authorizer: authorizer, accessMachine: accessMachine, }, nil }
// newAPIWithBacking creates a new server-side Spaces API facade with // the given Backing. func newAPIWithBacking(backing networkingcommon.NetworkBacking, resources *common.Resources, authorizer common.Authorizer) (API, error) { // Only clients can access the Spaces facade. if !authorizer.AuthClient() { return nil, common.ErrPerm } return &spacesAPI{ backing: backing, resources: resources, authorizer: authorizer, }, nil }
// NewHighAvailabilityAPI creates a new server-side highavailability API end point. func NewHighAvailabilityAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*HighAvailabilityAPI, error) { // Only clients and environment managers can access the high availability service. if !authorizer.AuthClient() && !authorizer.AuthModelManager() { return nil, common.ErrPerm } return &HighAvailabilityAPI{ state: st, resources: resources, authorizer: authorizer, }, nil }
// NewActionAPI returns an initialized ActionAPI func NewActionAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*ActionAPI, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } return &ActionAPI{ state: st, resources: resources, authorizer: authorizer, }, nil }
// NewImageManagerAPI creates a new server-side imagemanager API end point. func NewImageManagerAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*ImageManagerAPI, error) { // Only clients can access the image manager service. if !authorizer.AuthClient() { return nil, common.ErrPerm } return &ImageManagerAPI{ state: getState(st), resources: resources, authorizer: authorizer, check: common.NewBlockChecker(st), }, nil }
// newPublicFacade is passed into common.RegisterStandardFacade // in registerPublicFacade. func (resources) newPublicFacade(st *corestate.State, _ *common.Resources, authorizer common.Authorizer) (*server.Facade, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } rst, err := st.Resources() //rst, err := state.NewState(&resourceState{raw: st}) if err != nil { return nil, errors.Trace(err) } return server.NewFacade(rst), nil }
// NewCleanerAPI creates a new instance of the Cleaner API. func NewCleanerAPI( st *state.State, res *common.Resources, authorizer common.Authorizer, ) (*CleanerAPI, error) { if !authorizer.AuthModelManager() { return nil, common.ErrPerm } return &CleanerAPI{ st: getState(st), resources: res, }, 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 }
func newClientAllWatcher(st *state.State, resources *common.Resources, auth common.Authorizer, id string) (interface{}, error) { if !auth.AuthClient() { return nil, common.ErrPerm } watcher, ok := resources.Get(id).(*state.Multiwatcher) if !ok { return nil, common.ErrUnknownWatcher } return &srvClientAllWatcher{ watcher: watcher, id: id, resources: resources, }, 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 a new charm annotator API facade. func NewAPI( st *state.State, resources *common.Resources, authorizer common.Authorizer, ) (*API, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } return &API{ access: getState(st), authorizer: authorizer, }, 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.AuthModelManager() { return nil, common.ErrPerm } return &API{ backend: getBackend(st), authorizer: authorizer, resources: resources, }, nil }