Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: Allow custom rest parent resource to register subresource #52

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions pkg/builder/builder_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,23 @@ func (a *Server) WithResource(obj resource.Object) *Server {
return a
}

var parentStorageProvider rest.ResourceHandlerProvider

defer func() {
// automatically create status subresource if the object implements the status interface
a.withSubResourceIfExists(obj, parentStorageProvider)
}()

// If the type implements it's own storage, then use that
switch s := obj.(type) {
case resourcerest.Creator:
return a.forGroupVersionResource(gvr, rest.StaticHandlerProvider{Storage: s.(regsitryrest.Storage)}.Get)
case resourcerest.Updater:
return a.forGroupVersionResource(gvr, rest.StaticHandlerProvider{Storage: s.(regsitryrest.Storage)}.Get)
case resourcerest.Getter:
return a.forGroupVersionResource(gvr, rest.StaticHandlerProvider{Storage: s.(regsitryrest.Storage)}.Get)
case resourcerest.Lister:
return a.forGroupVersionResource(gvr, rest.StaticHandlerProvider{Storage: s.(regsitryrest.Storage)}.Get)
case resourcerest.Creator, resourcerest.Updater, resourcerest.Getter, resourcerest.Lister:
parentStorageProvider = rest.StaticHandlerProvider{Storage: s.(regsitryrest.Storage)}.Get
default:
parentStorageProvider = rest.New(obj)
}

parentStorageProvider := rest.New(obj)
_ = a.forGroupVersionResource(gvr, parentStorageProvider)

// automatically create status subresource if the object implements the status interface
a.withSubResourceIfExists(obj, parentStorageProvider)
return a
}

Expand Down
48 changes: 37 additions & 11 deletions pkg/builder/storage_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ func (s *subResourceStorageProvider) Get(scheme *runtime.Scheme, optsGetter gene
if err != nil {
return nil, err
}
stdParentStorage, ok := parentStorage.(registryrest.StandardStorage)
if !ok {
return nil, fmt.Errorf("parent storageProvider for %v/%v/%v must implement rest.StandardStorage",
s.subResourceGVR.Group, s.subResourceGVR.Version, s.subResourceGVR.Resource)
}

var subResourceStorage registryrest.Storage
if s.subResourceStorageProvider != nil {
Expand All @@ -65,17 +60,39 @@ func (s *subResourceStorageProvider) Get(scheme *runtime.Scheme, optsGetter gene

// status subresource
if strings.HasSuffix(s.subResourceGVR.Resource, "/status") {
stdParentStorage, ok := parentStorage.(registryrest.StandardStorage)
if !ok {
return nil, fmt.Errorf("parent storageProvider for %v/%v/%v must implement rest.StandardStorage",
s.subResourceGVR.Group, s.subResourceGVR.Version, s.subResourceGVR.Resource)
}
return createStatusSubResourceStorage(stdParentStorage)
}
// scale subresource
if strings.HasSuffix(s.subResourceGVR.Resource, "/scale") {
getter, ok := parentStorage.(registryrest.Getter)
if !ok {
return nil, fmt.Errorf("parent storageProvider for %v/%v/%v must implement rest.Getter",
s.subResourceGVR.Group, s.subResourceGVR.Version, s.subResourceGVR.Resource)
}
updater, ok := parentStorage.(registryrest.Updater)
if !ok {
return nil, fmt.Errorf("parent storageProvider for %v/%v/%v must implement rest.Updater",
s.subResourceGVR.Group, s.subResourceGVR.Version, s.subResourceGVR.Resource)
}
return &scaleSubResourceStorage{
parentStorage: stdParentStorage,
parentStorage: parentStorage,
parentStorageGetter: getter,
parentStorageUpdater: updater,
}, nil
}
// getter & updater
getterUpdaterSubResource, isGetterUpdater := subResourceStorage.(resource.GetterUpdaterSubResource)
if isGetterUpdater {
stdParentStorage, ok := parentStorage.(registryrest.StandardStorage)
if !ok {
return nil, fmt.Errorf("parent storageProvider for %v/%v/%v must implement rest.StandardStorage",
s.subResourceGVR.Group, s.subResourceGVR.Version, s.subResourceGVR.Resource)
}
return &commonSubResourceStorage{
parentStorage: stdParentStorage,
subResourceConstructor: subResourceStorage,
Expand All @@ -86,8 +103,14 @@ func (s *subResourceStorageProvider) Get(scheme *runtime.Scheme, optsGetter gene
// connector
connectorSubResource, isConnector := subResourceStorage.(resource.ConnectorSubResource)
if isConnector {
getter, ok := parentStorage.(registryrest.Getter)
if !ok {
return nil, fmt.Errorf("parent storageProvider for %v/%v/%v must implement rest.Getter",
s.subResourceGVR.Group, s.subResourceGVR.Version, s.subResourceGVR.Resource)
}
return &connectorSubResourceStorage{
parentStorage: stdParentStorage,
parentStorage: parentStorage,
parentStorageGetter: getter,
subResourceConstructor: subResourceStorage,
subResourceConnector: connectorSubResource,
}, nil
Expand Down Expand Up @@ -195,7 +218,8 @@ func (c *commonSubResourceStorage) Update(ctx context.Context,

// connector subresource storage
type connectorSubResourceStorage struct {
parentStorage registryrest.StandardStorage
parentStorage registryrest.Storage
parentStorageGetter registryrest.Getter
subResourceConstructor registryrest.Storage
subResourceConnector registryrest.Connecter
}
Expand Down Expand Up @@ -225,7 +249,9 @@ func (c *connectorSubResourceStorage) ConnectMethods() []string {

// scale subresource storage
type scaleSubResourceStorage struct {
parentStorage registryrest.StandardStorage
parentStorage registryrest.Storage
parentStorageGetter registryrest.Getter
parentStorageUpdater registryrest.Updater
}

func (s *scaleSubResourceStorage) GroupVersionKind(containingGV schema.GroupVersion) schema.GroupVersionKind {
Expand All @@ -241,7 +267,7 @@ func (s *scaleSubResourceStorage) New() runtime.Object {
}

func (s *scaleSubResourceStorage) Get(ctx context.Context, name string, options *v1.GetOptions) (runtime.Object, error) {
parentObj, err := s.parentStorage.Get(
parentObj, err := s.parentStorageGetter.Get(
contextutil.WithParentStorage(ctx, s.parentStorage),
name,
options)
Expand All @@ -262,7 +288,7 @@ func (s *scaleSubResourceStorage) Update(ctx context.Context,
updateValidation registryrest.ValidateObjectUpdateFunc,
forceAllowCreate bool,
options *v1.UpdateOptions) (runtime.Object, bool, error) {
updatedObj, updated, err := s.parentStorage.Update(
updatedObj, updated, err := s.parentStorageUpdater.Update(
contextutil.WithParentStorage(ctx, s.parentStorage),
name,
&scaleUpdatedObjectInfo{reqObjInfo: objInfo},
Expand Down
2 changes: 1 addition & 1 deletion pkg/util/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type parentStorageContextKeyType string
var parentStorageContextKey parentStorageContextKeyType

// WithParentStorage creates a new child context w/ parent storage plumbed
func WithParentStorage(ctx context.Context, storage rest.StandardStorage) context.Context {
func WithParentStorage(ctx context.Context, storage rest.Storage) context.Context {
return context.WithValue(ctx, parentStorageContextKey, storage)
}

Expand Down