github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/apiserver/common" 14 "github.com/juju/juju/cmd/juju/model" 15 "github.com/juju/juju/jujuclient" 16 "github.com/juju/juju/jujuclient/jujuclienttesting" 17 "github.com/juju/juju/testing" 18 ) 19 20 type grantRevokeSuite struct { 21 testing.FakeJujuXDGDataHomeSuite 22 fake *fakeGrantRevokeAPI 23 cmdFactory func(*fakeGrantRevokeAPI) cmd.Command 24 store *jujuclienttesting.MemStore 25 } 26 27 const ( 28 fooModelUUID = "0701e916-3274-46e4-bd12-c31aff89cee3" 29 barModelUUID = "0701e916-3274-46e4-bd12-c31aff89cee4" 30 bazModelUUID = "0701e916-3274-46e4-bd12-c31aff89cee5" 31 model1ModelUUID = "0701e916-3274-46e4-bd12-c31aff89cee6" 32 model2ModelUUID = "0701e916-3274-46e4-bd12-c31aff89cee7" 33 ) 34 35 func (s *grantRevokeSuite) SetUpTest(c *gc.C) { 36 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 37 s.fake = &fakeGrantRevokeAPI{} 38 39 // Set up the current controller, and write just enough info 40 // so we don't try to refresh 41 controllerName := "test-master" 42 43 s.store = jujuclienttesting.NewMemStore() 44 s.store.CurrentControllerName = controllerName 45 s.store.Controllers[controllerName] = jujuclient.ControllerDetails{} 46 s.store.Accounts[controllerName] = jujuclient.AccountDetails{ 47 User: "bob", 48 } 49 s.store.Models = map[string]*jujuclient.ControllerModels{ 50 controllerName: { 51 Models: map[string]jujuclient.ModelDetails{ 52 "bob/foo": jujuclient.ModelDetails{fooModelUUID}, 53 "bob/bar": jujuclient.ModelDetails{barModelUUID}, 54 "bob/baz": jujuclient.ModelDetails{bazModelUUID}, 55 "bob/model1": jujuclient.ModelDetails{model1ModelUUID}, 56 "bob/model2": jujuclient.ModelDetails{model2ModelUUID}, 57 }, 58 }, 59 } 60 } 61 62 func (s *grantRevokeSuite) run(c *gc.C, args ...string) (*cmd.Context, error) { 63 command := s.cmdFactory(s.fake) 64 return testing.RunCommand(c, command, args...) 65 } 66 67 func (s *grantRevokeSuite) TestPassesValues(c *gc.C) { 68 user := "sam" 69 models := []string{fooModelUUID, barModelUUID, bazModelUUID} 70 _, err := s.run(c, "sam", "read", "foo", "bar", "baz") 71 c.Assert(err, jc.ErrorIsNil) 72 c.Assert(s.fake.user, jc.DeepEquals, user) 73 c.Assert(s.fake.modelUUIDs, jc.DeepEquals, models) 74 c.Assert(s.fake.access, gc.Equals, "read") 75 } 76 77 func (s *grantRevokeSuite) TestAccess(c *gc.C) { 78 sam := "sam" 79 _, err := s.run(c, "sam", "write", "model1", "model2") 80 c.Assert(err, jc.ErrorIsNil) 81 c.Assert(s.fake.user, jc.DeepEquals, sam) 82 c.Assert(s.fake.modelUUIDs, jc.DeepEquals, []string{model1ModelUUID, model2ModelUUID}) 83 c.Assert(s.fake.access, gc.Equals, "write") 84 } 85 86 func (s *grantRevokeSuite) TestBlockGrant(c *gc.C) { 87 s.fake.err = common.OperationBlockedError("TestBlockGrant") 88 _, err := s.run(c, "sam", "read", "foo") 89 testing.AssertOperationWasBlocked(c, err, ".*TestBlockGrant.*") 90 } 91 92 type grantSuite struct { 93 grantRevokeSuite 94 } 95 96 var _ = gc.Suite(&grantSuite{}) 97 98 func (s *grantSuite) SetUpTest(c *gc.C) { 99 s.grantRevokeSuite.SetUpTest(c) 100 s.cmdFactory = func(fake *fakeGrantRevokeAPI) cmd.Command { 101 c, _ := model.NewGrantCommandForTest(fake, s.store) 102 return c 103 } 104 } 105 106 func (s *grantSuite) TestInit(c *gc.C) { 107 wrappedCmd, grantCmd := model.NewGrantCommandForTest(s.fake, s.store) 108 err := testing.InitCommand(wrappedCmd, []string{}) 109 c.Assert(err, gc.ErrorMatches, "no user specified") 110 111 err = testing.InitCommand(wrappedCmd, []string{"bob", "read", "model1", "model2"}) 112 c.Assert(err, jc.ErrorIsNil) 113 114 c.Assert(grantCmd.User, gc.Equals, "bob") 115 c.Assert(grantCmd.ModelNames, jc.DeepEquals, []string{"model1", "model2"}) 116 117 err = testing.InitCommand(wrappedCmd, []string{}) 118 c.Assert(err, gc.ErrorMatches, `no user specified`) 119 } 120 121 // TestInitGrantAddModel checks that both the documented 'add-model' access and 122 // the backwards-compatible 'addmodel' work to grant the AddModel permission. 123 func (s *grantSuite) TestInitGrantAddModel(c *gc.C) { 124 wrappedCmd, grantCmd := model.NewGrantCommandForTest(s.fake, s.store) 125 // The documented case, add-model. 126 err := testing.InitCommand(wrappedCmd, []string{"bob", "add-model"}) 127 c.Check(err, jc.ErrorIsNil) 128 129 // The backwards-compatible case, addmodel. 130 err = testing.InitCommand(wrappedCmd, []string{"bob", "addmodel"}) 131 c.Check(err, jc.ErrorIsNil) 132 c.Assert(grantCmd.Access, gc.Equals, "add-model") 133 } 134 135 type revokeSuite struct { 136 grantRevokeSuite 137 } 138 139 var _ = gc.Suite(&revokeSuite{}) 140 141 func (s *revokeSuite) SetUpTest(c *gc.C) { 142 s.grantRevokeSuite.SetUpTest(c) 143 s.cmdFactory = func(fake *fakeGrantRevokeAPI) cmd.Command { 144 c, _ := model.NewRevokeCommandForTest(fake, s.store) 145 return c 146 } 147 } 148 149 func (s *revokeSuite) TestInit(c *gc.C) { 150 wrappedCmd, revokeCmd := model.NewRevokeCommandForTest(s.fake, s.store) 151 err := testing.InitCommand(wrappedCmd, []string{}) 152 c.Assert(err, gc.ErrorMatches, "no user specified") 153 154 err = testing.InitCommand(wrappedCmd, []string{"bob", "read", "model1", "model2"}) 155 c.Assert(err, jc.ErrorIsNil) 156 157 c.Assert(revokeCmd.User, gc.Equals, "bob") 158 c.Assert(revokeCmd.ModelNames, jc.DeepEquals, []string{"model1", "model2"}) 159 160 err = testing.InitCommand(wrappedCmd, []string{}) 161 c.Assert(err, gc.ErrorMatches, `no user specified`) 162 163 } 164 165 // TestInitRevokeAddModel checks that both the documented 'add-model' access and 166 // the backwards-compatible 'addmodel' work to revoke the AddModel permission. 167 func (s *grantSuite) TestInitRevokeAddModel(c *gc.C) { 168 wrappedCmd, revokeCmd := model.NewRevokeCommandForTest(s.fake, s.store) 169 // The documented case, add-model. 170 err := testing.InitCommand(wrappedCmd, []string{"bob", "add-model"}) 171 c.Check(err, jc.ErrorIsNil) 172 173 // The backwards-compatible case, addmodel. 174 err = testing.InitCommand(wrappedCmd, []string{"bob", "addmodel"}) 175 c.Check(err, jc.ErrorIsNil) 176 c.Assert(revokeCmd.Access, gc.Equals, "add-model") 177 } 178 179 func (s *grantSuite) TestModelAccessForController(c *gc.C) { 180 wrappedCmd, _ := model.NewRevokeCommandForTest(s.fake, s.store) 181 err := testing.InitCommand(wrappedCmd, []string{"bob", "write"}) 182 msg := strings.Replace(err.Error(), "\n", "", -1) 183 c.Check(msg, gc.Matches, `You have specified a model access permission "write".*`) 184 } 185 186 func (s *grantSuite) TestControllerAccessForModel(c *gc.C) { 187 wrappedCmd, _ := model.NewRevokeCommandForTest(s.fake, s.store) 188 err := testing.InitCommand(wrappedCmd, []string{"bob", "superuser", "default"}) 189 msg := strings.Replace(err.Error(), "\n", "", -1) 190 c.Check(msg, gc.Matches, `You have specified a controller access permission "superuser".*`) 191 } 192 193 type fakeGrantRevokeAPI struct { 194 err error 195 user string 196 access string 197 modelUUIDs []string 198 } 199 200 func (f *fakeGrantRevokeAPI) Close() error { return nil } 201 202 func (f *fakeGrantRevokeAPI) GrantModel(user, access string, modelUUIDs ...string) error { 203 return f.fake(user, access, modelUUIDs...) 204 } 205 206 func (f *fakeGrantRevokeAPI) RevokeModel(user, access string, modelUUIDs ...string) error { 207 return f.fake(user, access, modelUUIDs...) 208 } 209 210 func (f *fakeGrantRevokeAPI) fake(user, access string, modelUUIDs ...string) error { 211 f.user = user 212 f.access = access 213 f.modelUUIDs = modelUUIDs 214 return f.err 215 }