-
Notifications
You must be signed in to change notification settings - Fork 493
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
gwctl: Introduce a --for
flag to filter results related to a specified resource.
#3068
gwctl: Introduce a --for
flag to filter results related to a specified resource.
#3068
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: gauravkghildiyal The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
8d423fb
to
3ff810b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all the great work on this @gauravkghildiyal!
gwctl/cmd/root.go
Outdated
@@ -26,31 +25,45 @@ import ( | |||
"github.com/spf13/cobra" | |||
"k8s.io/klog/v2" | |||
|
|||
"sigs.k8s.io/gateway-api/gwctl/pkg/common" | |||
"sigs.k8s.io/gateway-api/gwctl/pkg/policymanager" | |||
cmdutils "sigs.k8s.io/gateway-api/gwctl/pkg/utils" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Package name doesn't really match path - maybe the scope of the package expanded over time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch. Changed to use the default name.
gwctl/pkg/utils/types.go
Outdated
type Factory interface { | ||
K8sClients() (*common.K8sClients, error) | ||
PolicyManager() (*policymanager.PolicyManager, error) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this need to be an interface? Are you expecting other implementations of the interface to be added in the future? (Not saying this is necessarily bad, just trying to understand the use case).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice question. Added an internal comment for future context as well. Happy to explain it differently if needed.
// INTERNAL COMMENT:
// - The reason for an interface here is to be able to inject this dependency
// during unit tests.
// - The reason for the "factory" pattern is to delay the construction of the
// objects for when the commands get run (as opposed to when the commands
// are registered in Cobra). This is required because during registration of
// the commands, we will need to inject this dependency, but we cannot
// construct the dependency because it depends on some flag values which are
// only known during the runtime of the command.
Namespace: httpRouteNode.HTTPRoute.GetNamespace(), | ||
} | ||
var referenceAccepted bool | ||
for _, referenceGrantNode := range backendNode.ReferenceGrants { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would probably be useful to have some basic scalability tests - let's say 100 of each kind of resources with different levels of connections between to help keep some basic understanding of the impact each additional change like this adds. Not a blocker for this PR, but could be useful as a follow up issue for someone to tackle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes of course you have the right thoughts/concerns. I certainly know that computing all such relations (including all the other ones) will definitely take some time. I have a few thoughts about how this user experience will look like. Will share / discuss separately.
// Backend does not exist in the resourceModel (maybe because of some | ||
// error), so skip processing this backend. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like some debug logging could be useful here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure added one log.
The verbosity is a bit higher since a relevant error (with more precise details) for this specific case should have been logged in the previous looping construct i.e. Step 1
rootCmd.AddCommand(NewSubCommand(factory, os.Stdout, commandNameGet)) | ||
rootCmd.AddCommand(NewSubCommand(factory, os.Stdout, commandNameDescribe)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very neat bit of cleanup and refactoring (along with the new subcommand file), nicely done!
if kubeConfigPath == "" { | ||
kubeConfigPath = os.Getenv("KUBECONFIG") | ||
if kubeConfigPath == "" { | ||
kubeConfigPath = path.Join(os.Getenv("HOME"), ".kube/config") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm rusty here, but I thought if you left kubeconfig path empty when initializing clients, they'd already choose a sane default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah I gave it a try and from what I understand, that part is supposed to work when the process is running within a kubernetes clusters (so it can assume certain environment variables being set and so on).
Though that's a good callout. Added an action item to #2761 to figure out what the best approach here is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review, @robscott
gwctl/cmd/root.go
Outdated
@@ -26,31 +25,45 @@ import ( | |||
"github.com/spf13/cobra" | |||
"k8s.io/klog/v2" | |||
|
|||
"sigs.k8s.io/gateway-api/gwctl/pkg/common" | |||
"sigs.k8s.io/gateway-api/gwctl/pkg/policymanager" | |||
cmdutils "sigs.k8s.io/gateway-api/gwctl/pkg/utils" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch. Changed to use the default name.
Namespace: httpRouteNode.HTTPRoute.GetNamespace(), | ||
} | ||
var referenceAccepted bool | ||
for _, referenceGrantNode := range backendNode.ReferenceGrants { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes of course you have the right thoughts/concerns. I certainly know that computing all such relations (including all the other ones) will definitely take some time. I have a few thoughts about how this user experience will look like. Will share / discuss separately.
// Backend does not exist in the resourceModel (maybe because of some | ||
// error), so skip processing this backend. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure added one log.
The verbosity is a bit higher since a relevant error (with more precise details) for this specific case should have been logged in the previous looping construct i.e. Step 1
gwctl/pkg/utils/types.go
Outdated
type Factory interface { | ||
K8sClients() (*common.K8sClients, error) | ||
PolicyManager() (*policymanager.PolicyManager, error) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice question. Added an internal comment for future context as well. Happy to explain it differently if needed.
// INTERNAL COMMENT:
// - The reason for an interface here is to be able to inject this dependency
// during unit tests.
// - The reason for the "factory" pattern is to delay the construction of the
// objects for when the commands get run (as opposed to when the commands
// are registered in Cobra). This is required because during registration of
// the commands, we will need to inject this dependency, but we cannot
// construct the dependency because it depends on some flag values which are
// only known during the runtime of the command.
if kubeConfigPath == "" { | ||
kubeConfigPath = os.Getenv("KUBECONFIG") | ||
if kubeConfigPath == "" { | ||
kubeConfigPath = path.Join(os.Getenv("HOME"), ".kube/config") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah I gave it a try and from what I understand, that part is supposed to work when the process is running within a kubernetes clusters (so it can assume certain environment variables being set and so on).
Though that's a good callout. Added an action item to #2761 to figure out what the best approach here is.
…y (-v) flag. Get rid of global flag variables like kubeConfigPath.
discoverBackendsForHTTPRoutes().
For example: * gwctl get backends --for gateway/ns2/my-gateway * gwctl get gateways --for httproute/ns1/my-httproute * gwctl get gateways --for gatewayclass/foo-gatewayclass
…ses() and discoverBackendsForHTTPRoutes().
a20a9cd
to
611b912
Compare
(Rebased) |
611b912
to
2092ffd
Compare
Thanks @gauravkghildiyal! /lgtm |
…ied resource. (kubernetes-sigs#3068) * Remove unnecessary flags exposed by klog and only expose the verbosity (-v) flag. Get rid of global flag variables like kubeConfigPath. * Remove duplication in Get and Describe commands. * Add missing discovery functions discoverGatewaysForGatewayClasses() and discoverBackendsForHTTPRoutes(). * Add --for flag for filtering resources based on an associated resource. For example: * gwctl get backends --for gateway/ns2/my-gateway * gwctl get gateways --for httproute/ns1/my-httproute * gwctl get gateways --for gatewayclass/foo-gatewayclass * fixup! Remove duplication in Get and Describe commands. * fixup! Add missing discovery functions discoverGatewaysForGatewayClasses() and discoverBackendsForHTTPRoutes(). * fixup! Remove duplication in Get and Describe commands. * fixup! Add --for flag for filtering resources based on an associated resource.
…ied resource. (kubernetes-sigs#3068) * Remove unnecessary flags exposed by klog and only expose the verbosity (-v) flag. Get rid of global flag variables like kubeConfigPath. * Remove duplication in Get and Describe commands. * Add missing discovery functions discoverGatewaysForGatewayClasses() and discoverBackendsForHTTPRoutes(). * Add --for flag for filtering resources based on an associated resource. For example: * gwctl get backends --for gateway/ns2/my-gateway * gwctl get gateways --for httproute/ns1/my-httproute * gwctl get gateways --for gatewayclass/foo-gatewayclass * fixup! Remove duplication in Get and Describe commands. * fixup! Add missing discovery functions discoverGatewaysForGatewayClasses() and discoverBackendsForHTTPRoutes(). * fixup! Remove duplication in Get and Describe commands. * fixup! Add --for flag for filtering resources based on an associated resource.
What type of PR is this?
/kind feature
What this PR does / why we need it:
This PR achieves two broad things:
Add --for flag for filtering resources based on an associated resource.
For example:
Remove duplication from cli setup of Get and Describe commands. This inturn
allows both commands to share feataures/flags (when applicable) without the
need to manually configure them independently for each of them
Which issue(s) this PR fixes:
Fixes #
Does this PR introduce a user-facing change?: