github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/model/grantrevokecloud_test.go (about) 1 // Copyright 2018 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 coremodel "github.com/juju/juju/core/model" 17 "github.com/juju/juju/jujuclient" 18 "github.com/juju/juju/testing" 19 ) 20 21 type grantRevokeCloudSuite struct { 22 testing.FakeJujuXDGDataHomeSuite 23 fakeCloudAPI *fakeCloudGrantRevokeAPI 24 cmdFactory func(*fakeCloudGrantRevokeAPI) cmd.Command 25 store *jujuclient.MemStore 26 } 27 28 func (s *grantRevokeCloudSuite) SetUpTest(c *gc.C) { 29 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 30 s.fakeCloudAPI = &fakeCloudGrantRevokeAPI{} 31 32 // Set up the current controller, and write just enough info 33 // so we don't try to refresh 34 controllerName := "test-master" 35 36 s.store = jujuclient.NewMemStore() 37 s.store.CurrentControllerName = controllerName 38 s.store.Controllers[controllerName] = jujuclient.ControllerDetails{} 39 s.store.Accounts[controllerName] = jujuclient.AccountDetails{ 40 User: "bob", 41 } 42 s.store.Models = map[string]*jujuclient.ControllerModels{ 43 controllerName: { 44 Models: map[string]jujuclient.ModelDetails{ 45 "bob/foo": {ModelUUID: fooModelUUID, ModelType: coremodel.IAAS}, 46 }, 47 }, 48 } 49 } 50 51 func (s *grantRevokeCloudSuite) run(c *gc.C, args ...string) (*cmd.Context, error) { 52 command := s.cmdFactory(s.fakeCloudAPI) 53 return cmdtesting.RunCommand(c, command, args...) 54 } 55 56 func (s *grantRevokeCloudSuite) TestAccess(c *gc.C) { 57 sam := "sam" 58 _, err := s.run(c, "sam", "add-model", "cloud1", "cloud2") 59 c.Assert(err, jc.ErrorIsNil) 60 c.Assert(s.fakeCloudAPI.user, jc.DeepEquals, sam) 61 c.Assert(s.fakeCloudAPI.clouds, jc.DeepEquals, []string{"cloud1", "cloud2"}) 62 c.Assert(s.fakeCloudAPI.access, gc.Equals, "add-model") 63 } 64 65 func (s *grantRevokeCloudSuite) TestBlockGrant(c *gc.C) { 66 s.fakeCloudAPI.err = common.OperationBlockedError("TestBlockGrant") 67 _, err := s.run(c, "sam", "admin", "foo", "cloud") 68 testing.AssertOperationWasBlocked(c, err, ".*TestBlockGrant.*") 69 } 70 71 type grantCloudSuite struct { 72 grantRevokeCloudSuite 73 } 74 75 var _ = gc.Suite(&grantCloudSuite{}) 76 77 func (s *grantCloudSuite) SetUpTest(c *gc.C) { 78 s.grantRevokeCloudSuite.SetUpTest(c) 79 s.cmdFactory = func(fakeCloudAPI *fakeCloudGrantRevokeAPI) cmd.Command { 80 c, _ := model.NewGrantCloudCommandForTest(fakeCloudAPI, s.store) 81 return c 82 } 83 } 84 85 // TestInitGrantAddModel checks that both the documented 'add-model' access and 86 // the backwards-compatible 'addmodel' work to grant the AddModel permission. 87 func (s *grantCloudSuite) TestInitGrantAddModel(c *gc.C) { 88 wrappedCmd, grantCmd := model.NewGrantCloudCommandForTest(nil, s.store) 89 // The documented case, add-model. 90 err := cmdtesting.InitCommand(wrappedCmd, []string{"bob", "add-model", "cloud"}) 91 c.Check(err, jc.ErrorIsNil) 92 93 // The backwards-compatible case, addmodel. 94 err = cmdtesting.InitCommand(wrappedCmd, []string{"bob", "addmodel", "cloud"}) 95 c.Check(err, jc.ErrorIsNil) 96 c.Assert(grantCmd.Access, gc.Equals, "add-model") 97 } 98 99 type revokeCloudSuite struct { 100 grantRevokeCloudSuite 101 } 102 103 var _ = gc.Suite(&revokeCloudSuite{}) 104 105 func (s *revokeCloudSuite) SetUpTest(c *gc.C) { 106 s.grantRevokeCloudSuite.SetUpTest(c) 107 s.cmdFactory = func(fakeCloudAPI *fakeCloudGrantRevokeAPI) cmd.Command { 108 c, _ := model.NewRevokeCloudCommandForTest(fakeCloudAPI, s.store) 109 return c 110 } 111 } 112 113 func (s *revokeCloudSuite) TestInit(c *gc.C) { 114 wrappedCmd, revokeCmd := model.NewRevokeCloudCommandForTest(nil, s.store) 115 err := cmdtesting.InitCommand(wrappedCmd, []string{}) 116 c.Assert(err, gc.ErrorMatches, "no user specified") 117 118 err = cmdtesting.InitCommand(wrappedCmd, []string{"bob", "add-model", "cloud1", "cloud2"}) 119 c.Assert(err, jc.ErrorIsNil) 120 121 c.Assert(revokeCmd.User, gc.Equals, "bob") 122 c.Assert(revokeCmd.Clouds, jc.DeepEquals, []string{"cloud1", "cloud2"}) 123 124 err = cmdtesting.InitCommand(wrappedCmd, []string{}) 125 c.Assert(err, gc.ErrorMatches, `no user specified`) 126 127 } 128 129 // TestInitRevokeAddModel checks that both the documented 'add-model' access and 130 // the backwards-compatible 'addmodel' work to revoke the AddModel permission. 131 func (s *grantCloudSuite) TestInitRevokeAddModel(c *gc.C) { 132 wrappedCmd, revokeCmd := model.NewRevokeCloudCommandForTest(nil, s.store) 133 // The documented case, add-model. 134 err := cmdtesting.InitCommand(wrappedCmd, []string{"bob", "add-model", "cloud"}) 135 c.Check(err, jc.ErrorIsNil) 136 137 // The backwards-compatible case, addmodel. 138 err = cmdtesting.InitCommand(wrappedCmd, []string{"bob", "addmodel", "cloud"}) 139 c.Check(err, jc.ErrorIsNil) 140 c.Assert(revokeCmd.Access, gc.Equals, "add-model") 141 } 142 143 func (s *grantCloudSuite) TestWrongAccess(c *gc.C) { 144 wrappedCmd, _ := model.NewRevokeCloudCommandForTest(nil, s.store) 145 err := cmdtesting.InitCommand(wrappedCmd, []string{"bob", "write", "cloud"}) 146 msg := strings.Replace(err.Error(), "\n", "", -1) 147 c.Check(msg, gc.Matches, `"write" cloud access not valid`) 148 } 149 150 type fakeCloudGrantRevokeAPI struct { 151 err error 152 user string 153 access string 154 clouds []string 155 } 156 157 func (f *fakeCloudGrantRevokeAPI) Close() error { return nil } 158 159 func (f *fakeCloudGrantRevokeAPI) GrantCloud(user, access string, clouds ...string) error { 160 return f.fake(user, access, clouds...) 161 } 162 163 func (f *fakeCloudGrantRevokeAPI) RevokeCloud(user, access string, clouds ...string) error { 164 return f.fake(user, access, clouds...) 165 } 166 167 func (f *fakeCloudGrantRevokeAPI) fake(user, access string, clouds ...string) error { 168 f.user = user 169 f.access = access 170 f.clouds = clouds 171 return f.err 172 }