Skip to content

Commit

Permalink
Merge pull request #64 from yue9944882/fix/parent-storage-stackoverflow
Browse files Browse the repository at this point in the history
Fix: Parent storage stackoverflow
  • Loading branch information
k8s-ci-robot committed Feb 10, 2022
2 parents 9fe5ff1 + a40af94 commit 6ec7cc3
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 11 deletions.
5 changes: 4 additions & 1 deletion pkg/builder/builder_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
73 changes: 63 additions & 10 deletions pkg/builder/rest/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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)
}

0 comments on commit 6ec7cc3

Please sign in to comment.