func (s *destroyTwoModelsSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) _, err := s.State.AddUser("jess", "jess", "", "test") c.Assert(err, jc.ErrorIsNil) s.otherModelOwner = names.NewUserTag("jess") s.otherState = factory.NewFactory(s.State).MakeModel(c, &factory.ModelParams{ Owner: s.otherModelOwner, ConfigAttrs: jujutesting.Attrs{ "controller": false, }, }) s.modelManager = common.NewModelManagerBackend(s.State) s.otherModelManager = common.NewModelManagerBackend(s.otherState) s.AddCleanup(func(*gc.C) { s.otherState.Close() }) }
// DestroyController will attempt to destroy the controller. If the args // specify the removal of blocks or the destruction of the models, this // method will attempt to do so. // // If the controller has any non-Dead hosted models, then an error with // the code params.CodeHasHostedModels will be transmitted, regardless of // the value of the DestroyModels parameter. This is to inform the client // that it should wait for hosted models to be completely cleaned up // before proceeding. func (s *ControllerAPI) DestroyController(args params.DestroyControllerArgs) error { hasPermission, err := s.authorizer.HasPermission(permission.SuperuserAccess, s.state.ControllerTag()) if err != nil { return errors.Trace(err) } if !hasPermission { return errors.Trace(common.ErrPerm) } st := common.NewModelManagerBackend(s.state) controllerModel, err := st.ControllerModel() if err != nil { return errors.Trace(err) } systemTag := controllerModel.ModelTag() if err = s.ensureNotBlocked(args); err != nil { return errors.Trace(err) } // If we are destroying models, we need to tolerate living // models but set the controller to dying to prevent new // models sneaking in. If we are not destroying hosted models, // this will fail if any hosted models are found. if args.DestroyModels { return errors.Trace(common.DestroyModelIncludingHosted(st, systemTag)) } if err := common.DestroyModel(st, systemTag); err != nil { return errors.Trace(err) } return nil }
func (s *modelManagerStateSuite) TestAdminDestroysOtherModel(c *gc.C) { // TODO(perrito666) Both users are admins in this case, this tesst is of dubious // usefulness until proper controller permissions are in place. owner := names.NewUserTag("admin@local") s.setAPIUser(c, owner) m, err := s.modelmanager.CreateModel(s.createArgs(c, owner)) c.Assert(err, jc.ErrorIsNil) st, err := s.State.ForModel(names.NewModelTag(m.UUID)) c.Assert(err, jc.ErrorIsNil) defer st.Close() s.modelmanager, err = modelmanager.NewModelManagerAPI( common.NewModelManagerBackend(st), nil, s.authoriser, ) c.Assert(err, jc.ErrorIsNil) other := s.AdminUserTag(c) s.setAPIUser(c, other) results, err := s.modelmanager.DestroyModels(params.Entities{ Entities: []params.Entity{{"model-" + m.UUID}}, }) c.Assert(err, jc.ErrorIsNil) c.Assert(results.Results, gc.HasLen, 1) c.Assert(results.Results[0].Error, gc.IsNil) s.setAPIUser(c, owner) model, err := st.Model() c.Assert(err, jc.ErrorIsNil) c.Assert(model.Life(), gc.Not(gc.Equals), state.Alive) }
func (s *modelManagerStateSuite) TestDestroyOwnModel(c *gc.C) { // TODO(perrito666) this test is not valid until we have // proper controller permission since the only users that // can create models are controller admins. owner := names.NewUserTag("admin@local") s.setAPIUser(c, owner) m, err := s.modelmanager.CreateModel(s.createArgs(c, owner)) c.Assert(err, jc.ErrorIsNil) st, err := s.State.ForModel(names.NewModelTag(m.UUID)) c.Assert(err, jc.ErrorIsNil) defer st.Close() s.modelmanager, err = modelmanager.NewModelManagerAPI( common.NewModelManagerBackend(st), nil, s.authoriser, ) c.Assert(err, jc.ErrorIsNil) results, err := s.modelmanager.DestroyModels(params.Entities{ Entities: []params.Entity{{"model-" + m.UUID}}, }) c.Assert(err, jc.ErrorIsNil) c.Assert(results.Results, gc.HasLen, 1) c.Assert(results.Results[0].Error, gc.IsNil) model, err := st.Model() c.Assert(err, jc.ErrorIsNil) c.Assert(model.Life(), gc.Not(gc.Equals), state.Alive) }
func (s *modelManagerStateSuite) TestNewAPIRefusesNonClient(c *gc.C) { anAuthoriser := s.authoriser anAuthoriser.Tag = names.NewUnitTag("mysql/0") endPoint, err := modelmanager.NewModelManagerAPI( common.NewModelManagerBackend(s.State), nil, anAuthoriser, ) c.Assert(endPoint, gc.IsNil) c.Assert(err, gc.ErrorMatches, "permission denied") }
func (s *modelManagerStateSuite) TestNewAPIAcceptsClient(c *gc.C) { anAuthoriser := s.authoriser anAuthoriser.Tag = names.NewUserTag("external@remote") endPoint, err := modelmanager.NewModelManagerAPI( common.NewModelManagerBackend(s.State), nil, anAuthoriser, ) c.Assert(err, jc.ErrorIsNil) c.Assert(endPoint, gc.NotNil) }
func (s *modelManagerStateSuite) setAPIUser(c *gc.C, user names.UserTag) { s.authoriser.Tag = user modelmanager, err := modelmanager.NewModelManagerAPI( common.NewModelManagerBackend(s.State), stateenvirons.EnvironConfigGetter{s.State}, s.authoriser, ) c.Assert(err, jc.ErrorIsNil) s.modelmanager = modelmanager }
func (c *ControllerAPI) modelStatus(tag string) (params.ModelStatus, error) { var status params.ModelStatus modelTag, err := names.ParseModelTag(tag) if err != nil { return status, errors.Trace(err) } st, err := c.state.ForModel(modelTag) if err != nil { return status, errors.Trace(err) } defer st.Close() machines, err := st.AllMachines() if err != nil { return status, errors.Trace(err) } var hostedMachines []*state.Machine for _, m := range machines { if !m.IsManager() { hostedMachines = append(hostedMachines, m) } } applications, err := st.AllApplications() if err != nil { return status, errors.Trace(err) } model, err := st.Model() if err != nil { return status, errors.Trace(err) } if err != nil { return status, errors.Trace(err) } modelMachines, err := common.ModelMachineInfo(common.NewModelManagerBackend(st)) if err != nil { return status, errors.Trace(err) } return params.ModelStatus{ ModelTag: tag, OwnerTag: model.Owner().String(), Life: params.Life(model.Life().String()), HostedMachineCount: len(hostedMachines), ApplicationCount: len(applications), Machines: modelMachines, }, nil }
func (s *modelManagerStateSuite) TestDestroyModelErrors(c *gc.C) { owner := names.NewUserTag("admin@local") s.setAPIUser(c, owner) m, err := s.modelmanager.CreateModel(s.createArgs(c, owner)) c.Assert(err, jc.ErrorIsNil) st, err := s.State.ForModel(names.NewModelTag(m.UUID)) c.Assert(err, jc.ErrorIsNil) defer st.Close() s.modelmanager, err = modelmanager.NewModelManagerAPI( common.NewModelManagerBackend(st), nil, s.authoriser, ) c.Assert(err, jc.ErrorIsNil) user := names.NewUserTag("other@remote") s.setAPIUser(c, user) results, err := s.modelmanager.DestroyModels(params.Entities{ Entities: []params.Entity{ {"model-" + m.UUID}, {"model-9f484882-2f18-4fd2-967d-db9663db7bea"}, {"machine-42"}, }, }) c.Assert(err, jc.ErrorIsNil) c.Assert(results.Results, jc.DeepEquals, []params.ErrorResult{{ // we don't have admin access to the model ¶ms.Error{ Message: "permission denied", Code: params.CodeUnauthorized, }, }, { ¶ms.Error{ Message: "model not found", Code: params.CodeNotFound, }, }, { ¶ms.Error{ Message: `"machine-42" is not a valid model tag`, }, }}) s.setAPIUser(c, owner) model, err := st.Model() c.Assert(err, jc.ErrorIsNil) c.Assert(model.Life(), gc.Equals, state.Alive) }
// 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), ModelStatusAPI: common.NewModelStatusAPI(common.NewModelManagerBackend(st), authorizer, apiUser), CloudSpecAPI: cloudspec.NewCloudSpec(environConfigGetter.CloudSpec, common.AuthFuncForTag(st.ModelTag())), state: st, authorizer: authorizer, apiUser: apiUser, resources: resources, }, nil }
func newFacade(st *state.State, _ facade.Resources, auth facade.Authorizer) (*ModelManagerAPI, error) { configGetter := stateenvirons.EnvironConfigGetter{st} return NewModelManagerAPI(common.NewModelManagerBackend(st), configGetter, auth) }
func (s *destroyModelSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) s.BlockHelper = commontesting.NewBlockHelper(s.APIState) s.modelManager = common.NewModelManagerBackend(s.State) s.AddCleanup(func(*gc.C) { s.BlockHelper.Close() }) }