github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/model/grantrevoke_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package model_test 5 6 import ( 7 "strings" 8 9 "github.com/juju/cmd" 10 "github.com/juju/cmd/cmdtesting" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/apiserver/common" 15 "github.com/juju/juju/cmd/juju/model" 16 "github.com/juju/juju/core/crossmodel" 17 coremodel "github.com/juju/juju/core/model" 18 "github.com/juju/juju/jujuclient" 19 "github.com/juju/juju/testing" 20 ) 21 22 type grantRevokeSuite struct { 23 testing.FakeJujuXDGDataHomeSuite 24 fakeModelAPI *fakeModelGrantRevokeAPI 25 fakeOffersAPI *fakeOffersGrantRevokeAPI 26 cmdFactory func(*fakeModelGrantRevokeAPI, *fakeOffersGrantRevokeAPI) cmd.Command 27 store *jujuclient.MemStore 28 } 29 30 const ( 31 fooModelUUID = "0701e916-3274-46e4-bd12-c31aff89cee3" 32 barModelUUID = "0701e916-3274-46e4-bd12-c31aff89cee4" 33 bazModelUUID = "0701e916-3274-46e4-bd12-c31aff89cee5" 34 model1ModelUUID = "0701e916-3274-46e4-bd12-c31aff89cee6" 35 model2ModelUUID = "0701e916-3274-46e4-bd12-c31aff89cee7" 36 ) 37 38 func (s *grantRevokeSuite) SetUpTest(c *gc.C) { 39 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 40 s.fakeModelAPI = &fakeModelGrantRevokeAPI{} 41 s.fakeOffersAPI = &fakeOffersGrantRevokeAPI{} 42 43 // Set up the current controller, and write just enough info 44 // so we don't try to refresh 45 controllerName := "test-master" 46 47 s.store = jujuclient.NewMemStore() 48 s.store.CurrentControllerName = controllerName 49 s.store.Controllers[controllerName] = jujuclient.ControllerDetails{} 50 s.store.Accounts[controllerName] = jujuclient.AccountDetails{ 51 User: "bob", 52 } 53 s.store.Models = map[string]*jujuclient.ControllerModels{ 54 controllerName: { 55 Models: map[string]jujuclient.ModelDetails{ 56 "bob/foo": {ModelUUID: fooModelUUID, ModelType: coremodel.IAAS}, 57 "bob/bar": {ModelUUID: barModelUUID, ModelType: coremodel.IAAS}, 58 "bob/baz": {ModelUUID: bazModelUUID, ModelType: coremodel.IAAS}, 59 "bob/model1": {ModelUUID: model1ModelUUID, ModelType: coremodel.IAAS}, 60 "bob/model2": {ModelUUID: model2ModelUUID, ModelType: coremodel.IAAS}, 61 }, 62 }, 63 } 64 } 65 66 func (s *grantRevokeSuite) run(c *gc.C, args ...string) (*cmd.Context, error) { 67 command := s.cmdFactory(s.fakeModelAPI, s.fakeOffersAPI) 68 return cmdtesting.RunCommand(c, command, args...) 69 } 70 71 func (s *grantRevokeSuite) TestPassesModelValues(c *gc.C) { 72 user := "sam" 73 models := []string{fooModelUUID, barModelUUID, bazModelUUID} 74 _, err := s.run(c, "sam", "read", "foo", "bar", "baz") 75 c.Assert(err, jc.ErrorIsNil) 76 c.Assert(s.fakeModelAPI.user, jc.DeepEquals, user) 77 c.Assert(s.fakeModelAPI.modelUUIDs, jc.DeepEquals, models) 78 c.Assert(s.fakeModelAPI.access, gc.Equals, "read") 79 } 80 81 func (s *grantRevokeSuite) TestPassesOfferValues(c *gc.C) { 82 offers := []string{"bob/foo.hosted-mysql", "bob/bar.mysql", "bob/baz.hosted-db2"} 83 _, err := s.run(c, "sam", "read", offers[0], offers[1], offers[2]) 84 c.Assert(err, jc.ErrorIsNil) 85 c.Assert(s.fakeOffersAPI.user, jc.DeepEquals, "sam") 86 c.Assert(s.fakeOffersAPI.offerURLs, jc.SameContents, []string{"bob/foo.hosted-mysql", "bob/bar.mysql", "bob/baz.hosted-db2"}) 87 c.Assert(s.fakeOffersAPI.access, gc.Equals, "read") 88 } 89 90 func (s *grantRevokeSuite) TestPassesOfferWithDefaultModelUser(c *gc.C) { 91 offer := "foo.hosted-mysql" 92 _, err := s.run(c, "sam", "read", offer) 93 c.Assert(err, jc.ErrorIsNil) 94 c.Assert(s.fakeOffersAPI.user, jc.DeepEquals, "sam") 95 c.Assert(s.fakeOffersAPI.offerURLs, jc.SameContents, []string{"bob/foo.hosted-mysql"}) 96 c.Assert(s.fakeOffersAPI.access, gc.Equals, "read") 97 } 98 99 func (s *grantRevokeSuite) TestModelAccess(c *gc.C) { 100 sam := "sam" 101 _, err := s.run(c, "sam", "write", "model1", "model2") 102 c.Assert(err, jc.ErrorIsNil) 103 c.Assert(s.fakeModelAPI.user, jc.DeepEquals, sam) 104 c.Assert(s.fakeModelAPI.modelUUIDs, jc.DeepEquals, []string{model1ModelUUID, model2ModelUUID}) 105 c.Assert(s.fakeModelAPI.access, gc.Equals, "write") 106 } 107 108 func (s *grantRevokeSuite) TestModelBlockGrant(c *gc.C) { 109 s.fakeModelAPI.err = common.OperationBlockedError("TestBlockGrant") 110 _, err := s.run(c, "sam", "read", "foo") 111 testing.AssertOperationWasBlocked(c, err, ".*TestBlockGrant.*") 112 } 113 114 type grantSuite struct { 115 grantRevokeSuite 116 } 117 118 var _ = gc.Suite(&grantSuite{}) 119 120 func (s *grantSuite) SetUpTest(c *gc.C) { 121 s.grantRevokeSuite.SetUpTest(c) 122 s.cmdFactory = func(fakeModelAPI *fakeModelGrantRevokeAPI, fakeOfferAPI *fakeOffersGrantRevokeAPI) cmd.Command { 123 c, _ := model.NewGrantCommandForTest(fakeModelAPI, fakeOfferAPI, s.store) 124 return c 125 } 126 } 127 128 func (s *grantSuite) TestInitModels(c *gc.C) { 129 wrappedCmd, grantCmd := model.NewGrantCommandForTest(nil, nil, s.store) 130 err := cmdtesting.InitCommand(wrappedCmd, []string{}) 131 c.Assert(err, gc.ErrorMatches, "no user specified") 132 133 err = cmdtesting.InitCommand(wrappedCmd, []string{"bob", "read", "model1", "model2"}) 134 c.Assert(err, jc.ErrorIsNil) 135 136 c.Assert(grantCmd.User, gc.Equals, "bob") 137 c.Assert(grantCmd.ModelNames, jc.DeepEquals, []string{"model1", "model2"}) 138 c.Assert(grantCmd.OfferURLs, gc.HasLen, 0) 139 140 err = cmdtesting.InitCommand(wrappedCmd, []string{}) 141 c.Assert(err, gc.ErrorMatches, `no user specified`) 142 } 143 144 func (s *grantSuite) TestInitOffers(c *gc.C) { 145 wrappedCmd, grantCmd := model.NewGrantCommandForTest(nil, nil, s.store) 146 147 err := cmdtesting.InitCommand(wrappedCmd, []string{"bob", "read", "fred/model.offer1", "mary/model.offer2"}) 148 c.Assert(err, jc.ErrorIsNil) 149 150 c.Assert(grantCmd.User, gc.Equals, "bob") 151 url1, err := crossmodel.ParseOfferURL("fred/model.offer1") 152 c.Assert(err, jc.ErrorIsNil) 153 url2, err := crossmodel.ParseOfferURL("mary/model.offer2") 154 c.Assert(err, jc.ErrorIsNil) 155 c.Assert(grantCmd.OfferURLs, jc.DeepEquals, []*crossmodel.OfferURL{url1, url2}) 156 c.Assert(grantCmd.ModelNames, gc.HasLen, 0) 157 } 158 159 type revokeSuite struct { 160 grantRevokeSuite 161 } 162 163 var _ = gc.Suite(&revokeSuite{}) 164 165 func (s *revokeSuite) SetUpTest(c *gc.C) { 166 s.grantRevokeSuite.SetUpTest(c) 167 s.cmdFactory = func(fakeModelAPI *fakeModelGrantRevokeAPI, fakeOffersAPI *fakeOffersGrantRevokeAPI) cmd.Command { 168 c, _ := model.NewRevokeCommandForTest(fakeModelAPI, fakeOffersAPI, s.store) 169 return c 170 } 171 } 172 173 func (s *revokeSuite) TestInit(c *gc.C) { 174 wrappedCmd, revokeCmd := model.NewRevokeCommandForTest(nil, nil, s.store) 175 err := cmdtesting.InitCommand(wrappedCmd, []string{}) 176 c.Assert(err, gc.ErrorMatches, "no user specified") 177 178 err = cmdtesting.InitCommand(wrappedCmd, []string{"bob", "read", "model1", "model2"}) 179 c.Assert(err, jc.ErrorIsNil) 180 181 c.Assert(revokeCmd.User, gc.Equals, "bob") 182 c.Assert(revokeCmd.ModelNames, jc.DeepEquals, []string{"model1", "model2"}) 183 184 err = cmdtesting.InitCommand(wrappedCmd, []string{}) 185 c.Assert(err, gc.ErrorMatches, `no user specified`) 186 187 } 188 189 func (s *grantSuite) TestModelAccessForController(c *gc.C) { 190 wrappedCmd, _ := model.NewRevokeCommandForTest(nil, nil, s.store) 191 err := cmdtesting.InitCommand(wrappedCmd, []string{"bob", "write"}) 192 msg := strings.Replace(err.Error(), "\n", "", -1) 193 c.Check(msg, gc.Matches, `You have specified a model access permission "write".*`) 194 } 195 196 func (s *grantSuite) TestControllerAccessForModel(c *gc.C) { 197 wrappedCmd, _ := model.NewRevokeCommandForTest(nil, nil, s.store) 198 err := cmdtesting.InitCommand(wrappedCmd, []string{"bob", "superuser", "default"}) 199 msg := strings.Replace(err.Error(), "\n", "", -1) 200 c.Check(msg, gc.Matches, `You have specified a controller access permission "superuser".*`) 201 } 202 203 func (s *grantSuite) TestControllerAccessForOffer(c *gc.C) { 204 wrappedCmd, _ := model.NewRevokeCommandForTest(nil, nil, s.store) 205 err := cmdtesting.InitCommand(wrappedCmd, []string{"bob", "superuser", "fred/default.mysql"}) 206 msg := strings.Replace(err.Error(), "\n", "", -1) 207 c.Check(msg, gc.Matches, `You have specified a controller access permission "superuser".*`) 208 } 209 210 type fakeModelGrantRevokeAPI struct { 211 err error 212 user string 213 access string 214 modelUUIDs []string 215 } 216 217 func (f *fakeModelGrantRevokeAPI) Close() error { return nil } 218 219 func (f *fakeModelGrantRevokeAPI) GrantModel(user, access string, modelUUIDs ...string) error { 220 return f.fake(user, access, modelUUIDs...) 221 } 222 223 func (f *fakeModelGrantRevokeAPI) RevokeModel(user, access string, modelUUIDs ...string) error { 224 return f.fake(user, access, modelUUIDs...) 225 } 226 227 func (f *fakeModelGrantRevokeAPI) fake(user, access string, modelUUIDs ...string) error { 228 f.user = user 229 f.access = access 230 f.modelUUIDs = modelUUIDs 231 return f.err 232 } 233 234 type fakeOffersGrantRevokeAPI struct { 235 err error 236 user string 237 access string 238 offerURLs []string 239 } 240 241 func (f *fakeOffersGrantRevokeAPI) Close() error { return nil } 242 243 func (f *fakeOffersGrantRevokeAPI) GrantOffer(user, access string, offerURLs ...string) error { 244 return f.fake(user, access, offerURLs...) 245 } 246 247 func (f *fakeOffersGrantRevokeAPI) RevokeOffer(user, access string, offerURLs ...string) error { 248 return f.fake(user, access, offerURLs...) 249 } 250 251 func (f *fakeOffersGrantRevokeAPI) fake(user, access string, offerURLs ...string) error { 252 f.user = user 253 f.access = access 254 f.offerURLs = append(f.offerURLs, offerURLs...) 255 return f.err 256 }