Skip to content

fix: Produce valid CRDs containing flattened untagged enums#1942

Merged
clux merged 4 commits into
kube-rs:mainfrom
stackabletech:fix/untagged-flattened-enums
Feb 24, 2026
Merged

fix: Produce valid CRDs containing flattened untagged enums#1942
clux merged 4 commits into
kube-rs:mainfrom
stackabletech:fix/untagged-flattened-enums

Conversation

@NickLarsenNZ
Copy link
Copy Markdown
Contributor

@NickLarsenNZ NickLarsenNZ commented Feb 20, 2026

Fixes #1941

Note

This is a minimal fix to make review easier and close the issue.
A follow up PR is intended to replace the properties transformation into a proper transformer like in #1839.

  • 1a40d62: Add a test for flattened untagged enums.
  • 2caf34b: Ensure description and type fields are dropped on untagged variants without fields.
  • 596bb93: Stop untagged variant descriptions being pushed into properties (which are for the fields)

@NickLarsenNZ NickLarsenNZ force-pushed the fix/untagged-flattened-enums branch 2 times, most recently from 8f9df35 to 18bf1ea Compare February 20, 2026 13:59
Note: This comes from kube-rs#1839, with some modifications (an extra field to the B variant, and change comments to indicate untagged variant descriptions should not leak into fields).

Co-authored-by: Sebastian Bernauer <sebastian.bernauer@stackable.tech>

Signed-off-by: Nick Larsen <nick.larsen@stackable.tech>
…iants without fields

Signed-off-by: Nick Larsen <nick.larsen@stackable.tech>
… for oneOf

Note: variant descriptions are meaningless for untagged enums - they don't correspond to the fields inside struct variants.

Signed-off-by: Nick Larsen <nick.larsen@stackable.tech>
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.3%. Comparing base (58cf5a6) to head (1d0eb38).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##            main   #1942     +/-   ##
=======================================
+ Coverage   76.2%   76.3%   +0.1%     
=======================================
  Files         89      89             
  Lines       8487    8495      +8     
=======================================
+ Hits        6465    6474      +9     
+ Misses      2022    2021      -1     
Files with missing lines Coverage Δ
kube-core/src/schema.rs 99.2% <100.0%> (+0.1%) ⬆️
kube-derive/tests/crd_complex_enum_test.rs 100.0% <100.0%> (ø)

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@NickLarsenNZ NickLarsenNZ marked this pull request as ready for review February 20, 2026 14:21
@NickLarsenNZ NickLarsenNZ moved this to Development: Track in Stackable Engineering Feb 20, 2026
Comment thread kube-derive/tests/crd_complex_enum_test.rs
Copy link
Copy Markdown
Member

@doxxx93 doxxx93 left a comment

Choose a reason for hiding this comment

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

Verified with a kind cluster:

  • The original bug reproduces on main (anyOf[2].description: Forbidden, anyOf[2].type: Forbidden)
  • With this fix, CRD registration and CR instance creation all pass (tested struct variants, empty variants, newtype variants, Option<>, Vec<>, nested untagged enums)
  • No regression on tagged enums (oneOf)

One minor nit left inline about test coverage for a newtype variant hitting the same else if branch.

LGTM otherwise.

@doxxx93
Copy link
Copy Markdown
Member

doxxx93 commented Feb 23, 2026

Sorry for the ping @clux — I've verified the normal behavior through the tests. One thing I noticed: the new else if branch (removing type/metadata from variants without fields) runs for both one_of (tagged) and any_of (untagged) paths, even though the comment says "untagged variants." Is this fine?

Could you take a look when you get a chance?

@NickLarsenNZ
Copy link
Copy Markdown
Contributor Author

NickLarsenNZ commented Feb 23, 2026

One thing I noticed: the new else if branch (removing type/metadata from variants without fields) runs for both one_of (tagged) and any_of (untagged) paths, even though the comment says "untagged variants." Is this fine?

No this isn't fine. I will fix that (by only doing it when push_description_to_property == true - maybe rename the variable).
This PR is only dealing with untagged enums and should not change anything else.

I didn't see any test failing. Can you share how you tested that?
I tested on one of our CRDs and didn't see a regression, so I'd like to ensure that path is covered.

@doxxx93
Copy link
Copy Markdown
Member

doxxx93 commented Feb 23, 2026

@NickLarsenNZ I didn't find a specific failing test case — it was more of a code review observation that the else if branch could theoretically run in the one_of (tagged) path as well. The existing tests with tagged enums pass fine, but I wasn't confident there isn't an uncovered edge case.

@NickLarsenNZ
Copy link
Copy Markdown
Contributor Author

NickLarsenNZ commented Feb 23, 2026

@doxxx93 I see what you mean.

These extra fields need to go regardless of oneOf or anyOf, as they are not accepted by Kubernetes.

My original implementation does this (and only preserves the descriptions in the case of a oneOf by moving them into the applicable property).
For the untagged variants, the doc-comment on the variant shouldn't be pushed into the properties because the comment is for the variant and not the field(s) within.

See here: https://github.com/stackabletech/kube-rs/blob/71707abf1109bad01bbf2c46e3b161846049767a/kube-core/src/schema/transform_properties.rs#L89-L95

I would keep it as-is for now, and raise a separate refactor PR based on the properties hoisting in #1839 which is easier to test/debug IMO - if you're ok with that.

Copy link
Copy Markdown
Member

@clux clux left a comment

Choose a reason for hiding this comment

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

logic itself looks sensible to me. thanks a lot!

an extra comment on the if here would be nice though.

Comment thread kube-core/src/schema.rs
subschemas: &mut Vec<Schema>,
common_obj: &mut Option<Box<ObjectValidation>>,
instance_type: &mut Option<SingleOrVec<InstanceType>>,
push_description_to_property: bool,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this signature is getting a little awkard and is probably another refactoring candidate for refactoring later.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Comment thread kube-core/src/schema.rs Outdated
@clux clux added the changelog-fix changelog fix category for prs label Feb 23, 2026
@clux clux added this to the 3.1.0 milestone Feb 23, 2026
Signed-off-by: Nick Larsen <nick.larsen@stackable.tech>
@clux
Copy link
Copy Markdown
Member

clux commented Feb 24, 2026

Thank you!

@clux clux merged commit 1320643 into kube-rs:main Feb 24, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog-fix changelog fix category for prs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flattened untagged enums lead to invalid CRDs

3 participants