From 1dfcb84108fd5107c28278c9a1b43be1d171641d Mon Sep 17 00:00:00 2001 From: Olaf Klischat Date: Wed, 1 Apr 2026 00:43:45 +0200 Subject: [PATCH] update webhooks: in case of resourceVersion conflict fall back to API's default handling If the update had a resourceVersion conflict, it makes no sense to perform the webhook's normal checks, e.g. for .spec immutability, as those checks might fail just because the base resourceVersion isn't the same. For example, if the client is trying to update based on an outdated version of the resource, the .spec might be different just because of that, triggering the corresponding webhook check and reponding with a 400, even though 409 would be the correct response that allows the client to perform proper conflict handling. So in case of a resourceVersion conflict the webhook now just returns success, which causes the API server to fall back to its default handling, which will detect the resourceVersion conflict and return the 409 itself. Signed-off-by: Olaf Klischat --- pkg/admission/machinedeployments.go | 4 ++++ pkg/admission/machines.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/pkg/admission/machinedeployments.go b/pkg/admission/machinedeployments.go index ec3d9f5cb..62da6cc00 100644 --- a/pkg/admission/machinedeployments.go +++ b/pkg/admission/machinedeployments.go @@ -55,6 +55,10 @@ func (ad *admissionData) mutateMachineDeployments(ctx context.Context, ar admiss if err := json.Unmarshal(ar.OldObject.Raw, &oldMachineDeployment); err != nil { return nil, fmt.Errorf("failed to unmarshal OldObject: %w", err) } + if oldMachineDeployment.ResourceVersion != machineDeployment.ResourceVersion { + // resource version conflict. Return success to fall back to the API server's default handler, which will respond with a proper 409 + return createAdmissionResponse(log, machineDeploymentOriginal, &machineDeployment) + } if equal := apiequality.Semantic.DeepEqual(oldMachineDeployment.Spec.Template.Spec, machineDeployment.Spec.Template.Spec); equal { machineSpecNeedsValidation = false } diff --git a/pkg/admission/machines.go b/pkg/admission/machines.go index 50f81dd4c..6b9a2076c 100644 --- a/pkg/admission/machines.go +++ b/pkg/admission/machines.go @@ -62,6 +62,10 @@ func (ad *admissionData) mutateMachines(ctx context.Context, ar admissionv1.Admi if err := json.Unmarshal(ar.OldObject.Raw, &oldMachine); err != nil { return nil, fmt.Errorf("failed to unmarshal OldObject: %w", err) } + if oldMachine.ResourceVersion != machine.ResourceVersion { + // resource version conflict. Return success to fall back to the API server's default handler, which will respond with a proper 409 + return createAdmissionResponse(log, machineOriginal, &machine) + } if oldMachine.Spec.Name != machine.Spec.Name && machine.Spec.Name == machine.Name { oldMachine.Spec.Name = machine.Spec.Name }