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

tighten validation of inlining and metadata #504

Merged
merged 2 commits into from
Sep 3, 2024

Conversation

pohly
Copy link
Contributor

@pohly pohly commented Aug 21, 2024

This catches the following mistake:

type ResourceSliceList struct {
   metav1.ListMeta `json:"listMeta" protobuf:"bytes,1,opt,name=listMeta"`
   ...
}

The "listMeta" name matches the Go field name, but the convention is to call that JSON field "metadata".

The same applies to ObjectMeta.

While at it, usage of the empty JSON name also gets checked more thoroughly. This is a mistake which was not detected earlier:

type SomeStruct struct {
    SomeInt int `json:",inline"`
}

@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. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Aug 21, 2024
@k8s-ci-robot k8s-ci-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Aug 21, 2024
Copy link
Member

@Jefftree Jefftree left a comment

Choose a reason for hiding this comment

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

Minor comments.

cc @liggitt for changes affect api linting

@@ -0,0 +1,70 @@
/*
Copyright 2018 The Kubernetes Authors.
Copy link
Member

Choose a reason for hiding this comment

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

nit: 2024

@@ -136,6 +136,7 @@ type apiLinter struct {
func newAPILinter() *apiLinter {
return &apiLinter{
rules: []APIRule{
&rules.NamingConvention{},
Copy link
Member

Choose a reason for hiding this comment

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

Should we be more specific that this is only referring to ListMeta naming convention?

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 asked on Slack whether there should be other conventions that this should enforce:
https://kubernetes.slack.com/archives/C0409NGC1TK/p1724256359105049?thread_ts=1723854248.858719&cid=C0409NGC1TK

If there aren't then renaming makes sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's also for ObjectMeta. That wasn't in my original commit, but I've included it in the revised one.

// Validate evaluates API rule on type t and returns a list of field names in
// the type that violate the rule. Empty field name [""] implies the entire
// type violates the rule.
func (n *NamingConvention) Validate(t *types.Type) ([]string, error) {
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 add a test for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Absolutely. It's WIP because I wanted to be sure first that this is going in the right direction.

@pohly pohly force-pushed the naming-convention branch from ae7eba5 to 250daf8 Compare August 21, 2024 16:08
return false
}
jsonName := strings.Split(jsonTag, ",")[0]
if jsonName != "metadata" {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

"metadata" is excluded from name checking in

// Special case for object and list meta
"metadata",

The effect is that this mistake is not caught:

Items []ResourceSlice `json:"metadata" protobuf:"bytes,2,rep,name=metadata"`

An alternative to adding this NamingConvention rule would be to extend the NamesMatch rule:

  • Check for ListMeta and ObjectMeta there.
  • Those fields must be called "metadata".
  • Other fields that are called "metadata" must have matching Go and JSON names.

Copy link
Member

Choose a reason for hiding this comment

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

Something along those lines sounds like a good direction to me

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, PR updated accordingly.

I couldn't resist also addressing this false positive:

SomeInt int `json:""`

This wasn't reported because "" was also in the jsonNameBlacklist.

@pohly pohly force-pushed the naming-convention branch from 250daf8 to 3d12da0 Compare August 26, 2024 07:38
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Aug 26, 2024
@pohly pohly changed the title WIP: rules: enforce that ListMeta is called "metadata" tighten validation of inlining and metadata Aug 26, 2024
@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 Aug 26, 2024
Not checking empty JSON names and "metadata" has the effect that incorrect
usage of those does not get detected. These new unit tests demonstrate
that. Fixing the behavior and updating the tests accordingly will follow.
@liggitt
Copy link
Member

liggitt commented Aug 26, 2024

/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 Aug 26, 2024
@pohly
Copy link
Contributor Author

pohly commented Aug 26, 2024

Using this in Kubernetes might be tricky, updating the dependency wasn't straight-forward - see kubernetes/kubernetes#126917 (not including this PR yet).

@liggitt
Copy link
Member

liggitt commented Aug 26, 2024

try rebasing, some other fixups went in last week (#507, #508)

I'd recommend waiting until kubernetes/kubernetes#126787 gets in and handles the regen cleanup

func nameIsOkay(member types.Member, jsonName string) bool {
if jsonName == "" {
return member.Type.Kind == types.Struct ||
member.Type.Kind == types.Pointer && member.Type.Underlying.Kind == types.Struct
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ooops. This should be member.Type.Elem.

/cancel lgtm

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noticed just in time when looking at the gengo API changes, but missed it earlier when writing the code... sorry!

@pohly pohly force-pushed the naming-convention branch from 3d12da0 to 5b13d40 Compare August 26, 2024 16:25
@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 26, 2024
@liggitt
Copy link
Member

liggitt commented Aug 26, 2024

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 26, 2024
Because "" and "metadata" were excluded from checking, some incorrect
usage of those were not detected.

Also, naming ListMeta or ObjectMeta "listMeta" or "objectMeta" was allowed
because the names match, even though by convention the name should have
been "metadata".
@Jefftree
Copy link
Member

Jefftree commented Sep 3, 2024

/lgtm
/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Jefftree, liggitt, pohly

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 Sep 3, 2024
@k8s-ci-robot k8s-ci-robot merged commit 9e1beec into kubernetes:master Sep 3, 2024
7 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. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants