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  }