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

Update CRD annotations for 1.x parity #1757

Merged
merged 12 commits into from
Aug 27, 2021
Merged

Update CRD annotations for 1.x parity #1757

merged 12 commits into from
Aug 27, 2021

Conversation

rainest
Copy link
Contributor

@rainest rainest commented Aug 25, 2021

What this PR does / why we need it:
Adds additional kubebuilder annotations to CRD types to (mostly) align them with 1.x. Type validations are mostly omitted because most did not set a validation different from the underlying Go type, and such explicit validations are unnecessary.

Copies the 1.x KongIngress schema into the 2.x CRD verbatim using a Kustomize patch. Generating this properly is difficult.

Which issue this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close that issue when PR gets merged):
fixes #1745
fixes #1748
fixes #1752
fixes #1749 (but needs future follow-up)

Special notes for your reviewer:
This is somewhat at odds with #1762. If we do proceed with that, I move that we merge this as-is and then make a separate change to pull in old CRDs after. Old CRDs only need to go into the final deploy manifests, and all the annotation changes here are something we'd want for an eventual transition to Kubebuilder CRDs, even if we're not doing that now.

IMO we should proceed with generated CRDs. fdf8552 does represent a review of the schema validation differences and adds back those that looked relevant. It includes validations that did not simply assert the underlying Go type, which are unnecessary. Per validation:Type in https://book.kubebuilder.io/reference/markers/crd-validation.html that happens automatically, and type validations should only be used when the desired type differs from the underlying type (e.g. for KongPlugin.Config, we want an object, whereas apiextesions.JSON will allow any valid JSON, so also standalone ints or strings).

My own review of differences between crd.yaml.txt and oldcrd.yaml.txt for #1761 using https://github.com/homeport/dyff is that the remaining differences are because of the inherent v1/v1beta1 differences (e.g. the addition of versions, validation moving into the schema section under versions, etc.). It's easy to get lost though, because those differences are significant. I don't think piecemeal verification of every field is a great idea because it's prone to error, so if we intend to proceed with #1762 I think we'd want to instead compare against a v1 version of the old CRDs, which we'd need for #1762 anyway.

PR Readiness Checklist:

Complete these before marking the PR as ready to review:

  • the CHANGELOG.md release notes have been updated to reflect any significant (and particularly user-facing) changes introduced by this PR

@rainest
Copy link
Contributor Author

rainest commented Aug 25, 2021

Draft pending:

  • Should merge chore: generator dependency updates #1754 first and rebase
  • Regenerate manifests and single manifests after rebase
  • Add in additionalPrinterColumns also. Not strictly necessary, could be its own PR, but may as well touch it while we're here.

Travis Raines added 5 commits August 26, 2021 09:09
Add shortNames to CRDs matching the shortNames available in 1.x.
Add validation to CRD schemas, mostly aligned with the 1.x CRDs. Omits
type validations where 1.x specified the type explicitly even though it
did not differ from the underlying Go type. These validations are
implicit.

Omits KongIngress validations. KongIngress does not specify fields of
its own and inherits everything from go-kong.
Copy the 1.x KongIngress openAPIV3Schema verbatim into the 2.x CRD via
Kustomize patch.

This works around generation pulling in undesired fields from the
underlying go-kong structures we include inside KongIngress, as well as
adding validation to fields even though the go-kong types have no
Kubebuilder tags.
Add additional printer columns included in the 1.x CRDs to the 2.x CRDs.
@rainest rainest marked this pull request as ready for review August 26, 2021 17:19
@rainest rainest requested a review from a team as a code owner August 26, 2021 17:19
@shaneutt
Copy link
Contributor

I'm on board for moving forward with generators for our CRDs, particularly given some updates we've had today on our 2.0 timeline and given that there's already a lot of work done here. Is #1763 useless in the face of this and should we close it? Or do you think there's something of value still in there we should keep?

@rainest
Copy link
Contributor Author

rainest commented Aug 26, 2021

Per https://kubernetes.slack.com/archives/C0EG7JC6T/p1630010315014600 the new test failures like

=== CONT  TestPluginEssentials
    plugin_test.go:120: 
        	Error Trace:	plugin_test.go:120
        	Error:      	Received unexpected error:
        	            	KongPlugin.configuration.konghq.com "teapot" is invalid: [configFrom.secretKeyRef.key: Required value, configFrom.secretKeyRef.name: Required value]
        	Test:       	TestPluginEssentials

are because non-pointer struct fields don't truly omit when empty, but rather create a phantom empty struct of that type.

I'm not sure why this wasn't an issue before, since ConfigFrom was not a pointer in 1.x either, and the fields were still required in the enclosed secretKeyRef, but whatever, I suppose that's what we need to refactor.

Copy link
Contributor

@ccfishk ccfishk left a comment

Choose a reason for hiding this comment

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

hard to evaluate which changes are needed.

Convert KongPlugin and KongClusterPlugin ConfigFrom fields from structs
to pointers to structs.

Currently, a struct field within another struct with the "omitempty"
JSON serialization tag does not truly omit that field when empty.
Instead, it creates an empty struct of that type. Ref:
golang/go#11939

This is at odds with required fields on optional object fields in a CRD
schema. When present, KongPlugin.ConfigFrom is set,
KongPlugin.ConfigFrom.secretKeyRef.name and
KongPlugin.ConfigFrom.secretKeyRef.key must be set. An omitempty struct
creates a KongPlugin.ConfigFrom == SecretValueFromSource{}, failing
validation even though the user intent is to set Config instead. Using
pointers to these structs avoids these behaviors; the fields are truly
omitted.
@rainest rainest temporarily deployed to Configure ci August 27, 2021 00:03 Inactive
@rainest
Copy link
Contributor Author

rainest commented Aug 27, 2021

@shaneutt what did you do locally for the controller-gen version update in #1754? For some reason my trying to make manifests tries to revert back to controller-gen.kubebuilder.io/version: v0.4.1 annotations. I'm not sure why, since I tried to update it on my machine:

$ go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.6.2
$ which controller-gen                                             
/home/traines/go/bin/controller-gen        
$ controller-gen --version
Version: v0.6.2

So I'd expect that should put 0.6.2 in the annotations, but it isn't.

Fake edit: the make target uses the local bin/controller-gen. That doesn't update if it's already downloaded at an older version; we should fix that.

@rainest rainest temporarily deployed to Configure ci August 27, 2021 00:19 Inactive
@shaneutt
Copy link
Contributor

@shaneutt what did you do locally for the controller-gen version update in #1754? For some reason my trying to make manifests tries to revert back to controller-gen.kubebuilder.io/version: v0.4.1 annotations. I'm not sure why, since I tried to update it on my machine:

$ go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.6.2
$ which controller-gen                                             
/home/traines/go/bin/controller-gen        
$ controller-gen --version
Version: v0.6.2

So I'd expect that should put 0.6.2 in the annotations, but it isn't.

Fake edit: the make target uses the local bin/controller-gen. That doesn't update if it's already downloaded at an older version; we should fix that.

Yeah I ran make clean but we should for sure fix that.

@ccfishk ccfishk self-requested a review August 27, 2021 16:07
@rainest
Copy link
Contributor Author

rainest commented Aug 27, 2021

Validations like this pose a problem:

     // Protocols configures plugin to run on requests received on specific
     // protocols.
     //+kubebuilder:validation:Enum=http;https;grpc;grpcs;tcp;tls;udp
     Protocols []string `json:"protocols,omitempty"`

It results in a schema entry like:

          protocols:
            description: Protocols configures plugin to run on requests received on
              specific protocols.
            enum:
            - http
            - https
            - grpc
            - grpcs
            - tcp
            - tls
            - udp
            items:
              type: string
            type: array

but we want

          protocols:
            items:
              enum:
              - http
              - https
              - grpc
              - grpcs
              - tcp
              - tls
              type: string
            type: array

i.e. that validation needs to apply to the items in the array, and the generator is making a rule that instead tries to validate the array (which won't work). This is due to kubernetes-sigs/controller-tools#342, which doesn't appear like it will change any time soon, so we need dedicated types for the array items.

@ccfishk
Copy link
Contributor

ccfishk commented Aug 27, 2021

Validations like this pose a problem:

     // Protocols configures plugin to run on requests received on specific
     // protocols.
     //+kubebuilder:validation:Enum=http;https;grpc;grpcs;tcp;tls;udp
     Protocols []string `json:"protocols,omitempty"`

It results in a schema entry like:

          protocols:
            description: Protocols configures plugin to run on requests received on
              specific protocols.
            enum:
            - http
            - https
            - grpc
            - grpcs
            - tcp
            - tls
            - udp
            items:
              type: string
            type: array

but we want

          protocols:
            items:
              enum:
              - http
              - https
              - grpc
              - grpcs
              - tcp
              - tls
              type: string
            type: array

i.e. that validation needs to apply to the items in the array, and the generator is making a rule that instead tries to validate the array (which won't work). This is due to kubernetes-sigs/controller-tools#342, which doesn't appear like it will change any time soon, so we need dedicated types for the array items.

Here is the openAPI standard (the first one)
https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema

@rainest rainest temporarily deployed to Configure ci August 27, 2021 17:59 Inactive
Copy link
Contributor

@ccfishk ccfishk left a comment

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

@shaneutt shaneutt 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 putting such hard and painstaking work into this.

I'm in favor of merging this, then once it's in I'll rebase #1763 and make do a roundup of the diffs to ensure everything looks 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants