// NewModelManagerAPI creates a new api server endpoint for managing // models. func NewModelManagerAPI( st common.ModelManagerBackend, configGetter environs.EnvironConfigGetter, authorizer facade.Authorizer, ) (*ModelManagerAPI, error) { if !authorizer.AuthClient() { return nil, 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) // Pretty much all of the user manager methods have special casing for admin // users, so look once when we start and remember if the user is an admin. isAdmin, err := authorizer.HasPermission(permission.SuperuserAccess, st.ControllerTag()) if err != nil { return nil, errors.Trace(err) } urlGetter := common.NewToolsURLGetter(st.ModelUUID(), st) return &ModelManagerAPI{ ModelStatusAPI: common.NewModelStatusAPI(st, authorizer, apiUser), state: st, check: common.NewBlockChecker(st), authorizer: authorizer, toolsFinder: common.NewToolsFinder(configGetter, st, urlGetter), apiUser: apiUser, isAdmin: isAdmin, }, nil }
// NewClient creates a new instance of the Client Facade. func NewClient( st Backend, modelConfigAPI *modelconfig.ModelConfigAPI, resources facade.Resources, authorizer facade.Authorizer, statusSetter *common.StatusSetter, toolsFinder *common.ToolsFinder, newEnviron func() (environs.Environ, error), blockChecker *common.BlockChecker, ) (*Client, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } client := &Client{ modelConfigAPI, &API{ stateAccessor: st, auth: authorizer, resources: resources, statusSetter: statusSetter, toolsFinder: toolsFinder, }, newEnviron, blockChecker, } return client, nil }
// NewCloudAPI creates a new API server endpoint for managing the controller's // cloud definition and cloud credentials. func NewCloudAPI(backend Backend, authorizer facade.Authorizer) (*CloudAPI, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } getUserAuthFunc := func() (common.AuthFunc, error) { authUser, _ := authorizer.GetAuthTag().(names.UserTag) isAdmin, err := authorizer.HasPermission(permission.SuperuserAccess, backend.ControllerTag()) if err != nil && !errors.IsNotFound(err) { return nil, err } return func(tag names.Tag) bool { userTag, ok := tag.(names.UserTag) if !ok { return false } return isAdmin || userTag == authUser }, nil } return &CloudAPI{ backend: backend, authorizer: authorizer, getCredentialsAuthFunc: getUserAuthFunc, }, nil }
func NewUserManagerAPI( st *state.State, resources facade.Resources, authorizer facade.Authorizer, ) (*UserManagerAPI, error) { if !authorizer.AuthClient() { return nil, 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) // Pretty much all of the user manager methods have special casing for admin // users, so look once when we start and remember if the user is an admin. isAdmin, err := authorizer.HasPermission(permission.SuperuserAccess, st.ControllerTag()) if err != nil { return nil, errors.Trace(err) } return &UserManagerAPI{ state: st, authorizer: authorizer, check: common.NewBlockChecker(st), apiUser: apiUser, isAdmin: isAdmin, }, nil }
// newAPIWithBacking creates a new server-side Spaces API facade with // the given Backing. func newAPIWithBacking(backing networkingcommon.NetworkBacking, resources facade.Resources, authorizer facade.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 facade.Resources, authorizer facade.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 }
// NewModelConfigAPI creates a new instance of the ModelConfig Facade. func NewModelConfigAPI(backend Backend, authorizer facade.Authorizer) (*ModelConfigAPI, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } client := &ModelConfigAPI{ backend: backend, auth: authorizer, check: common.NewBlockChecker(backend), } return client, nil }
// NewImageManagerAPI creates a new server-side imagemanager API end point. func NewImageManagerAPI(st *state.State, resources facade.Resources, authorizer facade.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 }
// NewMetricsDebugAPI creates a new API endpoint for calling metrics debug functions. func NewMetricsDebugAPI( st *state.State, resources facade.Resources, authorizer facade.Authorizer, ) (*MetricsDebugAPI, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } return &MetricsDebugAPI{ state: st, }, nil }
func checkAuth(authorizer facade.Authorizer, st *state.State) error { if !authorizer.AuthClient() { return errors.Trace(common.ErrPerm) } if isAdmin, err := authorizer.HasPermission(permission.SuperuserAccess, st.ControllerTag()); err != nil { return errors.Trace(err) } else if !isAdmin { // The entire facade is only accessible to controller administrators. return errors.Trace(common.ErrPerm) } return nil }
// NewAPI returns a new block API facade. func NewAPI( st *state.State, resources facade.Resources, authorizer facade.Authorizer, ) (*API, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } return &API{ access: getState(st), authorizer: authorizer, }, nil }
// createAPI returns a new image metadata API facade. func createAPI( st metadataAcess, newEnviron func() (environs.Environ, error), resources facade.Resources, authorizer facade.Authorizer, ) (*API, error) { if !authorizer.AuthClient() && !authorizer.AuthModelManager() { return nil, common.ErrPerm } return &API{ metadata: st, newEnviron: newEnviron, authorizer: authorizer, }, nil }
// NewAPI returns a new application API facade. func NewAPI( backend Backend, authorizer facade.Authorizer, blockChecker BlockChecker, stateCharm func(Charm) *state.Charm, ) (*API, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } return &API{ backend: backend, authorizer: authorizer, check: blockChecker, stateCharm: stateCharm, }, nil }
// NewMachineManagerAPI creates a new server-side MachineManager API facade. func NewMachineManagerAPI( st *state.State, resources facade.Resources, authorizer facade.Authorizer, ) (*MachineManagerAPI, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } s := getState(st) return &MachineManagerAPI{ st: s, authorizer: authorizer, check: common.NewBlockChecker(s), }, nil }
// NewAPI returns a new storage API facade. func NewAPI( st storageAccess, registry storage.ProviderRegistry, pm poolmanager.PoolManager, resources facade.Resources, authorizer facade.Authorizer, ) (*API, error) { if !authorizer.AuthClient() { return nil, common.ErrPerm } return &API{ storage: st, registry: registry, poolManager: pm, authorizer: authorizer, }, nil }
// NewKeyManagerAPI creates a new server-side keyupdater API end point. func NewKeyManagerAPI(st *state.State, resources facade.Resources, authorizer facade.Authorizer) (*KeyManagerAPI, error) { // Only clients and environment managers can access the key manager service. if !authorizer.AuthClient() && !authorizer.AuthModelManager() { return nil, common.ErrPerm } env, err := st.Model() if err != nil { return nil, errors.Trace(err) } // For gccgo interface comparisons, we need a Tag. owner := names.Tag(env.Owner()) // TODO(wallyworld) - replace stub with real canRead function // For now, only admins can read authorised ssh keys. canRead := func(user string) bool { // Are we a machine agent operating as the system identity? if user == config.JujuSystemKey { _, ismachinetag := authorizer.GetAuthTag().(names.MachineTag) return ismachinetag } return authorizer.GetAuthTag() == owner } // 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 } // No point looking to see if the user exists as we are not // yet storing keys on the user. return authorizer.GetAuthTag() == owner } return &KeyManagerAPI{ state: st, resources: resources, authorizer: authorizer, canRead: canRead, canWrite: canWrite, check: common.NewBlockChecker(st), }, nil }
// NewAPI creates a new instance of the Backups API facade. func NewAPI(backend Backend, resources facade.Resources, authorizer facade.Authorizer) (*API, error) { isControllerAdmin, err := authorizer.HasPermission(permission.SuperuserAccess, backend.ControllerTag()) if err != nil && !errors.IsNotFound(err) { return nil, errors.Trace(err) } if !authorizer.AuthClient() || !isControllerAdmin { return nil, common.ErrPerm } // For now, backup operations are only permitted on the controller environment. if !backend.IsController() { return nil, errors.New("backups are not supported for hosted models") } // 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{ backend: backend, paths: &paths, machineID: machineID, } return &b, nil }
// NewControllerAPI creates a new api server endpoint for managing // environments. func NewControllerAPI( st *state.State, resources facade.Resources, authorizer facade.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) environConfigGetter := stateenvirons.EnvironConfigGetter{st} return &ControllerAPI{ ControllerConfigAPI: common.NewControllerConfig(st), CloudSpecAPI: cloudspec.NewCloudSpec(environConfigGetter.CloudSpec, common.AuthFuncForTag(st.ModelTag())), state: st, authorizer: authorizer, apiUser: apiUser, resources: resources, }, nil }