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

Fixes to jimmctl auth relation list #1220

Merged
merged 16 commits into from
Jun 13, 2024

Conversation

pkulik0
Copy link
Contributor

@pkulik0 pkulik0 commented May 28, 2024

Description

This PR fixes a bugs in jimmctl auth relation list which cause:

  • an infinite loop of requesting the first page if the number of results go over defaultPageSize of 50.
  • invalid parsing of the serviceaccount tag

&

  • Small adjustments to the Makefile bring it up-to-date and unify naming of targets across files.

Engineering checklist

Check only items that apply

  • Documentation updated
  • Covered by unit tests
  • Covered by integration tests

Copy link

⚠️ This PR contains unsigned commits. To get your PR merged, please sign those commits (git rebase --exec 'git commit -S --amend --no-edit -n' @{upstream}) and force push them to this branch (git push --force-with-lease).

If you're new to commit signing, there are different ways to set it up:

Sign commits with gpg

Follow the steps below to set up commit signing with gpg:

  1. Generate a GPG key
  2. Add the GPG key to your GitHub account
  3. Configure git to use your GPG key for commit signing
Sign commits with ssh-agent

Follow the steps below to set up commit signing with ssh-agent:

  1. Generate an SSH key and add it to ssh-agent
  2. Add the SSH key to your GitHub account
  3. Configure git to use your SSH key for commit signing
Sign commits with 1Password

You can also sign commits using 1Password, which lets you sign commits with biometrics without the signing key leaving the local 1Password process.

Learn how to use 1Password to sign your commits.

Watch the demo

@pkulik0 pkulik0 force-pushed the CSS-8387-Fix-`jimmctl-auth-relation-list` branch from f3003f3 to 8240162 Compare May 28, 2024 11:28
_, err := cmdtesting.RunCommand(c, cmd.NewAddGroupCommandForTesting(s.ClientStore(), bClient), groupName)
c.Assert(err, gc.IsNil)

tabularOutput += fmt.Sprintf("\[email protected] member group-%-72s", groupName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come the use of -72s? I had to google as I don't see this often, for others, it left-justifies the text and prints a minimum of 72 chars.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output has whitespace after each line to match the length of the longest row. 72 is a hard-coded diff between the length of this string without groupName and the required line length.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe leave a comment to that effect, if someone were to add a new relation that increases/remove a relation and decreases the longest row, that will be annoying to debug.

cmd/jimmctl/cmd/relation_test.go Show resolved Hide resolved
@pkulik0 pkulik0 force-pushed the CSS-8387-Fix-`jimmctl-auth-relation-list` branch from d050539 to 5a90332 Compare May 28, 2024 16:31
@pkulik0 pkulik0 changed the title Fix relations pagination in jimmctl auth relation list Fixes to jimmctl auth relation list May 29, 2024
@pkulik0 pkulik0 requested a review from kian99 May 29, 2024 08:53
Copy link
Member

@babakks babakks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. Just a few comments.

@@ -111,13 +111,12 @@ endef

# Install packages required to develop JIMM and run tests.
APT_BASED := $(shell command -v apt-get >/dev/null; echo $$?)
sysdeps:
sys-deps:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I checked there are still a few more instances that point to sysdeps. Can you please update them as well?

Comment on lines 561 to 567
response, err := client.ListRelationshipTuples(&params)
if err != nil {
return nil, errors.E(err)
}
if response.ContinuationToken != "" {
response1, err := fetchRelations(client, params, response.ContinuationToken)
params.ContinuationToken = response.ContinuationToken
response1, err := fetchRelations(client, params)
Copy link
Member

@babakks babakks May 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(suggestion) Now that you're fixing this, can you please also refactor it and get rid of the recursive calls to fetchRelations? This should just be a simple loop that runs until it gets the same continuation token back.

We have done this kind of loop before. You can just replicate it.

https://github.com/babakks/jimm/blob/97e203f43c51969887aa52d524c28b3f05bf13a4/internal/openfga/user.go#L375-L393

c.Assert(err, gc.IsNil)
c.Assert(cmdtesting.Stdout(context), gc.Equals, relationsToTabularStr(expectedRelations))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand what you did here, but I think this actually is a bit against the purpose of the test.

The thing is, with this change, we'll have two implementations for tabular printing; one in the code (i.e., the formatRelationsTabular function that uses utiable under-the-hood), and the new relationsToTabularStr that you've made for testing. What we want to do is to make sure the former does its job as expected. So, we need to compare the output with something that we are absolutely sure that it's accurate. But, if we use the relationsToTabularStr helper method, we can never be sure because the helper method is not tested. Now, if we attempt to write a test for it, we again have to compare the output with a literal multiline string, like what we originally had in the test.

I'm not sure if I've conveyed my point clearly. But the gist is, if possible, we shouldn't assert against something that is not totally trusted to work as expected.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fully agree with this point, but in this situation I considered it trival enough to prefer a helper over an easily breakable hard-coded multiline string that requires perfectly matching whitespace on each line which gives you a headache on every change. The perspective of changing a few strings like this after possibly more tests get added seems dreading compared to, in my opinion, the minimal stink of this helper given its simple logic.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's get rid of the helper function, use export_test to export the formatting function used by the command and use that to write the expected output to a string, then compare.. i don't think there's any value in having a separate helper function here.. if we ever change tabular format, we'll need to change the helper function, too..

Comment on lines +397 to +398
case jimmnames.ServiceAccountTagKind:
return jimmnames.ServiceAccountTagKind + "-" + tag.ID, nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this. We need to update the tests to cover this as well. You can find the test function here:

https://github.com/babakks/jimm/blob/2750ee5242c18cbdb0ebb4c548ab6c2b367ae7c9/internal/jujuapi/access_control_test.go#L791

Please, in addition to a test case for the service account tag, add one more for the group tags (which we've missed adding before).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is still missing, a test in access_control.go for the changes to ToJAASTag.

Comment on lines +608 to +614
case jimmnames.ServiceAccountTagKind:
zapctx.Debug(
ctx,
"Resolving JIMM tags to Juju tags for tag kind: serviceaccount",
zap.String("serviceaccount-name", trailer),
)
return ofganames.ConvertTagWithRelation(jimmnames.NewServiceAccountTag(trailer), relation), nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(question) @alesstimec @ale8k @kian99 Just want to make sure; we cannot check for the service account existence at this stage? Because the tag might exist but the the service account has not yet logged in (and hence to Identity entry is associated to it), right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think we need a DB lookup at this point, no.. it's better to show "stale" tuples that might be left-overs and give admins the ability to delete them

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@babakks I believe that is correct:

the tag might exist but the the service account has not yet logged

Users work the same way

c.Assert(err, gc.IsNil)
c.Assert(cmdtesting.Stdout(context), gc.Equals, relationsToTabularStr(expectedRelations))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's get rid of the helper function, use export_test to export the formatting function used by the command and use that to write the expected output to a string, then compare.. i don't think there's any value in having a separate helper function here.. if we ever change tabular format, we'll need to change the helper function, too..

Comment on lines +608 to +614
case jimmnames.ServiceAccountTagKind:
zapctx.Debug(
ctx,
"Resolving JIMM tags to Juju tags for tag kind: serviceaccount",
zap.String("serviceaccount-name", trailer),
)
return ofganames.ConvertTagWithRelation(jimmnames.NewServiceAccountTag(trailer), relation), nil
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think we need a DB lookup at this point, no.. it's better to show "stale" tuples that might be left-overs and give admins the ability to delete them

Comment on lines 572 to 573
response.Tuples = tuples
return response, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit confusing to read because we are creating a new response object in each loop and then at the end using the last response. I'd prefer creating a response object above the for loop, and then renaming the current response variable to page, then append tuples to response.Tuples and finally return the response.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @kian99. We can just create a new apiparams.ListRelationshipTuplesResponse instance after the end of the loop and assign the tuples.

Comment on lines +397 to +398
case jimmnames.ServiceAccountTagKind:
return jimmnames.ServiceAccountTagKind + "-" + tag.ID, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is still missing, a test in access_control.go for the changes to ToJAASTag.

@@ -321,3 +323,7 @@ func NewMigrateModelCommandForTesting(store jujuclient.ClientStore, lp jujuapi.L

return modelcmd.WrapBase(cmd)
}

func FormatRelationsTabularForTesting(writer io.Writer, value interface{}) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it's just for the sake of exposing formatRelationsTabular you can do it like this (which makes it more consistent with other same usages like this one):

var FormatRelationsTabular = formatRelationsTabular

response1, err := fetchRelations(client, params)
tuples := make([]apiparams.RelationshipTuple, 0)
for {
response, err := client.ListRelationshipTuples(&params)
if err != nil {
return nil, errors.E(err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(suggestion) Can you please add an error message to this, like:

return nil, errors.E(err, "failed to fetch list of relationship tuples")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I'd caution against this because it would hide the underlying error. JIMM's error package is very poor in that it doesn't provide a clean way of masking or surfacing the underlying error. So here I think the best thing to do would be

errors.E(fmt.Sprintf("message: %s",err.Error()))

We'll need to improve it in the future but for now consider where you want to mask errors and where you want to present them to the user.

Comment on lines 572 to 573
response.Tuples = tuples
return response, nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @kian99. We can just create a new apiparams.ListRelationshipTuplesResponse instance after the end of the loop and assign the tuples.

@pkulik0 pkulik0 requested a review from a team as a code owner June 13, 2024 13:14
Copy link
Collaborator

@alesstimec alesstimec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@pkulik0 pkulik0 merged commit 0bceaa9 into v3 Jun 13, 2024
4 checks passed
@pkulik0 pkulik0 deleted the CSS-8387-Fix-`jimmctl-auth-relation-list` branch June 13, 2024 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants