Skip to content

Commit

Permalink
chore: handle role tags (#1467)
Browse files Browse the repository at this point in the history
* chore: parse role tags

* chore: move ToJAASTag test to internal/jimm

The ToJAASTag method was moved from the jujuapi to the jimm a while back but the test was not moved.
Additionally adds tests for roles.
  • Loading branch information
kian99 authored Nov 26, 2024
1 parent a6e5b7a commit 9d36ed4
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 122 deletions.
30 changes: 30 additions & 0 deletions internal/jimm/access.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,15 @@ func (j *JIMM) ToJAASTag(ctx context.Context, tag *ofganames.Tag, resolveUUIDs b
return "", errors.E(err, fmt.Sprintf("failed to fetch group information: %s", group.UUID))
}
return tagToString(jimmnames.GroupTagKind, group.Name), nil
case jimmnames.RoleTagKind:
role := dbmodel.RoleEntry{
UUID: tag.ID,
}
err := j.Database.GetRole(ctx, &role)
if err != nil {
return "", errors.E(err, fmt.Sprintf("failed to fetch role information: %s", role.UUID))
}
return tagToString(jimmnames.RoleTagKind, role.Name), nil
case names.CloudTagKind:
cloud := dbmodel.Cloud{
Name: tag.ID,
Expand Down Expand Up @@ -532,6 +541,25 @@ func (t *tagResolver) groupTag(ctx context.Context, db *db.Database) (*ofga.Enti
return ofganames.ConvertTagWithRelation(entry.ResourceTag(), t.relation), nil
}

func (t *tagResolver) roleTag(ctx context.Context, db *db.Database) (*ofga.Entity, error) {
zapctx.Debug(
ctx,
"Resolving JIMM tags to Juju tags for tag kind: role",
zap.String("role-name", t.trailer),
)
if t.resourceUUID != "" {
return ofganames.ConvertTagWithRelation(jimmnames.NewRoleTag(t.resourceUUID), t.relation), nil
}
entry := dbmodel.RoleEntry{Name: t.trailer}

err := db.GetRole(ctx, &entry)
if err != nil {
return nil, errors.E(fmt.Sprintf("role %s not found", t.trailer))
}

return ofganames.ConvertTagWithRelation(entry.ResourceTag(), t.relation), nil
}

func (t *tagResolver) controllerTag(ctx context.Context, jimmUUID string, db *db.Database) (*ofga.Entity, error) {
zapctx.Debug(
ctx,
Expand Down Expand Up @@ -649,6 +677,8 @@ func resolveTag(jimmUUID string, db *db.Database, tag string) (*ofganames.Tag, e
return resolver.userTag(ctx)
case jimmnames.GroupTagKind:
return resolver.groupTag(ctx, db)
case jimmnames.RoleTagKind:
return resolver.roleTag(ctx, db)
case names.ControllerTagKind:
return resolver.controllerTag(ctx, jimmUUID, db)
case names.ModelTagKind:
Expand Down
154 changes: 145 additions & 9 deletions internal/jimm/access_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ func TestParseAndValidateTag(t *testing.T) {
err = j.Database.Migrate(ctx, false)
c.Assert(err, qt.IsNil)

user, _, _, model, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)
user, _, _, model, _, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)

jimmTag := "model-" + user.Name + "/" + model.Name + "#administrator"

Expand Down Expand Up @@ -495,7 +495,7 @@ func TestResolveTags(t *testing.T) {
err := j.Database.Migrate(ctx, false)
c.Assert(err, qt.IsNil)

identity, group, controller, model, offer, cloud, _ := createTestControllerEnvironment(ctx, c, j.Database)
identity, group, controller, model, offer, cloud, _, role := createTestControllerEnvironment(ctx, c, j.Database)

testCases := []struct {
desc string
Expand All @@ -517,6 +517,14 @@ func TestResolveTags(t *testing.T) {
desc: "map group UUID with relation",
input: "group-" + group.UUID + "#member",
expected: ofganames.ConvertTagWithRelation(jimmnames.NewGroupTag(group.UUID), ofganames.MemberRelation),
}, {
desc: "map role UUID",
input: "role-" + role.UUID,
expected: ofganames.ConvertTag(jimmnames.NewRoleTag(role.UUID)),
}, {
desc: "map role UUID with relation",
input: "role-" + role.UUID + "#assignee",
expected: ofganames.ConvertTagWithRelation(jimmnames.NewRoleTag(role.UUID), ofganames.AssigneeRelation),
}, {
desc: "map jimm controller",
input: "controller-" + "jimm",
Expand Down Expand Up @@ -575,7 +583,7 @@ func TestResolveTupleObjectHandlesErrors(t *testing.T) {
err := j.Database.Migrate(ctx, false)
c.Assert(err, qt.IsNil)

_, _, controller, model, offer, _, _ := createTestControllerEnvironment(ctx, c, j.Database)
_, _, controller, model, offer, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)

type test struct {
input string
Expand Down Expand Up @@ -630,6 +638,129 @@ func TestResolveTupleObjectHandlesErrors(t *testing.T) {
}
}

func TestToJAASTag(t *testing.T) {
c := qt.New(t)
ctx := context.Background()

now := time.Now().UTC().Round(time.Millisecond)
j := &jimm.JIMM{
UUID: uuid.NewString(),
Database: db.Database{
DB: jimmtest.PostgresDB(c, func() time.Time { return now }),
},
}

err := j.Database.Migrate(ctx, false)
c.Assert(err, qt.IsNil)

user, group, controller, model, applicationOffer, cloud, _, role := createTestControllerEnvironment(ctx, c, j.Database)

serviceAccountId := petname.Generate(2, "-") + "@serviceaccount"

tests := []struct {
tag *ofganames.Tag
expectedJAASTag string
expectedError string
}{{
tag: ofganames.ConvertTag(user.ResourceTag()),
expectedJAASTag: "user-" + user.Name,
}, {
tag: ofganames.ConvertTag(jimmnames.NewServiceAccountTag(serviceAccountId)),
expectedJAASTag: "serviceaccount-" + serviceAccountId,
}, {
tag: ofganames.ConvertTag(group.ResourceTag()),
expectedJAASTag: "group-" + group.Name,
}, {
tag: ofganames.ConvertTag(controller.ResourceTag()),
expectedJAASTag: "controller-" + controller.Name,
}, {
tag: ofganames.ConvertTag(model.ResourceTag()),
expectedJAASTag: "model-" + user.Name + "/" + model.Name,
}, {
tag: ofganames.ConvertTag(applicationOffer.ResourceTag()),
expectedJAASTag: "applicationoffer-" + applicationOffer.URL,
}, {
tag: &ofganames.Tag{},
expectedError: "unexpected tag kind: ",
}, {
tag: ofganames.ConvertTag(cloud.ResourceTag()),
expectedJAASTag: "cloud-" + cloud.Name,
}, {
tag: ofganames.ConvertTag(role.ResourceTag()),
expectedJAASTag: "role-" + role.Name,
}}
for _, test := range tests {
t, err := j.ToJAASTag(ctx, test.tag, true)
if test.expectedError != "" {
c.Assert(err, qt.ErrorMatches, test.expectedError)
} else {
c.Assert(err, qt.IsNil)
c.Assert(t, qt.Equals, test.expectedJAASTag)
}
}
}

func TestToJAASTagNoUUIDResolution(t *testing.T) {
c := qt.New(t)
ctx := context.Background()

now := time.Now().UTC().Round(time.Millisecond)
j := &jimm.JIMM{
UUID: uuid.NewString(),
Database: db.Database{
DB: jimmtest.PostgresDB(c, func() time.Time { return now }),
},
}

err := j.Database.Migrate(ctx, false)
c.Assert(err, qt.IsNil)

user, group, controller, model, applicationOffer, cloud, _, role := createTestControllerEnvironment(ctx, c, j.Database)
serviceAccountId := petname.Generate(2, "-") + "@serviceaccount"

tests := []struct {
tag *ofganames.Tag
expectedJAASTag string
expectedError string
}{{
tag: ofganames.ConvertTag(user.ResourceTag()),
expectedJAASTag: "user-" + user.Name,
}, {
tag: ofganames.ConvertTag(jimmnames.NewServiceAccountTag(serviceAccountId)),
expectedJAASTag: "serviceaccount-" + serviceAccountId,
}, {
tag: ofganames.ConvertTag(group.ResourceTag()),
expectedJAASTag: "group-" + group.UUID,
}, {
tag: ofganames.ConvertTag(controller.ResourceTag()),
expectedJAASTag: "controller-" + controller.UUID,
}, {
tag: ofganames.ConvertTag(model.ResourceTag()),
expectedJAASTag: "model-" + model.UUID.String,
}, {
tag: ofganames.ConvertTag(applicationOffer.ResourceTag()),
expectedJAASTag: "applicationoffer-" + applicationOffer.UUID,
}, {
tag: ofganames.ConvertTag(cloud.ResourceTag()),
expectedJAASTag: "cloud-" + cloud.Name,
}, {
tag: ofganames.ConvertTag(role.ResourceTag()),
expectedJAASTag: "role-" + role.UUID,
}, {
tag: &ofganames.Tag{},
expectedJAASTag: "-",
}}
for _, test := range tests {
t, err := j.ToJAASTag(ctx, test.tag, false)
if test.expectedError != "" {
c.Assert(err, qt.ErrorMatches, test.expectedError)
} else {
c.Assert(err, qt.IsNil)
c.Assert(t, qt.Equals, test.expectedJAASTag)
}
}
}

// createTestControllerEnvironment is a utility function creating the necessary components of adding a:
// - user
// - user group
Expand All @@ -638,6 +769,7 @@ func TestResolveTupleObjectHandlesErrors(t *testing.T) {
// - application offer
// - cloud
// - cloud credential
// - role
//
// Into the test database, returning the dbmodels to be utilised for values within tests.
//
Expand All @@ -654,7 +786,8 @@ func createTestControllerEnvironment(ctx context.Context, c *qt.C, db db.Databas
dbmodel.Model,
dbmodel.ApplicationOffer,
dbmodel.Cloud,
dbmodel.CloudCredential) {
dbmodel.CloudCredential,
dbmodel.RoleEntry) {

_, err := db.AddGroup(ctx, "test-group")
c.Assert(err, qt.IsNil)
Expand Down Expand Up @@ -735,7 +868,10 @@ func createTestControllerEnvironment(ctx context.Context, c *qt.C, db db.Databas
c.Assert(err, qt.IsNil)
c.Assert(len(offer.UUID), qt.Equals, 36)

return *u, group, controller, model, offer, cloud, cred
role, err := db.AddRole(ctx, petname.Generate(2, "-"))
c.Assert(err, qt.IsNil)

return *u, group, controller, model, offer, cloud, cred, *role
}

func TestAddGroup(t *testing.T) {
Expand Down Expand Up @@ -867,7 +1003,7 @@ func TestRemoveGroup(t *testing.T) {
err = j.Database.Migrate(ctx, false)
c.Assert(err, qt.IsNil)

user, group, _, _, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)
user, group, _, _, _, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)
u := openfga.NewUser(&user, ofgaClient)
u.JimmAdmin = true

Expand Down Expand Up @@ -897,7 +1033,7 @@ func TestRemoveGroupRemovesTuples(t *testing.T) {
err = j.Database.Migrate(ctx, false)
c.Assert(err, qt.IsNil)

user, group, controller, model, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)
user, group, controller, model, _, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)

_, err = j.Database.AddGroup(ctx, "test-group2")
c.Assert(err, qt.IsNil)
Expand Down Expand Up @@ -981,7 +1117,7 @@ func TestRenameGroup(t *testing.T) {
err = j.Database.Migrate(ctx, false)
c.Assert(err, qt.IsNil)

user, group, controller, model, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)
user, group, controller, model, _, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)

u := openfga.NewUser(&user, ofgaClient)
u.JimmAdmin = true
Expand Down Expand Up @@ -1073,7 +1209,7 @@ func TestListGroups(t *testing.T) {
err = j.Database.Migrate(ctx, false)
c.Assert(err, qt.IsNil)

user, group, _, _, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)
user, group, _, _, _, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)

u := openfga.NewUser(&user, ofgaClient)
u.JimmAdmin = true
Expand Down
2 changes: 1 addition & 1 deletion internal/jimm/identity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestFetchIdentity(t *testing.T) {
err = j.Database.Migrate(ctx, false)
c.Assert(err, qt.IsNil)

user, _, _, _, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)
user, _, _, _, _, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)
u, err := j.FetchIdentity(ctx, user.Name)
c.Assert(err, qt.IsNil)
c.Assert(u.Name, qt.Equals, user.Name)
Expand Down
4 changes: 2 additions & 2 deletions internal/jimm/relation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestListRelationshipTuples(t *testing.T) {
u := openfga.NewUser(&dbmodel.Identity{Name: "[email protected]"}, ofgaClient)
u.JimmAdmin = true

user, _, controller, model, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)
user, _, controller, model, _, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database)
c.Assert(err, qt.IsNil)

err = j.AddRelation(ctx, u, []apiparams.RelationshipTuple{
Expand Down Expand Up @@ -192,7 +192,7 @@ func TestListObjectRelations(t *testing.T) {
u := openfga.NewUser(&dbmodel.Identity{Name: "[email protected]"}, ofgaClient)
u.JimmAdmin = true

user, group, controller, model, _, cloud, _ := createTestControllerEnvironment(ctx, c, j.Database)
user, group, controller, model, _, cloud, _, _ := createTestControllerEnvironment(ctx, c, j.Database)
c.Assert(err, qt.IsNil)

err = j.AddRelation(ctx, u, []apiparams.RelationshipTuple{
Expand Down
2 changes: 1 addition & 1 deletion internal/jimm/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestGetResources(t *testing.T) {

err = j.Database.Migrate(ctx, false)
c.Assert(err, qt.IsNil)
_, _, controller, model, applicationOffer, cloud, _ := createTestControllerEnvironment(ctx, c, j.Database)
_, _, controller, model, applicationOffer, cloud, _, _ := createTestControllerEnvironment(ctx, c, j.Database)

ids := []string{applicationOffer.UUID, cloud.Name, controller.UUID, model.UUID.String}

Expand Down
Loading

0 comments on commit 9d36ed4

Please sign in to comment.