From aa13d4501dc4de53e42683aea65c2d45eb114cb0 Mon Sep 17 00:00:00 2001 From: yue9944882 <291271447@qq.com> Date: Tue, 8 Feb 2022 18:09:32 +0800 Subject: [PATCH 1/3] fixes the stackoverflow issue due to parent storage instance Signed-off-by: yue9944882 <291271447@qq.com> --- pkg/builder/builder_resource.go | 5 ++++- pkg/builder/rest/provider.go | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) 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..b61a2b2 100644 --- a/pkg/builder/rest/provider.go +++ b/pkg/builder/rest/provider.go @@ -44,12 +44,20 @@ 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 + } + if getter, isGetter := parentStorage.(rest.Getter); isGetter { + return parentPlumbedStorageProvider{ + delegate: getter, + parentStorage: parentStorage, + }, nil } return p.Storage, nil } @@ -57,7 +65,8 @@ func (p ParentStaticHandlerProvider) Get(s *runtime.Scheme, g generic.RESTOption var _ rest.Getter = &parentPlumbedStorageProvider{} type parentPlumbedStorageProvider struct { - delegate rest.Getter + delegate rest.Getter + parentStorage rest.Storage } func (p parentPlumbedStorageProvider) New() runtime.Object { @@ -65,5 +74,5 @@ func (p parentPlumbedStorageProvider) New() runtime.Object { } 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) + return p.delegate.Get(contextutil.WithParentStorage(ctx, p.parentStorage), name, options) } From c85db350134a1b171295a370f2e799d6a9a692c6 Mon Sep 17 00:00:00 2001 From: yue9944882 <291271447@qq.com> Date: Wed, 9 Feb 2022 15:07:36 +0800 Subject: [PATCH 2/3] support subresource getter/updater Signed-off-by: yue9944882 <291271447@qq.com> --- pkg/builder/rest/provider.go | 57 ++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/pkg/builder/rest/provider.go b/pkg/builder/rest/provider.go index b61a2b2..e1ce418 100644 --- a/pkg/builder/rest/provider.go +++ b/pkg/builder/rest/provider.go @@ -19,6 +19,7 @@ package rest import ( "context" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/generic" @@ -53,8 +54,17 @@ func (p ParentStaticHandlerProvider) Get(s *runtime.Scheme, g generic.RESTOption if err != nil { return nil, err } - if getter, isGetter := parentStorage.(rest.Getter); isGetter { - return parentPlumbedStorageProvider{ + getter, isGetter := parentStorage.(rest.Getter) + updater, isUpdater := parentStorage.(rest.Updater) + switch { + case isGetter && isUpdater: + return parentPlumbedStorageGetterUpdaterProvider{ + getter: getter, + updater: updater, + parentStorage: parentStorage, + }, nil + case isGetter: + return parentPlumbedStorageGetterProvider{ delegate: getter, parentStorage: parentStorage, }, nil @@ -62,17 +72,52 @@ func (p ParentStaticHandlerProvider) Get(s *runtime.Scheme, g generic.RESTOption return p.Storage, nil } -var _ rest.Getter = &parentPlumbedStorageProvider{} +var _ rest.Getter = &parentPlumbedStorageGetterProvider{} -type parentPlumbedStorageProvider struct { +type parentPlumbedStorageGetterProvider struct { delegate rest.Getter parentStorage rest.Storage } -func (p parentPlumbedStorageProvider) New() runtime.Object { +func (p parentPlumbedStorageGetterProvider) New() runtime.Object { return p.delegate.(rest.Storage).New() } -func (p parentPlumbedStorageProvider) Get(ctx context.Context, name string, options *v1.GetOptions) (runtime.Object, error) { +func (p parentPlumbedStorageGetterProvider) Get(ctx context.Context, name string, options *v1.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 +} + +func (p parentPlumbedStorageGetterUpdaterProvider) New() runtime.Object { + return p.parentStorage.(rest.Storage).New() +} + +func (p parentPlumbedStorageGetterUpdaterProvider) Get(ctx context.Context, name string, options *v1.GetOptions) (runtime.Object, error) { + return p.getter.Get(contextutil.WithParentStorage(ctx, p.parentStorage), 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) +} From a40af9466396223443d3f1dde10473e186cd6468 Mon Sep 17 00:00:00 2001 From: yue9944882 <291271447@qq.com> Date: Wed, 9 Feb 2022 15:11:49 +0800 Subject: [PATCH 3/3] fixes storage type assertion Signed-off-by: yue9944882 <291271447@qq.com> --- pkg/builder/rest/provider.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pkg/builder/rest/provider.go b/pkg/builder/rest/provider.go index e1ce418..7b3e81e 100644 --- a/pkg/builder/rest/provider.go +++ b/pkg/builder/rest/provider.go @@ -20,7 +20,6 @@ import ( "context" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" @@ -54,8 +53,8 @@ func (p ParentStaticHandlerProvider) Get(s *runtime.Scheme, g generic.RESTOption if err != nil { return nil, err } - getter, isGetter := parentStorage.(rest.Getter) - updater, isUpdater := parentStorage.(rest.Updater) + getter, isGetter := p.Storage.(rest.Getter) + updater, isUpdater := p.Storage.(rest.Updater) switch { case isGetter && isUpdater: return parentPlumbedStorageGetterUpdaterProvider{ @@ -80,10 +79,10 @@ type parentPlumbedStorageGetterProvider struct { } func (p parentPlumbedStorageGetterProvider) New() runtime.Object { - return p.delegate.(rest.Storage).New() + return p.parentStorage.New() } -func (p parentPlumbedStorageGetterProvider) Get(ctx context.Context, name string, options *v1.GetOptions) (runtime.Object, error) { +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) } @@ -97,10 +96,10 @@ type parentPlumbedStorageGetterUpdaterProvider struct { } func (p parentPlumbedStorageGetterUpdaterProvider) New() runtime.Object { - return p.parentStorage.(rest.Storage).New() + return p.parentStorage.New() } -func (p parentPlumbedStorageGetterUpdaterProvider) Get(ctx context.Context, name string, options *v1.GetOptions) (runtime.Object, error) { +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) }