-
Notifications
You must be signed in to change notification settings - Fork 39.8k
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
Reset managedFields corrupted by admission controllers #98074
Reset managedFields corrupted by admission controllers #98074
Conversation
For a reason I still don't understand the webhook tests fail for me locally with |
6cde0f1
to
eb4d0af
Compare
/triage accepted |
/retest |
I don't really understand what I could have done to cause this specific error. |
Conformance test fail specifically on admission webhooks, that might be related ;-) |
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/admission.go
Outdated
Show resolved
Hide resolved
A few questions based on our discussion:
|
4f17899
to
9eb9385
Compare
/retest |
1094f21
to
9f45cd3
Compare
Rather than making this into a "admission wrapper", would it make sense to apply this right after admission instead in the |
0ee0fc6
to
470ad03
Compare
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go
Show resolved
Hide resolved
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 still need to look at the changes to the internal decoding functions.
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/admission.go
Outdated
Show resolved
Hide resolved
staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go
Outdated
Show resolved
Hide resolved
staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go
Show resolved
Hide resolved
{ | ||
FieldsType: "FieldsV1", | ||
}, | ||
}, |
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.
Maybe make a test that shows that corrupting the "FieldsV1" isn't good
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.
Actually this test is no longer testing what it did before.
All tests fail for the same reason, something is missing from the managedFields entry.
The manager name is not even covered by the reset anymore but still gets reset.
The test just makes sure a reset happens if anything is invalid.
The details are tested in the decoding tests. I'll simplify this one.
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.
Changed the test quite a bit and it should actually do what it's supposed to do now.
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/admission_test.go
Outdated
Show resolved
Hide resolved
// DecodeManagedFields converts ManagedFields from the wire format (api format) | ||
// to the format used by sigs.k8s.io/structured-merge-diff | ||
func DecodeManagedFields(encodedManagedFields []metav1.ManagedFieldsEntry) (Managed, error) { | ||
return internal.DecodeManagedFields(encodedManagedFields) |
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 haven't look at internal
yet, but can we get rid of the indirection here? I'd rather avoid having too many "DecodeManagedFields" functions if possible :-)
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 looked at it for a bit, but I didn't want to move too much outside the internal package if not needed.
There are a few internal types and decoding functions right now, but in theory we could move everything I think.
We would be splitting up decoding and encoding though, or move encoding as well. But I'm not sure if I want to also expose encoding.
Have a look and tell me what you think, I can do it either way.
@@ -219,7 +224,7 @@ func (f *FieldManager) Apply(liveObj, appliedObj runtime.Object, manager string, | |||
} | |||
|
|||
// Decode the managed fields in the live object, since it isn't allowed in the patch. | |||
managed, err := internal.DecodeObjectManagedFields(accessor.GetManagedFields()) | |||
managed, err := DecodeManagedFields(accessor.GetManagedFields()) |
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.
Yes, but somewhat unrelated, shouldn't we do something useful if the managedfields is invalid here?
Should we replace emptyManagedFieldsOnErr
method with a decodeManagedFieldsOrEmpty
, which could be used here?
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.
Shouldn't we keep returning the error here if decoding fails (it is apply)?
What would we want to happen if live is corrupted?
It could only happen if somebody updates it and then applies would fail in the future. I'd say we then should prevent invalid managedFields from getting persisted, what this PR tries to at least make harder.
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.
Right, if the managed fields are corrupted in the apiserver, then someone can't apply anymore. The right thing to do is to restart fresh I would say.
|
||
func emptyManagedFieldsOnErr(managed Managed, err error) (Managed, error) { |
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.
This always returns nil error, does it need to return that?
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.
Yeah, I made it this way for ease of use so it can just wrap the function call for providing the same return values.
So no additional error check or anything is required.
// to the format used by sigs.k8s.io/structured-merge-diff | ||
func decodeManagedFields(encodedManagedFields []metav1.ManagedFieldsEntry) (managed managedStruct, err error) { | ||
func DecodeManagedFields(encodedManagedFields []metav1.ManagedFieldsEntry) (ManagedInterface, error) { |
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.
That's good, thanks!
Beside the new validation that I think you have to revert, mostly nits, thanks! |
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.
/lgtm
Thanks Kevin!
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: kwiesmueller, lavalamp The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
What type of PR is this?
/kind bug
What this PR does / why we need it:
When a mutating admission controller changes managedFields in a way that causes them to be invalid, this change will reset them to their state before the admission chain modified them.
Which issue(s) this PR fixes:
Fixes #96688
Special notes for your reviewer:
Does this PR introduce a user-facing change?:
/sig api-machinery
/wg api-expression
/cc @apelisse