-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
🐛 Fix custom defaulter: avoid deleting unknown fields #2931
🐛 Fix custom defaulter: avoid deleting unknown fields #2931
Conversation
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: alculquicondor 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 |
This will allow to fix kubernetes-sigs/kueue#2878 once we upgrade |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Greate improvements!
Just a nit.
|
||
var _ = Describe("CustomDefaulter Handler", func() { | ||
|
||
It("should should not lose unknown fields", func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It("should should not lose unknown fields", func() { | |
It("should not lose unknown fields", func() { |
:)
// We need to decode and marshall the original because the type registered in the | ||
// decoder might not match the latest version of the API. | ||
// Creating a diff from the raw object might cause new fields to be dropped. | ||
marshalledOriginal, err := json.Marshal(original) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can lead to invalid patches. Now we are calculating patches based on how original looks like after unmarshal + marshal. But the apiserver will have to apply the patches on the original JSON object
(We had problems like this when implementing our own patch calculation like it is suggested here on this PR)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example: Imagine an API type that through (probably incorrect) omitempty / pointer/non-pointer fields will add additional fields to marshalledOriginal. This could be e.g.:
- a scalar field with an empty value or
- an object field with
{}
.
Now the resulting patches will:
- if the scalar field is defaulted: generate a replace instead of an add for the field
- if a field should be added through defaulting to this object field: it will just add the field and miss a patch to add the parent object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point, but both the existing and the proposed approaches are buggy.
Generally, the apiserver would have to go through the same unmarshal + marshal process, then the "raw" contents should not differ. A problem like the one you mention could arise when the webhook uses newer APIs than the API server has registered.
The problem I present arises when the API server has newer APIs than the webhook.
Not sure which can be more common.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally, the apiserver would have to go through the same unmarshal + marshal process, then the "raw" contents should not differ
For CRDs the apiserver doesn't even have the Go API types :)
Yeah it's definitely a tricky problem. I just think that if we now switch from one buggy version to another we will break a lot of people that currently have (somewhat) working implementations with controller-runtime
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please look at #2932?
PR needs rebase. 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. |
/close In favor of an approach closer to #2932 |
@alculquicondor: Closed this PR. In response to this:
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. |
When creating a patch for the custom defaulter, pass the original object through decoding.
Otherwise, the patch will include a remove instruction for fields that the go type doesn't contain.
This could happen when building a webhook for a resource that belongs to another project (including k8s types).
Added a test for it. This is the patch if we don't use the coder: