diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go index 9bf2467cc84..37579820a4a 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go @@ -291,12 +291,17 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag var versionedDeleteOptions runtime.Object var versionedDeleterObject interface{} + deleteReturnsDeletedObject := false if isGracefulDeleter { versionedDeleteOptions, err = a.group.Creater.New(optionsExternalVersion.WithKind("DeleteOptions")) if err != nil { return nil, err } versionedDeleterObject = indirectArbitraryPointer(versionedDeleteOptions) + + if mayReturnFullObjectDeleter, ok := storage.(rest.MayReturnFullObjectDeleter); ok { + deleteReturnsDeletedObject = mayReturnFullObjectDeleter.DeleteReturnsDeletedObject() + } } versionedStatusPtr, err := a.group.Creater.New(optionsExternalVersion.WithKind("Status")) @@ -769,15 +774,19 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if isSubresource { doc = "delete " + subresource + " of" + article + kind } + deleteReturnType := versionedStatus + if deleteReturnsDeletedObject { + deleteReturnType = producedObject + } handler := metrics.InstrumentRouteFunc(action.Verb, group, version, resource, subresource, requestScope, metrics.APIServerComponent, restfulDeleteResource(gracefulDeleter, isGracefulDeleter, reqScope, admit)) route := ws.DELETE(action.Path).To(handler). Doc(doc). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Operation("delete"+namespaced+kind+strings.Title(subresource)+operationSuffix). Produces(append(storageMeta.ProducesMIMETypes(action.Verb), mediaTypes...)...). - Writes(versionedStatus). - Returns(http.StatusOK, "OK", versionedStatus). - Returns(http.StatusAccepted, "Accepted", versionedStatus) + Writes(deleteReturnType). + Returns(http.StatusOK, "OK", deleteReturnType). + Returns(http.StatusAccepted, "Accepted", deleteReturnType) if isGracefulDeleter { route.Reads(versionedDeleterObject) route.ParameterNamed("body").Required(false) 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 dc287d1ed5b..8701d4542d1 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 @@ -975,6 +975,11 @@ func (e *Store) Delete(ctx context.Context, name string, deleteValidation rest.V return out, true, err } +// DeleteReturnsDeletedObject implements the rest.MayReturnFullObjectDeleter interface +func (e *Store) DeleteReturnsDeletedObject() bool { + return e.ReturnDeletedObject +} + // DeleteCollection removes all items returned by List with a given ListOptions from storage. // // DeleteCollection is currently NOT atomic. It can happen that only subset of objects diff --git a/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go b/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go index 9ea6f98970e..8f9c981dd85 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go @@ -161,6 +161,11 @@ type GracefulDeleter interface { Delete(ctx context.Context, name string, deleteValidation ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) } +// MayReturnFullObjectDeleter may return deleted object (instead of a simple status) on deletion. +type MayReturnFullObjectDeleter interface { + DeleteReturnsDeletedObject() bool +} + // CollectionDeleter is an object that can delete a collection // of RESTful resources. type CollectionDeleter interface {