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

Add more filtering options to entry count/show and agent count/list #4714

Merged
merged 19 commits into from
Mar 27, 2024

Conversation

FedeNQ
Copy link
Contributor

@FedeNQ FedeNQ commented Dec 6, 2023

Pull Request check list

  • Commit conforms to CONTRIBUTING.md?
  • Proper tests/regressions included?
  • Documentation updated?

Affected functionality
Provides the possibility of add multiple flags to entry show, entry count, agent list and agent count commands.
Requires the approval of this PR in SPIRE-API-SDK

Description of change

Add the following flags:

  • Agent count/list:

    • selectors, matchSelectorsOn, banned, expiresBefore, attestationType, canReattest.
  • Entry count:

    • parentID, spiffeID, hint, federatesWith, downstream, matchFederatesWithOn, matchSelectorsOn
  • Entry show:

    • downstream

Which issue this PR fixes
Fixes #2137

Copy link
Member

@amartinezfayo amartinezfayo left a comment

Choose a reason for hiding this comment

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

Thank you @FedeNQ for this contribution, and sorry for the delay in the review.
I left some comments.

if len(s) > 10 {
return fmt.Errorf("date is too long")
}
_, err := time.Parse("2006-01-02", s)
Copy link
Member

Choose a reason for hiding this comment

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

Any reason to exclude the time here?
From a user experience perspective, I would probably consume this CLI with data that I got from other CLI commands. When the user list/shows agents, the output format of the Expiration time also includes the time (which I think it's useful). So when I'm filtering by expiration time, I would expect to use the same layout, like "2006-01-02 15:04:05 -0700 -07".

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 don't have a particular reason, so it could be changed.
Use time.Parse(time.RFC3339, s) it could be a good change?

Comment on lines 9 to 14
if len(s) < 10 {
return fmt.Errorf("date is too short")
}
if len(s) > 10 {
return fmt.Errorf("date is too long")
}
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure that we really need this validation, I would probably just leave the validation that is done by the time.Parse function. Were your intention to have more descriptive errors?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it was expected to guide the user about the error.

@@ -14,6 +14,14 @@ var (
Path to the SPIRE Server API socket (default "/tmp/spire-server/private/api.sock")
`
listUsage = `Usage of agent list:
-attestationType string
The SPIFFE ID of the nodes to list
Copy link
Member

Choose a reason for hiding this comment

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

The description doesn't match here. Since the name may not obviously indicate that this refers to the node attestor used, I would also probably include examples. Something like:
Filter by attestation type, like join_token or x509pop.


func (b *BoolFlag) Set(val string) error {
if val == "false" {
*b = 1
Copy link
Member

Choose a reason for hiding this comment

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

We could probably define constants for the true, false and default values. Something like cli.BoolFlagTrue, cli.BoolFlagFalse and cli.BoolFlagDefault. Then, consumers of the package can refer to those instead of having to look at this code to figure out that the 1, 2, and 0 values are used for that.

ByHint: req.ByHint,
ByDownstream: req.ByDownstream,
})
return int32(len(resp.Entries)), err
Copy link
Member

Choose a reason for hiding this comment

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

This will retrieve all the records for the registration entries from the backend database, while we need to retrieve a single record with the count. Maybe we could reuse the SQL query used in the listRegistrationEntries and perform a SQL COUNT operation over it? That way we would get as a result a single record with the count.

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 think it could be a valid approach, will try to change it

fs.Var(&c.selectors, "selector", "A colon-delimited type:value selector. Can be used more than once")
fs.StringVar(&c.attestationType, "attestationType", "", "The SPIFFE ID of the nodes to list")
Copy link
Member

Choose a reason for hiding this comment

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

The description doesn't match here.

@@ -49,6 +123,12 @@ func (c *countCommand) Run(ctx context.Context, _ *commoncli.Env, serverClient u
}

func (c *countCommand) AppendFlags(fs *flag.FlagSet) {
fs.Var(&c.selectors, "selector", "A colon-delimited type:value selector. Can be used more than once")
fs.StringVar(&c.attestationType, "attestationType", "", "The SPIFFE ID of the nodes to count")
Copy link
Member

Choose a reason for hiding this comment

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

The description doesn't match here.

@@ -40,8 +48,20 @@ var (
The SPIFFE ID of the agent to evict (agent identity)
`
countUsage = `Usage of agent count:
-attestationType string
Copy link
Member

Choose a reason for hiding this comment

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

The description doesn't match here.

| `-canReattest` | Filter based on string received, 'true': agents that can reattest, 'false': agents that can't reattest, other value will return all | |
| `-banned` | Filter based on string received, 'true': banned agents, 'false': not banned agents, other value will return all | |
| `-expiresBefore` | A date that indicates the time it should expired before. (format: YYYY-MM-DD)| |
| `-attestationType` | Filters agents to those matching the attestation type. | |
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
| `-attestationType` | Filters agents to those matching the attestation type. | |
| `-attestationType` | Filters agents to those matching the attestation type, like join_token or x509pop. | |

fs.StringVar(&c.attestationType, "attestationType", "", "The SPIFFE ID of the nodes to count")
fs.Var(&c.canReattest, "canReattest", "Filter based on string received, 'true': agents that can reattest, 'false': agents that can't reattest, other value will return all.")
fs.Var(&c.banned, "banned", "Filter based on string received, 'true': banned agents, 'false': not banned agents, other value will return all.")
fs.StringVar(&c.expiresBefore, "expiresBefore", "", "A date that indicates the time it should expired before, (format: YYYY-MM-DD)")
Copy link
Member

Choose a reason for hiding this comment

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

In the same way that we make it explicit in the description of other flags that the flag will apply a filter, I think that we should make it explicit here. Something like:
Filter by expiration time (format: "2006-01-02 15:04:05 -0700 -07").
I've commented about the format separately.

The same applies to other flags added that don't mention that a filter will be applied.

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
FedeNQ and others added 9 commits February 27, 2024 16:07
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: Federico Nahuel Quijada <63385953+FedeNQ@users.noreply.github.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
countReq.ByAttestationType = filter.ByAttestationType
}

// err is verified previously
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure if this comment should really be here?

Comment on lines 145 to 146
// err is verified previously
// countReq.ByExpiresBefore, _ = time.Parse("2006-01-02", filter.ByExpiresBefore)
Copy link
Member

Choose a reason for hiding this comment

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

Looks like we should remove this?

func (ds *Plugin) CountAttestedNodes(ctx context.Context) (count int32, err error) {
func (ds *Plugin) CountAttestedNodes(ctx context.Context, req *datastore.CountAttestedNodesRequest) (count int32, err error) {
if countAttestedNodesHasFilters(req) {
resp, err := listAttestedNodes(ctx, ds.db, ds.log, &datastore.ListAttestedNodesRequest{
Copy link
Member

Choose a reason for hiding this comment

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

I think that we need to make paginated requests here so we don't get all the records at once.

FetchSelectors: req.FetchSelectors,
ByCanReattest: req.ByCanReattest,
})
return int32(len(resp.Nodes)), err
Copy link
Member

Choose a reason for hiding this comment

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

Discussed this with @FedeNQ offline. Since the changes to avoid retrieving all the records are too complex, I suggest to keep it as is so we minimize the changes required in the datastore, which has a complex code already.

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
@FedeNQ FedeNQ force-pushed the add-filtering branch 2 times, most recently from adec60c to 296a77f Compare March 27, 2024 21:32
Signed-off-by: Federico Nahuel Quijada <63385953+FedeNQ@users.noreply.github.com>
Copy link
Member

@amartinezfayo amartinezfayo left a comment

Choose a reason for hiding this comment

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

Thank you @FedeNQ for this contribution, and for the patience in the review!

@amartinezfayo amartinezfayo merged commit 0727fa6 into spiffe:main Mar 27, 2024
32 checks passed
@amartinezfayo amartinezfayo added this to the 1.9.3 milestone Mar 27, 2024
@amartinezfayo amartinezfayo modified the milestones: 1.9.3, 1.9.4, 1.9.5 Apr 4, 2024
rushi47 pushed a commit to rushi47/spire that referenced this pull request Apr 11, 2024
…piffe#4714)

* add filtering options to count command

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* add more fields

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* Add filtering to entry & agent count/show/list commands

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* fix lint

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* add more unit test

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* Change count & list for entries

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* rollback

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* fix

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* fix lint

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* update go.mod & go.sum

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* fix windows message

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* update agent & entry message

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* update agent message

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* count entries & agent now uses pagination

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* remove comment

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* fix lint

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

* rollback

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>

---------

Signed-off-by: FedeNQ <fedenahuel07@gmail.com>
Signed-off-by: Federico Nahuel Quijada <63385953+FedeNQ@users.noreply.github.com>
@amartinezfayo amartinezfayo modified the milestones: 1.9.5, 1.9.6 May 8, 2024
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.

Add list-style filtering to agent and entry server CLI count commands
2 participants