Skip to content

+enum validation marker #1179

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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

MishimaPorte
Copy link

As per issue #933, it seems to be beneficial to support upstream +enum validation marker that infers enum members for a type from constant declarations of that type.

So, given

// +enum
type MyEnumType string

const (
    MyEnumType_One MyEnumType = "one"
    MyEnumType_Two MyEnumType = "two"
)

every time the MyEnumType is used, an enum block is rendered in the schema as follows:

enum:
- one
- two

This mechanism only handles the string-based types and does not handle numerical types.

A testcase for the generator is added as well.

Copy link

linux-foundation-easycla bot commented Mar 25, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: MishimaPorte
Once this PR has been reviewed and has the lgtm label, please assign alvaroaleman for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found 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 cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. label Mar 25, 2025
@k8s-ci-robot
Copy link
Contributor

Welcome @MishimaPorte!

It looks like this is your first PR to kubernetes-sigs/controller-tools 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes-sigs/controller-tools has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Mar 25, 2025
@k8s-ci-robot k8s-ci-robot requested a review from joelanford March 25, 2025 12:54
@k8s-ci-robot
Copy link
Contributor

Hi @MishimaPorte. 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-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot requested a review from JoelSpeed March 25, 2025 12:54
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. and removed cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. labels Mar 25, 2025
Copy link
Contributor

@JoelSpeed JoelSpeed left a comment

Choose a reason for hiding this comment

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

What happens if an existing API has the +enum marker AND a +kubebuilder:validation:enum marker? Can we add a test?

Copy link
Contributor

Choose a reason for hiding this comment

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

There are clearly a lot of types that have enum already that we've ignored up til now. This will impact existing CRDs for users where they've copied core kube types. Are we to assume that where they've copied the built-in type, this is a safe change? The general use case would be to pass through the core kube type to the underlying pod or whatever it is that is being created

Assuming a recent version of K8s, the change should ratchet invalid values anyway 🤔

Copy link
Author

Choose a reason for hiding this comment

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

I think it is? Probably for core types that have enum tags the values outside of enum-defined set are anyway invalid.

Co-authored-by: Joel Speed <[email protected]>
@MishimaPorte
Copy link
Author

MishimaPorte commented Mar 25, 2025

What happens if an existing API has the +enum marker AND a +kubebuilder:validation:enum marker?

When both +enum and +kubebuilder:validation:enum are defined the +enum takes precedence

@MishimaPorte MishimaPorte requested a review from JoelSpeed March 25, 2025 13:51
@JoelSpeed
Copy link
Contributor

When both +enum and +kubebuilder:validation:enum are defined the +enum takes precedence

Lets add a test case for this one please

@MishimaPorte
Copy link
Author

MishimaPorte commented Mar 25, 2025

Lets add a test case for this one please

Done

@JoelSpeed
Copy link
Contributor

/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 Mar 25, 2025
Comment on lines 473 to 477
// apply this enum only if there were no other enum values specified
// (e.g. via a "+enum" marker)
if len(schema.Enum) != 0 {
return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there any other markers that do this kind of thing? Is there precedence?

Comment on lines 473 to 477
// apply this enum only if there were no other enum values specified
// (e.g. via a "+enum" marker)
if len(schema.Enum) != 0 {
return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there any other markers that do this kind of thing? Is there precedence?

Copy link
Author

Choose a reason for hiding this comment

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

I don't think so. But enum markers are kind of the only ones that do the same thing differently so some decision on precedence here is needed in any case.

Copy link
Contributor

Choose a reason for hiding this comment

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

CC @alvaroaleman @sbueringer do you have an opinion on this?

At present, when you have the kubebuilder:validation:enum on the field and a type alias, I believe you get a struct like

allOf:
- enum: []
- enum: []

I wonder if, to be consistent, this case should also do the same? It would encourage developers to deduplicate their markers which I think is probably a positive

Copy link
Author

Choose a reason for hiding this comment

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

It would encourage developers to deduplicate their markers

I believe this is less of a usecase here since both markers (+enum and +kubebuilder:validation:enum) are at the same place - on the type alias declaration, not in distant places (one on the field and the other on the type). So it is close to impossible to have accidental duplicates, like with the aforementioned example. I personally would prefer this to be an error right away, but it can probably harm backward compatibility.

Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we want to make the preference configurable. The default behaviour though I think needs to be that kubebuilder:validation:enum takes precedence over the naked enum though. That way we won't break existing users. I'm worried that built in types that already have the enum will get broken when this change rolls out

Copy link
Author

Choose a reason for hiding this comment

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

I think configurable precedence would complicate things too much - we can just make the kubebuilder:validation:enum take precedence over +enum and call it a day.

For known core types it can be made configurable, but, honestly, the now-generated enum block should have always been there in the schema. I can think of zero example where such a change would complicate something - on the contrary, probably additional validation would make the generated crds less error-prone.

Copy link
Contributor

Choose a reason for hiding this comment

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

should have always been there in the schema

Yes, but depending on the use case, this is likely a breaking change for the people using the CRDs built by this tooling

we can just make the kubebuilder:validation:enum take precedence over +enum and call it a day.

I would lean towards this for now to be safe

Copy link
Author

@MishimaPorte MishimaPorte Apr 12, 2025

Choose a reason for hiding this comment

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

this is likely a breaking change for the people using the CRDs built by this tooling

so, a configuration flag? but an opt-in or opt-out one is what we need? I personally would argue for the latter since the change seems to be beneficial in most of the cases (at least when something like PodTemplate is used)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. 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.

3 participants