diff --git a/pkg/admission/cachedresource/admission.go b/pkg/admission/cachedresource/admission.go index 8d6e9b41aad..8c39ecbe281 100644 --- a/pkg/admission/cachedresource/admission.go +++ b/pkg/admission/cachedresource/admission.go @@ -156,8 +156,15 @@ func (adm *CachedResourceAdmission) validateV1alpha1(ctx context.Context, a admi return err } - // Make sure there is at most one CachedResource per GVR. - if len(existing) > 0 { + // Make sure there is at most one CachedResource per GVR. An entry that + // matches the incoming object's name is not a real conflict — it is a + // re-apply of the same object, which the storage layer will surface + // naturally as AlreadyExists. Rejecting here would mask that error + // behind a misleading Forbidden and break idempotent client flows. + for _, e := range existing { + if e.Name == cachedResource.Name { + continue + } return admission.NewForbidden(a, field.Invalid( field.NewPath("spec"), diff --git a/pkg/admission/cachedresource/admission_test.go b/pkg/admission/cachedresource/admission_test.go index eeb8cf3baac..9d5685d9af1 100644 --- a/pkg/admission/cachedresource/admission_test.go +++ b/pkg/admission/cachedresource/admission_test.go @@ -156,6 +156,30 @@ func TestAdmission(t *testing.T) { ), cluster: logicalcluster.Name("cluster-2"), }, + "SameNameReapply": { + attr: createAttr(createCachedResource("wohoo", schema.GroupVersionResource{ + Group: "example.org", + Version: "v1", + Resource: "objects", + })), + index: map[logicalcluster.Name]map[schema.GroupVersionResource][]*cachev1alpha1.CachedResource{ + "cluster-1": { + schema.GroupVersionResource{ + Group: "example.org", + Version: "v1", + Resource: "objects", + }: []*cachev1alpha1.CachedResource{ + createCachedResource("wohoo", schema.GroupVersionResource{ + Group: "example.org", + Version: "v1", + Resource: "objects", + }), + }, + }, + }, + wantErr: nil, + cluster: logicalcluster.Name("cluster-1"), + }, "IgnoreIfNotCreate": { attr: updateAttr(createCachedResource("wohoo", schema.GroupVersionResource{ Group: "example.org",