diff --git a/pkg/builder/builder_resource.go b/pkg/builder/builder_resource.go index 7026058..18eef8f 100644 --- a/pkg/builder/builder_resource.go +++ b/pkg/builder/builder_resource.go @@ -192,7 +192,10 @@ func (a *Server) withSubResourceIfExists(obj resource.Object, parentStorageProvi for _, sub := range sgs.GetArbitrarySubResources() { sub := sub subResourceGVR := parentGVR.GroupVersion().WithResource(parentGVR.Resource + "/" + sub.SubResourceName()) - a.forGroupVersionSubResource(subResourceGVR, parentStorageProvider, rest.ParentStaticHandlerProvider{Storage: sub}.Get) + a.forGroupVersionSubResource(subResourceGVR, parentStorageProvider, rest.ParentStaticHandlerProvider{ + Storage: sub, + ParentProvider: parentStorageProvider, + }.Get) } } } diff --git a/pkg/builder/rest/provider.go b/pkg/builder/rest/provider.go index ca92c37..7b3e81e 100644 --- a/pkg/builder/rest/provider.go +++ b/pkg/builder/rest/provider.go @@ -19,7 +19,7 @@ package rest import ( "context" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" @@ -44,26 +44,79 @@ func (p StaticHandlerProvider) Get(s *runtime.Scheme, g generic.RESTOptionsGette // storage plumbed in the context. type ParentStaticHandlerProvider struct { rest.Storage + ParentProvider ResourceHandlerProvider } // Get returns itself as the handler func (p ParentStaticHandlerProvider) Get(s *runtime.Scheme, g generic.RESTOptionsGetter) (rest.Storage, error) { - if getter, isGetter := p.Storage.(rest.Getter); isGetter { - return parentPlumbedStorageProvider{delegate: getter}, nil + parentStorage, err := p.ParentProvider(s, g) + if err != nil { + return nil, err + } + getter, isGetter := p.Storage.(rest.Getter) + updater, isUpdater := p.Storage.(rest.Updater) + switch { + case isGetter && isUpdater: + return parentPlumbedStorageGetterUpdaterProvider{ + getter: getter, + updater: updater, + parentStorage: parentStorage, + }, nil + case isGetter: + return parentPlumbedStorageGetterProvider{ + delegate: getter, + parentStorage: parentStorage, + }, nil } return p.Storage, nil } -var _ rest.Getter = &parentPlumbedStorageProvider{} +var _ rest.Getter = &parentPlumbedStorageGetterProvider{} + +type parentPlumbedStorageGetterProvider struct { + delegate rest.Getter + parentStorage rest.Storage +} + +func (p parentPlumbedStorageGetterProvider) New() runtime.Object { + return p.parentStorage.New() +} + +func (p parentPlumbedStorageGetterProvider) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { + return p.delegate.Get(contextutil.WithParentStorage(ctx, p.parentStorage), name, options) +} + +var _ rest.Getter = &parentPlumbedStorageGetterUpdaterProvider{} +var _ rest.Updater = &parentPlumbedStorageGetterUpdaterProvider{} + +type parentPlumbedStorageGetterUpdaterProvider struct { + getter rest.Getter + updater rest.Updater + parentStorage rest.Storage +} -type parentPlumbedStorageProvider struct { - delegate rest.Getter +func (p parentPlumbedStorageGetterUpdaterProvider) New() runtime.Object { + return p.parentStorage.New() } -func (p parentPlumbedStorageProvider) New() runtime.Object { - return p.delegate.(rest.Storage).New() +func (p parentPlumbedStorageGetterUpdaterProvider) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { + return p.getter.Get(contextutil.WithParentStorage(ctx, p.parentStorage), name, options) } -func (p parentPlumbedStorageProvider) Get(ctx context.Context, name string, options *v1.GetOptions) (runtime.Object, error) { - return p.delegate.Get(contextutil.WithParentStorage(ctx, p.delegate.(rest.Storage)), name, options) +func (p parentPlumbedStorageGetterUpdaterProvider) Update( + ctx context.Context, + name string, + objInfo rest.UpdatedObjectInfo, + createValidation rest.ValidateObjectFunc, + updateValidation rest.ValidateObjectUpdateFunc, + forceAllowCreate bool, + options *metav1.UpdateOptions) (runtime.Object, bool, error) { + return p.updater.Update( + contextutil.WithParentStorage(ctx, p.parentStorage), + name, + objInfo, + createValidation, + updateValidation, + forceAllowCreate, + options) }