Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS-6952 add service account command #1141

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions api/jimm.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,8 @@ func (c *Client) MigrateModel(req *params.MigrateModelRequest) (*jujuparams.Init
err := c.caller.APICall("JIMM", 4, "", "MigrateModel", req, &response)
return &response, err
}

// AddServiceAccount binds a service account to a user allowing them to manage it.
func (c *Client) AddServiceAccount(req *params.AddServiceAccountRequest) error {
return c.caller.APICall("JIMM", 4, "", "AddServiceAccount", req, nil)
}
7 changes: 4 additions & 3 deletions cmd/jimmctl/cmd/addcloudtocontroller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,21 @@ import (
gc "gopkg.in/check.v1"

"github.com/canonical/jimm/cmd/jimmctl/cmd"
"github.com/canonical/jimm/internal/cmdtest"
"github.com/canonical/jimm/internal/dbmodel"
"github.com/canonical/jimm/internal/errors"
"github.com/canonical/jimm/internal/openfga"
ofganames "github.com/canonical/jimm/internal/openfga/names"
)

type addCloudToControllerSuite struct {
jimmSuite
cmdtest.JimmSuite
}

var _ = gc.Suite(&addCloudToControllerSuite{})

func (s *addCloudToControllerSuite) SetUpTest(c *gc.C) {
s.jimmSuite.SetUpTest(c)
s.JimmSuite.SetUpTest(c)

// We add user bob, who is a JIMM administrator.
err := s.JIMM.Database.UpdateIdentity(context.Background(), &dbmodel.Identity{
Expand Down Expand Up @@ -166,7 +167,7 @@ clouds:
c.Log(test.about)
tmpfile, cleanupFunc := writeTempFile(c, test.cloudInfo)

bClient := s.userBakeryClient("bob@external")
bClient := s.UserBakeryClient("bob@external")
// Running the command succeeds
newCmd := cmd.NewAddCloudToControllerCommandForTesting(s.ClientStore(), bClient, test.cloudByNameFunc)
var err error
Expand Down
7 changes: 4 additions & 3 deletions cmd/jimmctl/cmd/addcontroller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import (

apiparams "github.com/canonical/jimm/api/params"
"github.com/canonical/jimm/cmd/jimmctl/cmd"
"github.com/canonical/jimm/internal/cmdtest"
"github.com/canonical/jimm/internal/jimmtest"
)

type addControllerSuite struct {
jimmSuite
cmdtest.JimmSuite
}

var _ = gc.Suite(&addControllerSuite{})
Expand All @@ -37,7 +38,7 @@ func (s *addControllerSuite) TestAddControllerSuperuser(c *gc.C) {
defer os.RemoveAll(tmpdir)

// alice is superuser
bClient := s.userBakeryClient("alice")
bClient := s.UserBakeryClient("alice")
ctx, err := cmdtesting.RunCommand(c, cmd.NewAddControllerCommandForTesting(s.ClientStore(), bClient), tmpfile)
c.Assert(err, gc.IsNil)
c.Assert(cmdtesting.Stdout(ctx), gc.Matches, `name: controller-1
Expand Down Expand Up @@ -100,7 +101,7 @@ func (s *addControllerSuite) TestAddController(c *gc.C) {
defer os.RemoveAll(tmpdir)

// bob is not superuser
bClient := s.userBakeryClient("bob")
bClient := s.UserBakeryClient("bob")
_, err := cmdtesting.RunCommand(c, cmd.NewAddControllerCommandForTesting(s.ClientStore(), bClient), tmpfile)
c.Assert(err, gc.ErrorMatches, `unauthorized \(unauthorized access\)`)
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/jimmctl/cmd/controllerinfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import (
gc "gopkg.in/check.v1"

"github.com/canonical/jimm/cmd/jimmctl/cmd"
"github.com/canonical/jimm/internal/cmdtest"
)

type controllerInfoSuite struct {
jimmSuite
cmdtest.JimmSuite
}

var _ = gc.Suite(&controllerInfoSuite{})
Expand Down
5 changes: 3 additions & 2 deletions cmd/jimmctl/cmd/crossmodelquery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/json"

"github.com/canonical/jimm/cmd/jimmctl/cmd"
"github.com/canonical/jimm/internal/cmdtest"
"github.com/canonical/jimm/internal/jimmtest"
"github.com/juju/cmd/v3/cmdtesting"
jujuparams "github.com/juju/juju/rpc/params"
Expand All @@ -15,15 +16,15 @@ import (
)

type crossModelQuerySuite struct {
jimmSuite
cmdtest.JimmSuite
}

var _ = gc.Suite(&crossModelQuerySuite{})

func (s *crossModelQuerySuite) TestCrossModelQueryCommand(c *gc.C) {
// Test setup.
store := s.ClientStore()
bClient := s.userBakeryClient("alice")
bClient := s.UserBakeryClient("alice")

s.AddController(c, "controller-2", s.APIInfo(c))
cct := names.NewCloudCredentialTag(jimmtest.TestCloudName + "/alice@external/cred")
Expand Down
7 changes: 4 additions & 3 deletions cmd/jimmctl/cmd/grantauditlogaccess_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,26 @@ import (
gc "gopkg.in/check.v1"

"github.com/canonical/jimm/cmd/jimmctl/cmd"
"github.com/canonical/jimm/internal/cmdtest"
)

type grantAuditLogAccessSuite struct {
jimmSuite
cmdtest.JimmSuite
}

// TODO (alesstimec) uncomment once granting/revoking is reimplemented
//var _ = gc.Suite(&grantAuditLogAccessSuite{})

func (s *grantAuditLogAccessSuite) TestGrantAuditLogAccessSuperuser(c *gc.C) {
// alice is superuser
bClient := s.userBakeryClient("alice")
bClient := s.UserBakeryClient("alice")
_, err := cmdtesting.RunCommand(c, cmd.NewGrantAuditLogAccessCommandForTesting(s.ClientStore(), bClient), "bob@external")
c.Assert(err, gc.IsNil)
}

func (s *grantAuditLogAccessSuite) TestGrantAuditLogAccess(c *gc.C) {
// bob is not superuser
bClient := s.userBakeryClient("bob")
bClient := s.UserBakeryClient("bob")
_, err := cmdtesting.RunCommand(c, cmd.NewGrantAuditLogAccessCommandForTesting(s.ClientStore(), bClient), "bob@external")
c.Assert(err, gc.ErrorMatches, `unauthorized \(unauthorized access\)`)
}
33 changes: 17 additions & 16 deletions cmd/jimmctl/cmd/group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,95 +11,96 @@ import (
gc "gopkg.in/check.v1"

"github.com/canonical/jimm/cmd/jimmctl/cmd"
"github.com/canonical/jimm/internal/cmdtest"
"github.com/canonical/jimm/internal/dbmodel"
)

type groupSuite struct {
jimmSuite
cmdtest.JimmSuite
}

var _ = gc.Suite(&groupSuite{})

func (s *groupSuite) TestAddGroupSuperuser(c *gc.C) {
// alice is superuser
bClient := s.userBakeryClient("alice")
bClient := s.UserBakeryClient("alice")
_, err := cmdtesting.RunCommand(c, cmd.NewAddGroupCommandForTesting(s.ClientStore(), bClient), "test-group")
c.Assert(err, gc.IsNil)

group := &dbmodel.GroupEntry{Name: "test-group"}
err = s.jimmSuite.JIMM.Database.GetGroup(context.TODO(), group)
err = s.JimmSuite.JIMM.Database.GetGroup(context.TODO(), group)
c.Assert(err, gc.IsNil)
c.Assert(group.ID, gc.Equals, uint(1))
c.Assert(group.Name, gc.Equals, "test-group")
}

func (s *groupSuite) TestAddGroup(c *gc.C) {
// bob is not superuser
bClient := s.userBakeryClient("bob")
bClient := s.UserBakeryClient("bob")
_, err := cmdtesting.RunCommand(c, cmd.NewAddGroupCommandForTesting(s.ClientStore(), bClient), "test-group")
c.Assert(err, gc.ErrorMatches, `unauthorized \(unauthorized access\)`)
}

func (s *groupSuite) TestRenameGroupSuperuser(c *gc.C) {
// alice is superuser
bClient := s.userBakeryClient("alice")
bClient := s.UserBakeryClient("alice")

err := s.jimmSuite.JIMM.Database.AddGroup(context.TODO(), "test-group")
err := s.JimmSuite.JIMM.Database.AddGroup(context.TODO(), "test-group")
c.Assert(err, gc.IsNil)

_, err = cmdtesting.RunCommand(c, cmd.NewRenameGroupCommandForTesting(s.ClientStore(), bClient), "test-group", "renamed-group")
c.Assert(err, gc.IsNil)

group := &dbmodel.GroupEntry{Name: "renamed-group"}
err = s.jimmSuite.JIMM.Database.GetGroup(context.TODO(), group)
err = s.JimmSuite.JIMM.Database.GetGroup(context.TODO(), group)
c.Assert(err, gc.IsNil)
c.Assert(group.ID, gc.Equals, uint(1))
c.Assert(group.Name, gc.Equals, "renamed-group")
}

func (s *groupSuite) TestRenameGroup(c *gc.C) {
// bob is not superuser
bClient := s.userBakeryClient("bob")
bClient := s.UserBakeryClient("bob")
_, err := cmdtesting.RunCommand(c, cmd.NewRenameGroupCommandForTesting(s.ClientStore(), bClient), "test-group", "renamed-group")
c.Assert(err, gc.ErrorMatches, `unauthorized \(unauthorized access\)`)
}

func (s *groupSuite) TestRemoveGroupSuperuser(c *gc.C) {
// alice is superuser
bClient := s.userBakeryClient("alice")
bClient := s.UserBakeryClient("alice")

err := s.jimmSuite.JIMM.Database.AddGroup(context.TODO(), "test-group")
err := s.JimmSuite.JIMM.Database.AddGroup(context.TODO(), "test-group")
c.Assert(err, gc.IsNil)

_, err = cmdtesting.RunCommand(c, cmd.NewRemoveGroupCommandForTesting(s.ClientStore(), bClient), "test-group", "-y")
c.Assert(err, gc.IsNil)

group := &dbmodel.GroupEntry{Name: "test-group"}
err = s.jimmSuite.JIMM.Database.GetGroup(context.TODO(), group)
err = s.JimmSuite.JIMM.Database.GetGroup(context.TODO(), group)
c.Assert(err, gc.ErrorMatches, "record not found")
}

func (s *groupSuite) TestRemoveGroupWithoutFlag(c *gc.C) {
// alice is superuser
bClient := s.userBakeryClient("alice")
bClient := s.UserBakeryClient("alice")

_, err := cmdtesting.RunCommand(c, cmd.NewRemoveGroupCommandForTesting(s.ClientStore(), bClient), "test-group")
c.Assert(err.Error(), gc.Matches, "Failed to read from input.")
}

func (s *groupSuite) TestRemoveGroup(c *gc.C) {
// bob is not superuser
bClient := s.userBakeryClient("bob")
bClient := s.UserBakeryClient("bob")
_, err := cmdtesting.RunCommand(c, cmd.NewRemoveGroupCommandForTesting(s.ClientStore(), bClient), "test-group", "-y")
c.Assert(err, gc.ErrorMatches, `unauthorized \(unauthorized access\)`)
}

func (s *groupSuite) TestListGroupsSuperuser(c *gc.C) {
// alice is superuser
bClient := s.userBakeryClient("alice")
bClient := s.UserBakeryClient("alice")

for i := 0; i < 3; i++ {
err := s.jimmSuite.JIMM.Database.AddGroup(context.TODO(), fmt.Sprint("test-group", i))
err := s.JimmSuite.JIMM.Database.AddGroup(context.TODO(), fmt.Sprint("test-group", i))
c.Assert(err, gc.IsNil)
}

Expand All @@ -113,7 +114,7 @@ func (s *groupSuite) TestListGroupsSuperuser(c *gc.C) {

func (s *groupSuite) TestListGroups(c *gc.C) {
// bob is not superuser
bClient := s.userBakeryClient("bob")
bClient := s.UserBakeryClient("bob")
_, err := cmdtesting.RunCommand(c, cmd.NewListGroupsCommandForTesting(s.ClientStore(), bClient), "test-group")
c.Assert(err, gc.ErrorMatches, `unauthorized \(unauthorized access\)`)
}
5 changes: 3 additions & 2 deletions cmd/jimmctl/cmd/importcloudcredentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import (
gc "gopkg.in/check.v1"

"github.com/canonical/jimm/cmd/jimmctl/cmd"
"github.com/canonical/jimm/internal/cmdtest"
"github.com/canonical/jimm/internal/dbmodel"
)

type importCloudCredentialsSuite struct {
jimmSuite
cmdtest.JimmSuite
}

var _ = gc.Suite(&importCloudCredentialsSuite{})
Expand Down Expand Up @@ -62,7 +63,7 @@ func (s *importCloudCredentialsSuite) TestImportCloudCredentials(c *gc.C) {
c.Assert(err, gc.IsNil)

// alice is superuser
bClient := s.userBakeryClient("alice")
bClient := s.UserBakeryClient("alice")
_, err = cmdtesting.RunCommand(c, cmd.NewImportCloudCredentialsCommandForTesting(s.ClientStore(), bClient), tmpfile)
c.Assert(err, gc.IsNil)

Expand Down
17 changes: 9 additions & 8 deletions cmd/jimmctl/cmd/importmodel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ import (
gc "gopkg.in/check.v1"

"github.com/canonical/jimm/cmd/jimmctl/cmd"
"github.com/canonical/jimm/internal/cmdtest"
"github.com/canonical/jimm/internal/dbmodel"
"github.com/canonical/jimm/internal/jimmtest"
)

type importModelSuite struct {
jimmSuite
cmdtest.JimmSuite
}

var _ = gc.Suite(&importModelSuite{})
Expand All @@ -42,7 +43,7 @@ func (s *importModelSuite) TestImportModelSuperuser(c *gc.C) {
defer m.Close()

// alice is superuser
bClient := s.userBakeryClient("alice")
bClient := s.UserBakeryClient("alice")
_, err = cmdtesting.RunCommand(c, cmd.NewImportModelCommandForTesting(s.ClientStore(), bClient), "controller-1", m.ModelUUID())
c.Assert(err, gc.IsNil)

Expand All @@ -69,7 +70,7 @@ func (s *importModelSuite) TestImportModelFromLocalUser(c *gc.C) {
c.Assert(err, gc.Equals, nil)

// alice is superuser
bClient := s.userBakeryClient("alice")
bClient := s.UserBakeryClient("alice")
_, err = cmdtesting.RunCommand(c, cmd.NewImportModelCommandForTesting(s.ClientStore(), bClient), "controller-1", mt.Id(), "--owner", "alice@external")
c.Assert(err, gc.IsNil)

Expand Down Expand Up @@ -100,31 +101,31 @@ func (s *importModelSuite) TestImportModelUnauthorized(c *gc.C) {
defer m.Close()

// bob is not superuser
bClient := s.userBakeryClient("bob")
bClient := s.UserBakeryClient("bob")
_, err = cmdtesting.RunCommand(c, cmd.NewImportModelCommandForTesting(s.ClientStore(), bClient), "controller-1", m.ModelUUID())
c.Assert(err, gc.ErrorMatches, `unauthorized \(unauthorized access\)`)
}

func (s *importModelSuite) TestImportModelNoController(c *gc.C) {
bClient := s.userBakeryClient("bob")
bClient := s.UserBakeryClient("bob")
_, err := cmdtesting.RunCommand(c, cmd.NewImportModelCommandForTesting(s.ClientStore(), bClient))
c.Assert(err, gc.ErrorMatches, `controller not specified`)
}

func (s *importModelSuite) TestImportModelNoModelUUID(c *gc.C) {
bClient := s.userBakeryClient("bob")
bClient := s.UserBakeryClient("bob")
_, err := cmdtesting.RunCommand(c, cmd.NewImportModelCommandForTesting(s.ClientStore(), bClient), "controller-id")
c.Assert(err, gc.ErrorMatches, `model uuid not specified`)
}

func (s *importModelSuite) TestImportModelInvalidModelUUID(c *gc.C) {
bClient := s.userBakeryClient("bob")
bClient := s.UserBakeryClient("bob")
_, err := cmdtesting.RunCommand(c, cmd.NewImportModelCommandForTesting(s.ClientStore(), bClient), "controller-id", "not-a-uuid")
c.Assert(err, gc.ErrorMatches, `invalid model uuid`)
}

func (s *importModelSuite) TestImportModelTooManyArgs(c *gc.C) {
bClient := s.userBakeryClient("bob")
bClient := s.UserBakeryClient("bob")
_, err := cmdtesting.RunCommand(c, cmd.NewImportModelCommandForTesting(s.ClientStore(), bClient), "controller-id", "not-a-uuid", "spare-argument")
c.Assert(err, gc.ErrorMatches, `too many args`)
}
7 changes: 4 additions & 3 deletions cmd/jimmctl/cmd/listauditevents_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import (
gc "gopkg.in/check.v1"

"github.com/canonical/jimm/cmd/jimmctl/cmd"
"github.com/canonical/jimm/internal/cmdtest"
"github.com/canonical/jimm/internal/jimmtest"
)

type listAuditEventsSuite struct {
jimmSuite
cmdtest.JimmSuite
}

var _ = gc.Suite(&listAuditEventsSuite{})
Expand All @@ -26,7 +27,7 @@ func (s *listAuditEventsSuite) TestListAuditEventsSuperuser(c *gc.C) {
s.AddModel(c, names.NewUserTag("charlie@external"), "model-2", names.NewCloudTag(jimmtest.TestCloudName), jimmtest.TestCloudRegionName, cct)

// alice is superuser
bClient := s.userBakeryClient("alice")
bClient := s.UserBakeryClient("alice")
context, err := cmdtesting.RunCommand(c, cmd.NewListAuditEventsCommandForTesting(s.ClientStore(), bClient))
c.Assert(err, gc.IsNil)
c.Assert(cmdtesting.Stdout(context), gc.Matches,
Expand Down Expand Up @@ -65,7 +66,7 @@ func (s *listAuditEventsSuite) TestListAuditEventsStatus(c *gc.C) {
s.AddModel(c, names.NewUserTag("charlie@external"), "model-2", names.NewCloudTag(jimmtest.TestCloudName), jimmtest.TestCloudRegionName, cct)

// bob is not superuser
bClient := s.userBakeryClient("bob")
bClient := s.UserBakeryClient("bob")
_, err := cmdtesting.RunCommand(c, cmd.NewListAuditEventsCommandForTesting(s.ClientStore(), bClient))
c.Assert(err, gc.ErrorMatches, `unauthorized \(unauthorized access\)`)
}
Loading
Loading