🐛 Dedupe equal Default values in flattenAllOfInto#1401
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: ravisastryk The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Welcome @ravisastryk! |
|
Hi @ravisastryk. 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 Regular contributors should join the org to skip this step. Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions 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. |
|
@sbueringer @alvaroaleman Please review when you get a chance |
|
/ok-to-test |
There was a problem hiding this comment.
I have minor suggestions. This PR sort out:
Example
Before PR
protocol:
allOf:
- default: "TCP"
- default: "TCP" # duplicate!
type: string
Very similar to the issue fixed in the PR as well: #1398
Also, see that we have lint issues to sort out, that is why I reduced the complexity by creating its own func in: #1398
It might be easier if we get merged: #1398, then you do that on top.
Beyond the nits, it seems great !!!.
Could you please address those, then I am happy to LGTM.
Adds an explicit `case "Default":` so two *apiextensionsv1.JSON pointers with equal raw bytes are deduped instead of hoisted into a fresh allOf, and adds regression tests for the equal-bytes and differing-bytes cases. Follow-up to kubernetes-sigs#1027 / kubernetes-sigs#1035. Signed-off-by: Ravi Sastry Kadali <ravisastryk@gmail.com>
- flatten.go: rewrite the case "Default" comment to focus on what/why/when
(pointer-vs-bytes comparison, where the equal-bytes case comes from, and
why hoisting produces a structural-schema-violating CRD) without naming
a specific issue number.
- flatten_all_of_test.go: simplify Context and It descriptions per
reviewer suggestion ("should not allow duplications when ...").
Signed-off-by: Ravi Sastry Kadali <ravisastryk@gmail.com>
Signed-off-by: Ravi Sastry Kadali <ravisastryk@gmail.com>
205769e to
9533efd
Compare
Adds an explicit
case "Default":so two *apiextensionsv1.JSON pointers with equal raw bytes are deduped instead of hoisted into a fresh allOf, and adds regression tests for the equal-bytes and differing-bytes cases.Follow-up to #1027 / #1035.
What does this do, and why do we need it?
Closes the
// TODO(directxman12): Default -- use field?inpkg/crd/flatten.goby givingDefaultan explicit merge case inflattenAllOfInto.Today the
Defaultfield ofJSONSchemaPropsis*apiextensionsv1.JSON. That type isComparableinreflect's sense, but==on it compares pointer addresses, not pointee bytes. The equality check atflatten.go:107:returns
falsefor two distinct allocations that both wrap"TCP". With no explicit case, the field falls into thedefault:branch which hoists both values into a freshallOf, producing structural-schema-violating output:The API server rejects this with:
How this relates to #1035
#1035 fixed the only known producer of this shape by removing the hard-coded
corev1.Protocolschema frompkg/crd/known_types.gooncek8s.io/apistarted shipping the+default="TCP"marker upstream. That fix is preserved here — including the regression test onCronJobSpec.Protocolinpkg/crd/testdata/cronjob_types.go, which now also serves as a higher-level integration check for this PR.This PR closes the merge-logic half of the problem so the same YAML can't recur from a future
KnownPackagesoverride, a+default=-carrying alias type, or any other code path that puts a default on a referenced type schema.Behavior change
flattenAllOfIntonow handlesDefaultexplicitly:allOf.dst(parent / field-level value), dropsrc. This matches howXPreserveUnknownFieldsandXMapTypeare already merged: the field-level value wins over the type-level value, since users add+default=on a field precisely to override anything the type provides. No error is recorded — silently honoring the override is the less surprising behavior. If reviewers prefer an error here, swapping the finalcontinueforerrRec.AddError(...)is a one-line change.No public API changes. No marker changes. No testdata bumps. Behavior change is limited to schemas that previously produced
default: ...insideallOf, which were already broken at apply-time, so this can only fix CRDs, not break them.Test plan
Two new specs in
pkg/crd/flatten_all_of_test.go:*JSONdefaults with equal raw bytes (the Error applying a CRD generated by controller-tools that contains the ContainerPort struct #1027 shape) — expects noallOfand a single preserved default.*JSONdefaults with different raw bytes — expects the dst (field-level) value to win and noallOf.The existing
It("should leave properties not in an AllOf branch ... alone")spec still passes, confirming we haven't regressed the "no merge needed" path.The
Protocol corev1.Protocolfield added to the cronjob testdata in #1035 continues to flatten to a singledefault: TCP(verified againstpkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml).What issue does this fix
Fixes #65
Follow-up to / completes #1027 (originally fixed by #1035).