Refactor REST storage to use generic defaults
Signed-off-by: Monis Khan <mkhan@redhat.com>
This commit is contained in:
parent
dd974b7412
commit
57604816c7
|
@ -128,8 +128,15 @@ func (serverOptions *ServerRunOptions) Run(stopCh <-chan struct{}) error {
|
|||
return fmt.Errorf("Unable to get storage config: %v", err)
|
||||
}
|
||||
|
||||
testTypeOpts := generic.RESTOptions{
|
||||
StorageConfig: storageConfig,
|
||||
Decorator: generic.UndecoratedStorage,
|
||||
ResourcePrefix: "testtypes",
|
||||
DeleteCollectionWorkers: 1,
|
||||
}
|
||||
|
||||
restStorageMap := map[string]rest.Storage{
|
||||
"testtypes": testgroupetcd.NewREST(storageConfig, generic.UndecoratedStorage),
|
||||
"testtypes": testgroupetcd.NewREST(testTypeOpts),
|
||||
}
|
||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *groupMeta,
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/storage"
|
||||
"k8s.io/kubernetes/pkg/storage/storagebackend"
|
||||
"k8s.io/kubernetes/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
type REST struct {
|
||||
|
@ -35,60 +35,53 @@ type REST struct {
|
|||
}
|
||||
|
||||
// NewREST returns a RESTStorage object that will work with testtype.
|
||||
func NewREST(config *storagebackend.Config, storageDecorator generic.StorageDecorator) *REST {
|
||||
prefix := "/testtype"
|
||||
newListFunc := func() runtime.Object { return &testgroup.TestTypeList{} }
|
||||
// Usually you should reuse your RESTCreateStrategy.
|
||||
strategy := &NotNamespaceScoped{}
|
||||
getAttrs := func(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
testObj, ok := obj.(*testgroup.TestType)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a TestType")
|
||||
}
|
||||
return labels.Set(testObj.Labels), nil, nil
|
||||
}
|
||||
storageInterface, _ := storageDecorator(
|
||||
config, 100, &testgroup.TestType{}, prefix, strategy, newListFunc, getAttrs, storage.NoTriggerPublisher)
|
||||
func NewREST(optsGetter generic.RESTOptionsGetter) *REST {
|
||||
store := &genericregistry.Store{
|
||||
NewFunc: func() runtime.Object { return &testgroup.TestType{} },
|
||||
// NewListFunc returns an object capable of storing results of an etcd list.
|
||||
NewListFunc: newListFunc,
|
||||
// Produces a path that etcd understands, to the root of the resource
|
||||
// by combining the namespace in the context with the given prefix.
|
||||
KeyRootFunc: func(ctx api.Context) string {
|
||||
return genericregistry.NamespaceKeyRootFunc(ctx, prefix)
|
||||
},
|
||||
// Produces a path that etcd understands, to the resource by combining
|
||||
// the namespace in the context with the given prefix.
|
||||
KeyFunc: func(ctx api.Context, name string) (string, error) {
|
||||
return genericregistry.NamespaceKeyFunc(ctx, prefix, name)
|
||||
},
|
||||
NewListFunc: func() runtime.Object { return &testgroup.TestTypeList{} },
|
||||
// Retrieve the name field of the resource.
|
||||
ObjectNameFunc: func(obj runtime.Object) (string, error) {
|
||||
return obj.(*testgroup.TestType).Name, nil
|
||||
},
|
||||
// Used to match objects based on labels/fields for list.
|
||||
PredicateFunc: func(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
|
||||
return storage.SelectionPredicate{
|
||||
Label: label,
|
||||
Field: field,
|
||||
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
testType, ok := obj.(*testgroup.TestType)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("unexpected type of given object")
|
||||
}
|
||||
return labels.Set(testType.ObjectMeta.Labels), fields.Set{}, nil
|
||||
},
|
||||
}
|
||||
},
|
||||
Storage: storageInterface,
|
||||
PredicateFunc: matcher,
|
||||
// QualifiedResource should always be plural
|
||||
QualifiedResource: api.Resource("testtypes"),
|
||||
|
||||
CreateStrategy: strategy,
|
||||
}
|
||||
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: getAttrs}
|
||||
if err := store.CompleteWithOptions(options); err != nil {
|
||||
panic(err) // TODO: Propagate error up
|
||||
}
|
||||
return &REST{store}
|
||||
}
|
||||
|
||||
type NotNamespaceScoped struct {
|
||||
type fakeStrategy struct {
|
||||
runtime.ObjectTyper
|
||||
api.NameGenerator
|
||||
}
|
||||
|
||||
func (*NotNamespaceScoped) NamespaceScoped() bool {
|
||||
return false
|
||||
func (*fakeStrategy) NamespaceScoped() bool { return false }
|
||||
func (*fakeStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {}
|
||||
func (*fakeStrategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList { return nil }
|
||||
func (*fakeStrategy) Canonicalize(obj runtime.Object) {}
|
||||
|
||||
var strategy = &fakeStrategy{api.Scheme, api.SimpleNameGenerator}
|
||||
|
||||
func getAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
testType, ok := obj.(*testgroup.TestType)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a TestType")
|
||||
}
|
||||
return labels.Set(testType.ObjectMeta.Labels), fields.Set{}, nil
|
||||
}
|
||||
|
||||
func matcher(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
|
||||
return storage.SelectionPredicate{
|
||||
Label: label,
|
||||
Field: field,
|
||||
GetAttrs: getAttrs,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ func main() {
|
|||
serverRunOptions := apiserver.NewServerRunOptions()
|
||||
|
||||
// Parse command line flags.
|
||||
serverRunOptions.AddUniversalFlags(pflag.CommandLine)
|
||||
serverRunOptions.GenericServerRunOptions.AddUniversalFlags(pflag.CommandLine)
|
||||
serverRunOptions.Etcd.AddFlags(pflag.CommandLine)
|
||||
serverRunOptions.SecureServing.AddFlags(pflag.CommandLine)
|
||||
serverRunOptions.SecureServing.AddDeprecatedFlags(pflag.CommandLine)
|
||||
|
|
Loading…
Reference in New Issue