diff --git a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go index e516cb7d819..422353a38d1 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go @@ -633,9 +633,12 @@ func (e *Store) Update(ctx context.Context, name string, objInfo rest.UpdatedObj } out := e.NewFunc() + + // only ignore a not found error if this type allows creating on update, or we're forcing allowing create (like for server-side-apply) + ignoreNotFound := e.UpdateStrategy.AllowCreateOnUpdate() || forceAllowCreate // deleteObj is only used in case a deletion is carried out var deleteObj runtime.Object - err = e.Storage.GuaranteedUpdate(ctx, key, out, true, storagePreconditions, func(existing runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { + err = e.Storage.GuaranteedUpdate(ctx, key, out, ignoreNotFound, storagePreconditions, func(existing runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { existingResourceVersion, err := e.Storage.Versioner().ObjectResourceVersion(existing) if err != nil { return nil, nil, err diff --git a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store_test.go b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store_test.go index 24ac2a6c7a4..cc50afede2a 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store_test.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store_test.go @@ -773,6 +773,10 @@ func TestStoreUpdate(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "7"}, Spec: example.PodSpec{NodeName: "machine"}, } + podAWithResourceAndUID := &example.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "7", UID: "A"}, + Spec: example.PodSpec{NodeName: "machine"}, + } testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") destroyFunc, registry := NewTestGenericStoreRegistry(t) @@ -790,6 +794,12 @@ func TestStoreUpdate(t *testing.T) { t.Errorf("Unexpected error: %v", err) } + // try to update a non-existing node that was created previously + _, _, err = registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podAWithResourceAndUID), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) + if !errors.IsNotFound(err) { + t.Errorf("Unexpected error: %v", err) + } + // allow creation registry.UpdateStrategy.(*testRESTStrategy).allowCreateOnUpdate = true