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

Implemented gwctl describe policycrds #2872

Merged

Conversation

Devaansh-Kumar
Copy link
Contributor

What type of PR is this?
Add one of the following kinds:
/area gwctl
/kind feature
/cc @gauravkghildiyal

What this PR does / why we need it:
Implement gwctl describe policycrds command

Which issue(s) this PR fixes:
Fixes #2870

Does this PR introduce a user-facing change?:

Implemented command `gwctl describe policycrds`

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. release-note Denotes a PR that will be considered when it comes time to generate release notes. area/gwctl kind/feature Categorizes issue or PR as related to a new feature. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 14, 2024
@k8s-ci-robot
Copy link
Contributor

Hi @Devaansh-Kumar. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@Devaansh-Kumar Devaansh-Kumar marked this pull request as ready for review March 14, 2024 12:37
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 14, 2024
@gauravkghildiyal
Copy link
Member

/assign

@@ -196,6 +201,36 @@ func (p PolicyCRD) IsClusterScoped() bool {
return p.crd.Spec.Scope == apiextensionsv1.ClusterScoped
}

func (p PolicyCRD) Spec() map[string]interface{} {
Copy link
Member

Choose a reason for hiding this comment

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

These helper functions seem to be purely concerned with printing at the moment. Lets keep them in the printer package.

@@ -148,3 +150,65 @@ func (pp *PoliciesPrinter) PrintDescribeView(policies []policymanager.Policy) {
}
}
}

type policyCrdDescribeView struct {
// PolicyCrd *apiextensionsv1.CustomResourceDefinition `json:",omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

Does this comment need to be cleaned up?

@@ -354,3 +354,155 @@ timeoutpolicies.bar.com Direct Namespaced 5m
t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got, want, diff)
}
}

func TestPolicyCrd_PrintDescribeView(t *testing.T) {
// fakeClock := testingclock.NewFakeClock(time.Now())
Copy link
Member

Choose a reason for hiding this comment

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

Can we clean this up if we don't need a fakeClock? Else, can we evaluate if we need a fakeClock and use it?

params := utils.MustParamsForTest(t, common.MustClientsForTest(t, objects...))
pp := &PoliciesPrinter{
Out: &bytes.Buffer{},
// Clock: fakeClock,
Copy link
Member

Choose a reason for hiding this comment

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

Same comment as above.

Kind: CustomResourceDefinition
Metadata:
creationTimestamp: null
labels:
Copy link
Member

Choose a reason for hiding this comment

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

For things like label, annotations etc which we're including outside the metadata, maybe we should not print them twice?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, I will remove the label and annotations outside as its more difficult to remove from within metadata

Copy link
Member

Choose a reason for hiding this comment

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

Lets try using concrete types and see if that helps ease this as well.

policyCrdList = params.PolicyManager.GetCRDs()
} else {
var found bool
policyCrd, found := params.PolicyManager.GetCRD(args[1])
Copy link
Member

Choose a reason for hiding this comment

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

For users, args[1] would usually mean the actual "name" of the CRD. It's worth noting here that the "name" of the CRD is not the policyCrdID which is being used as the "key" for the policyCRDs map within manager.go.

This means that if someone does gwctl describe policycrds mycrd.foo.bar, it might not work.

I think we need to modify the GetCRD function to accept a crdName and then manually search for the CRD in the map and return the right one.

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 I agree with this. I will make the changes

APIVersion string `json:",omitempty"`
Kind string `json:",omitempty"`
Metadata map[string]interface{} `json:",omitempty"`
Spec map[string]interface{} `json:",omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

Will using the concrete type here instead of map[string]interface{} make things simple? Any reason why we purposely want to keep this generic?

Same comment for Metadata and Status

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, initially I used concrete types itself, but the output was not being parsed properly by yaml package, so I had to convert it to map[string]interface{}.
Should I leave it as it is or do you suggest any other alternative?

Copy link
Member

Choose a reason for hiding this comment

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

Can you elaborate on what problem you run into if you use something like this:

	Metadata    *metav1.ObjectMeta                              `json:",omitempty"`
	Spec        *apiextensionsv1.CustomResourceDefinitionSpec   `json:",omitempty"`
	Status      *apiextensionsv1.CustomResourceDefinitionStatus `json:",omitempty"`

I think this should make things very easy. Am I missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My mistake, I was not dereferencing the type, due to which it wasnt parsing properly. I works fine now

@Devaansh-Kumar
Copy link
Contributor Author

@gauravkghildiyal I have resolved the above issues, just reconfirm this comment once: #2872 (comment)

APIVersion string `json:",omitempty"`
Kind string `json:",omitempty"`
Metadata map[string]interface{} `json:",omitempty"`
Spec map[string]interface{} `json:",omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

Can you elaborate on what problem you run into if you use something like this:

	Metadata    *metav1.ObjectMeta                              `json:",omitempty"`
	Spec        *apiextensionsv1.CustomResourceDefinitionSpec   `json:",omitempty"`
	Status      *apiextensionsv1.CustomResourceDefinitionStatus `json:",omitempty"`

I think this should make things very easy. Am I missing something?

Kind: CustomResourceDefinition
Metadata:
creationTimestamp: null
labels:
Copy link
Member

Choose a reason for hiding this comment

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

Lets try using concrete types and see if that helps ease this as well.

Status map[string]interface{} `json:",omitempty"`
}

func (pp *PoliciesPrinter) PolicyCrd_PrintDescribeView(policyCrds []policymanager.PolicyCRD) {
Copy link
Member

Choose a reason for hiding this comment

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

This isn't a blocker, but it would be nice if we could adjust the overall evolving names of other functions as well:

PrintPoliciesGetView
PrintPoliciesDescribeView
PrintPolicyCRDsGetView
PrintPolicyCRDsDescribeView

If we do include this change, lets correspondingly change the Test function names as well :)

@Devaansh-Kumar
Copy link
Contributor Author

@gauravkghildiyal I have resolved the above issues, please review

Copy link
Member

@gauravkghildiyal gauravkghildiyal left a comment

Choose a reason for hiding this comment

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

gwctl/cmd/describe.go Outdated Show resolved Hide resolved
@gauravkghildiyal
Copy link
Member

@Devaansh-Kumar I see you pushed some new changes...is https://github.com/kubernetes-sigs/gateway-api/pull/2872/files#r1534775341 still a work in progress?

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Apr 2, 2024
@Devaansh-Kumar
Copy link
Contributor Author

@Devaansh-Kumar I see you pushed some new changes...is https://github.com/kubernetes-sigs/gateway-api/pull/2872/files#r1534775341 still a work in progress?

/ok-to-test

@gauravkghildiyal I have already left a comment on that thread before, I think I have already solved it but maybe you are asking for something else that I dont understand.

You had told to not print out Labels and Annotations twice as they appear in Metadata as well. So I changed the code to only print Metadata. Am I missing something?

@gauravkghildiyal
Copy link
Member

Am I missing something?

Can we try to get those outside Metadata please, as per the original plan. I'm hoping it won't be too challenging now (correct me if I'm wrong)

@Devaansh-Kumar
Copy link
Contributor Author

Devaansh-Kumar commented Apr 2, 2024

Am I missing something?

Can we try to get those outside Metadata please, as per the original plan. I'm hoping it won't be too challenging now (correct me if I'm wrong)

Ok, now I understood what you wanted. You want me to parse the entire *metav1.ObjectMeta struct and not include label and annotations, right?

@Devaansh-Kumar
Copy link
Contributor Author

@gauravkghildiyal I have tried out your suggested change here by creating a new function ExcludeFieldsFromStruct to remove fields from a struct. I put this in a seperate file so that we can use this in the future as well.

Labels:
gateway.networking.k8s.io/policy: inherited
Metadata:
creationTimestamp: null
Copy link
Member

@jongwooo jongwooo Apr 2, 2024

Choose a reason for hiding this comment

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

Consider using fakeClock to validate the output for creationTimestamp.
Ref. #2822

fakeClock := testingclock.NewFakeClock(time.Now())

Copy link
Member

Choose a reason for hiding this comment

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

+1

@gauravkghildiyal
Copy link
Member

@Devaansh-Kumar

How about something like this:

type policyCrdDescribeView struct {
	Name        string                                          `json:",omitempty"`
	Namespace   string                                          `json:",omitempty"`
	APIVersion  string                                          `json:",omitempty"`
	Kind        string                                          `json:",omitempty"`
	Labels      map[string]string                               `json:",omitempty"`
	Annotations map[string]string                               `json:",omitempty"`
	Metadata    *metav1.ObjectMeta                              `json:",omitempty"`
	Spec        *apiextensionsv1.CustomResourceDefinitionSpec   `json:",omitempty"`
	Status      *apiextensionsv1.CustomResourceDefinitionStatus `json:",omitempty"`
}
.
.
.
		metadata := crd.ObjectMeta.DeepCopy()
		// Remove fields which are printed independently from the metadata.
		metadata.Name = ""
		metadata.Namespace = ""
		metadata.Labels = nil
		metadata.Annotations = nil

		views := []policyCrdDescribeView{
			{
				Name:      crd.Name,
				Namespace: crd.Namespace,
			},
			{
				APIVersion: crd.APIVersion,
				Kind:       crd.Kind,
			},
			{
				Labels:      crd.Labels,
				Annotations: crd.Annotations,
			},
			{
				Metadata: metadata,
			},
			{
				Spec: &crd.Spec,
			},
			{
				Status: &crd.Status,
			},
		}

I guess you won't need the ExcludeFieldsFromStruct then? The intent was/is:

  • To avoid duplication
  • And show important fields at the top level (like kubectl), instead of within metadata.

@gauravkghildiyal
Copy link
Member

/label tide/merge-method-squash

@k8s-ci-robot k8s-ci-robot added the tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges. label Apr 3, 2024
@Devaansh-Kumar
Copy link
Contributor Author

@gauravkghildiyal I have made the necessary changes, please review

@gauravkghildiyal
Copy link
Member

Thanks for getting this through @Devaansh-Kumar

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Apr 4, 2024
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Devaansh-Kumar, 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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 4, 2024
@k8s-ci-robot k8s-ci-robot merged commit 947463f into kubernetes-sigs:main Apr 4, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/gwctl cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/feature Categorizes issue or PR as related to a new feature. lgtm "Looks good to me", indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement gwctl describe policycrds
4 participants