Refactor REST storage to use generic defaults

Signed-off-by: Monis Khan <mkhan@redhat.com>
pull/6/head
Monis Khan 2016-11-30 21:09:56 -05:00
parent 809d259d68
commit a6bafbacbf
No known key found for this signature in database
GPG Key ID: 52C90ADA01B269B8
145 changed files with 920 additions and 1679 deletions

View File

@ -26,7 +26,7 @@ go_library(
"//cmd/kubernetes-discovery/pkg/client/informers:go_default_library", "//cmd/kubernetes-discovery/pkg/client/informers:go_default_library",
"//cmd/kubernetes-discovery/pkg/client/informers/apiregistration/internalversion:go_default_library", "//cmd/kubernetes-discovery/pkg/client/informers/apiregistration/internalversion:go_default_library",
"//cmd/kubernetes-discovery/pkg/client/listers/apiregistration/internalversion:go_default_library", "//cmd/kubernetes-discovery/pkg/client/listers/apiregistration/internalversion:go_default_library",
"//cmd/kubernetes-discovery/pkg/registry/apiservice:go_default_library", "//cmd/kubernetes-discovery/pkg/registry/apiservice/etcd:go_default_library",
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/api/errors:go_default_library", "//pkg/api/errors:go_default_library",
"//pkg/api/rest:go_default_library", "//pkg/api/rest:go_default_library",
@ -41,7 +41,6 @@ go_library(
"//pkg/labels:go_default_library", "//pkg/labels:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/runtime/schema:go_default_library",
"//pkg/util/runtime:go_default_library", "//pkg/util/runtime:go_default_library",
"//pkg/util/sets:go_default_library", "//pkg/util/sets:go_default_library",
"//pkg/util/wait:go_default_library", "//pkg/util/wait:go_default_library",

View File

@ -28,7 +28,6 @@ import (
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
genericfilters "k8s.io/kubernetes/pkg/genericapiserver/filters" genericfilters "k8s.io/kubernetes/pkg/genericapiserver/filters"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/util/wait"
"k8s.io/kubernetes/pkg/version" "k8s.io/kubernetes/pkg/version"
@ -39,23 +38,17 @@ import (
clientset "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/clientset_generated/release_1_5" clientset "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/clientset_generated/release_1_5"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/informers" "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/informers"
listers "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/listers/apiregistration/internalversion" listers "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/listers/apiregistration/internalversion"
apiservicestorage "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/registry/apiservice" apiservicestorage "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/registry/apiservice/etcd"
) )
// legacyAPIServiceName is the fixed name of the only non-groupified API version // legacyAPIServiceName is the fixed name of the only non-groupified API version
const legacyAPIServiceName = "v1." const legacyAPIServiceName = "v1."
// TODO move to genericapiserver or something like that
// RESTOptionsGetter is used to construct storage for a particular resource
type RESTOptionsGetter interface {
NewFor(resource schema.GroupResource) generic.RESTOptions
}
type Config struct { type Config struct {
GenericConfig *genericapiserver.Config GenericConfig *genericapiserver.Config
// RESTOptionsGetter is used to construct storage for a particular resource // RESTOptionsGetter is used to construct storage for a particular resource
RESTOptionsGetter RESTOptionsGetter RESTOptionsGetter generic.RESTOptionsGetter
} }
// APIDiscoveryServer contains state for a Kubernetes cluster master/api server. // APIDiscoveryServer contains state for a Kubernetes cluster master/api server.
@ -117,7 +110,7 @@ func (c completedConfig) New() (*APIDiscoveryServer, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiregistration.GroupName) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiregistration.GroupName)
apiGroupInfo.GroupMeta.GroupVersion = v1alpha1.SchemeGroupVersion apiGroupInfo.GroupMeta.GroupVersion = v1alpha1.SchemeGroupVersion
v1alpha1storage := map[string]rest.Storage{} v1alpha1storage := map[string]rest.Storage{}
v1alpha1storage["apiservices"] = apiservicestorage.NewREST(c.RESTOptionsGetter.NewFor(apiregistration.Resource("apiservices"))) v1alpha1storage["apiservices"] = apiservicestorage.NewREST(c.RESTOptionsGetter)
apiGroupInfo.VersionedResourcesStorageMap["v1alpha1"] = v1alpha1storage apiGroupInfo.VersionedResourcesStorageMap["v1alpha1"] = v1alpha1storage
if err := s.GenericAPIServer.InstallAPIGroup(&apiGroupInfo); err != nil { if err := s.GenericAPIServer.InstallAPIGroup(&apiGroupInfo); err != nil {

View File

@ -122,7 +122,7 @@ func (o DiscoveryServerOptions) RunDiscoveryServer() error {
config := apiserver.Config{ config := apiserver.Config{
GenericConfig: genericAPIServerConfig, GenericConfig: genericAPIServerConfig,
RESTOptionsGetter: restOptionsFactory{storageConfig: &o.Etcd.StorageConfig}, RESTOptionsGetter: &restOptionsFactory{storageConfig: &o.Etcd.StorageConfig},
} }
server, err := config.Complete().New() server, err := config.Complete().New()
@ -149,12 +149,12 @@ type restOptionsFactory struct {
storageConfig *storagebackend.Config storageConfig *storagebackend.Config
} }
func (f restOptionsFactory) NewFor(resource schema.GroupResource) generic.RESTOptions { func (f *restOptionsFactory) GetRESTOptions(resource schema.GroupResource) (generic.RESTOptions, error) {
return generic.RESTOptions{ return generic.RESTOptions{
StorageConfig: f.storageConfig, StorageConfig: f.storageConfig,
Decorator: registry.StorageWithCacher, Decorator: registry.StorageWithCacher,
DeleteCollectionWorkers: 1, DeleteCollectionWorkers: 1,
EnableGarbageCollection: false, EnableGarbageCollection: false,
ResourcePrefix: f.storageConfig.Prefix + "/" + resource.Group + "/" + resource.Resource, ResourcePrefix: f.storageConfig.Prefix + "/" + resource.Group + "/" + resource.Resource,
} }, nil
} }

View File

@ -12,10 +12,7 @@ load(
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = ["strategy.go"],
"etcd.go",
"strategy.go",
],
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//cmd/kubernetes-discovery/pkg/apis/apiregistration:go_default_library", "//cmd/kubernetes-discovery/pkg/apis/apiregistration:go_default_library",
@ -24,7 +21,6 @@ go_library(
"//pkg/fields:go_default_library", "//pkg/fields:go_default_library",
"//pkg/labels:go_default_library", "//pkg/labels:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library", "//pkg/storage:go_default_library",
"//pkg/util/validation/field:go_default_library", "//pkg/util/validation/field:go_default_library",

View File

@ -1,99 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package apiservice
import (
"fmt"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration"
)
// rest implements a RESTStorage for network policies against etcd
type REST struct {
*registry.Store
}
// NewREST returns a RESTStorage object that will work against network policies.
func NewREST(opts generic.RESTOptions) *REST {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &apiregistration.APIServiceList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
1000, // cache size
&apiregistration.APIService{},
prefix,
strategy,
newListFunc,
getAttrs,
storage.NoTriggerPublisher,
)
store := &registry.Store{
NewFunc: func() runtime.Object { return &apiregistration.APIService{} },
// NewListFunc returns an object capable of storing results of an etcd list.
NewListFunc: newListFunc,
// Produces a APIService 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 prefix
},
// Produces a APIService 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 registry.NoNamespaceKeyFunc(ctx, prefix, name)
},
// Retrieve the name field of an apiserver
ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*apiregistration.APIService).Name, nil
},
// Used to match objects based on labels/fields for list and watch
PredicateFunc: MatchAPIService,
QualifiedResource: apiregistration.Resource("apiservers"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
// Used to validate controller creation
CreateStrategy: strategy,
// Used to validate controller updates
UpdateStrategy: strategy,
DeleteStrategy: strategy,
Storage: storageInterface,
DestroyFunc: dFunc,
}
return &REST{store}
}
// getAttrs returns labels and fields of a given object for filtering purposes.
func getAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
castObj, ok := obj.(*apiregistration.APIService)
if !ok {
return nil, nil, fmt.Errorf("given object is not an APIService.")
}
return labels.Set(castObj.ObjectMeta.Labels), APIServiceToSelectableFields(castObj), nil
}

View File

@ -0,0 +1,24 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = ["etcd.go"],
tags = ["automanaged"],
deps = [
"//cmd/kubernetes-discovery/pkg/apis/apiregistration:go_default_library",
"//cmd/kubernetes-discovery/pkg/registry/apiservice:go_default_library",
"//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library",
],
)

View File

@ -0,0 +1,52 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package etcd
import (
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/registry/apiservice"
"k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime"
)
// rest implements a RESTStorage for API services against etcd
type REST struct {
*genericregistry.Store
}
// NewREST returns a RESTStorage object that will work against API services.
func NewREST(optsGetter generic.RESTOptionsGetter) *REST {
store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &apiregistration.APIService{} },
NewListFunc: func() runtime.Object { return &apiregistration.APIServiceList{} },
ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*apiregistration.APIService).Name, nil
},
PredicateFunc: apiservice.MatchAPIService,
QualifiedResource: apiregistration.Resource("apiservices"),
CreateStrategy: apiservice.Strategy,
UpdateStrategy: apiservice.Strategy,
DeleteStrategy: apiservice.Strategy,
}
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: apiservice.GetAttrs}
if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
}
return &REST{store}
}

View File

@ -36,7 +36,7 @@ type apiServerStrategy struct {
kapi.NameGenerator kapi.NameGenerator
} }
var strategy = apiServerStrategy{kapi.Scheme, kapi.SimpleNameGenerator} var Strategy = apiServerStrategy{kapi.Scheme, kapi.SimpleNameGenerator}
func (apiServerStrategy) NamespaceScoped() bool { func (apiServerStrategy) NamespaceScoped() bool {
return false return false
@ -71,19 +71,21 @@ func (apiServerStrategy) ValidateUpdate(ctx kapi.Context, obj, old runtime.Objec
return validation.ValidateAPIServiceUpdate(obj.(*apiregistration.APIService), old.(*apiregistration.APIService)) return validation.ValidateAPIServiceUpdate(obj.(*apiregistration.APIService), old.(*apiregistration.APIService))
} }
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
apiserver, ok := obj.(*apiregistration.APIService)
if !ok {
return nil, nil, fmt.Errorf("given object is not a APIService.")
}
return labels.Set(apiserver.ObjectMeta.Labels), APIServiceToSelectableFields(apiserver), nil
}
// MatchAPIService is the filter used by the generic etcd backend to watch events // MatchAPIService is the filter used by the generic etcd backend to watch events
// from etcd to clients of the apiserver only interested in specific labels/fields. // from etcd to clients of the apiserver only interested in specific labels/fields.
func MatchAPIService(label labels.Selector, field fields.Selector) storage.SelectionPredicate { func MatchAPIService(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
return storage.SelectionPredicate{ return storage.SelectionPredicate{
Label: label, Label: label,
Field: field, Field: field,
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { GetAttrs: GetAttrs,
apiserver, ok := obj.(*apiregistration.APIService)
if !ok {
return nil, nil, fmt.Errorf("given object is not a APIService.")
}
return labels.Set(apiserver.ObjectMeta.Labels), APIServiceToSelectableFields(apiserver), nil
},
} }
} }

View File

@ -128,8 +128,15 @@ func (serverOptions *ServerRunOptions) Run(stopCh <-chan struct{}) error {
return fmt.Errorf("Unable to get storage config: %v", err) 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{ restStorageMap := map[string]rest.Storage{
"testtypes": testgroupetcd.NewREST(storageConfig, generic.UndecoratedStorage), "testtypes": testgroupetcd.NewREST(testTypeOpts),
} }
apiGroupInfo := genericapiserver.APIGroupInfo{ apiGroupInfo := genericapiserver.APIGroupInfo{
GroupMeta: *groupMeta, GroupMeta: *groupMeta,

View File

@ -27,7 +27,7 @@ import (
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
"k8s.io/kubernetes/pkg/storage/storagebackend" "k8s.io/kubernetes/pkg/util/validation/field"
) )
type REST struct { type REST struct {
@ -35,60 +35,53 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work with testtype. // NewREST returns a RESTStorage object that will work with testtype.
func NewREST(config *storagebackend.Config, storageDecorator generic.StorageDecorator) *REST { func NewREST(optsGetter generic.RESTOptionsGetter) *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)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &testgroup.TestType{} }, NewFunc: func() runtime.Object { return &testgroup.TestType{} },
// NewListFunc returns an object capable of storing results of an etcd list. // NewListFunc returns an object capable of storing results of an etcd list.
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &testgroup.TestTypeList{} },
// 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)
},
// Retrieve the name field of the resource. // Retrieve the name field of the resource.
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*testgroup.TestType).Name, nil return obj.(*testgroup.TestType).Name, nil
}, },
// Used to match objects based on labels/fields for list. // Used to match objects based on labels/fields for list.
PredicateFunc: func(label labels.Selector, field fields.Selector) storage.SelectionPredicate { PredicateFunc: matcher,
return storage.SelectionPredicate{ // QualifiedResource should always be plural
Label: label, QualifiedResource: api.Resource("testtypes"),
Field: field,
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { CreateStrategy: strategy,
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 options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: getAttrs}
}, if err := store.CompleteWithOptions(options); err != nil {
} panic(err) // TODO: Propagate error up
},
Storage: storageInterface,
} }
return &REST{store} return &REST{store}
} }
type NotNamespaceScoped struct { type fakeStrategy struct {
runtime.ObjectTyper
api.NameGenerator
} }
func (*NotNamespaceScoped) NamespaceScoped() bool { func (*fakeStrategy) NamespaceScoped() bool { return false }
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,
}
} }

View File

@ -29,7 +29,7 @@ func main() {
serverRunOptions := apiserver.NewServerRunOptions() serverRunOptions := apiserver.NewServerRunOptions()
// Parse command line flags. // Parse command line flags.
serverRunOptions.AddUniversalFlags(pflag.CommandLine) serverRunOptions.GenericServerRunOptions.AddUniversalFlags(pflag.CommandLine)
serverRunOptions.Etcd.AddFlags(pflag.CommandLine) serverRunOptions.Etcd.AddFlags(pflag.CommandLine)
serverRunOptions.SecureServing.AddFlags(pflag.CommandLine) serverRunOptions.SecureServing.AddFlags(pflag.CommandLine)
serverRunOptions.SecureServing.AddDeprecatedFlags(pflag.CommandLine) serverRunOptions.SecureServing.AddDeprecatedFlags(pflag.CommandLine)

View File

@ -30,7 +30,6 @@ import (
_ "k8s.io/kubernetes/federation/apis/core/install" _ "k8s.io/kubernetes/federation/apis/core/install"
"k8s.io/kubernetes/federation/apis/core/v1" "k8s.io/kubernetes/federation/apis/core/v1"
"k8s.io/kubernetes/federation/cmd/federation-apiserver/app/options" "k8s.io/kubernetes/federation/cmd/federation-apiserver/app/options"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
@ -39,14 +38,15 @@ import (
namespaceetcd "k8s.io/kubernetes/pkg/registry/core/namespace/etcd" namespaceetcd "k8s.io/kubernetes/pkg/registry/core/namespace/etcd"
secretetcd "k8s.io/kubernetes/pkg/registry/core/secret/etcd" secretetcd "k8s.io/kubernetes/pkg/registry/core/secret/etcd"
serviceetcd "k8s.io/kubernetes/pkg/registry/core/service/etcd" serviceetcd "k8s.io/kubernetes/pkg/registry/core/service/etcd"
"k8s.io/kubernetes/pkg/registry/generic"
) )
func installCoreAPIs(s *options.ServerRunOptions, g *genericapiserver.GenericAPIServer, restOptionsFactory restOptionsFactory) { func installCoreAPIs(s *options.ServerRunOptions, g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter) {
serviceStore, serviceStatusStore := serviceetcd.NewREST(restOptionsFactory.NewFor(api.Resource("service"))) serviceStore, serviceStatusStore := serviceetcd.NewREST(optsGetter)
namespaceStore, namespaceStatusStore, namespaceFinalizeStore := namespaceetcd.NewREST(restOptionsFactory.NewFor(api.Resource("namespaces"))) namespaceStore, namespaceStatusStore, namespaceFinalizeStore := namespaceetcd.NewREST(optsGetter)
secretStore := secretetcd.NewREST(restOptionsFactory.NewFor(api.Resource("secrets"))) secretStore := secretetcd.NewREST(optsGetter)
configMapStore := configmapetcd.NewREST(restOptionsFactory.NewFor(api.Resource("configmaps"))) configMapStore := configmapetcd.NewREST(optsGetter)
eventStore := eventetcd.NewREST(restOptionsFactory.NewFor(api.Resource("events")), uint64(s.EventTTL.Seconds())) eventStore := eventetcd.NewREST(optsGetter, uint64(s.EventTTL.Seconds()))
coreResources := map[string]rest.Storage{ coreResources := map[string]rest.Storage{
"secrets": secretStore, "secrets": secretStore,
"services": serviceStore, "services": serviceStore,

View File

@ -28,13 +28,14 @@ import (
deploymentetcd "k8s.io/kubernetes/pkg/registry/extensions/deployment/etcd" deploymentetcd "k8s.io/kubernetes/pkg/registry/extensions/deployment/etcd"
ingressetcd "k8s.io/kubernetes/pkg/registry/extensions/ingress/etcd" ingressetcd "k8s.io/kubernetes/pkg/registry/extensions/ingress/etcd"
replicasetetcd "k8s.io/kubernetes/pkg/registry/extensions/replicaset/etcd" replicasetetcd "k8s.io/kubernetes/pkg/registry/extensions/replicaset/etcd"
"k8s.io/kubernetes/pkg/registry/generic"
) )
func installExtensionsAPIs(g *genericapiserver.GenericAPIServer, restOptionsFactory restOptionsFactory) { func installExtensionsAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter) {
replicaSetStorage := replicasetetcd.NewStorage(restOptionsFactory.NewFor(extensions.Resource("replicasets"))) replicaSetStorage := replicasetetcd.NewStorage(optsGetter)
deploymentStorage := deploymentetcd.NewStorage(restOptionsFactory.NewFor(extensions.Resource("deployments"))) deploymentStorage := deploymentetcd.NewStorage(optsGetter)
ingressStorage, ingressStatusStorage := ingressetcd.NewREST(restOptionsFactory.NewFor(extensions.Resource("ingresses"))) ingressStorage, ingressStatusStorage := ingressetcd.NewREST(optsGetter)
daemonSetStorage, daemonSetStatusStorage := daemonsetetcd.NewREST(restOptionsFactory.NewFor(extensions.Resource("daemonsets"))) daemonSetStorage, daemonSetStatusStorage := daemonsetetcd.NewREST(optsGetter)
extensionsResources := map[string]rest.Storage{ extensionsResources := map[string]rest.Storage{
"replicasets": replicaSetStorage.ReplicaSet, "replicasets": replicaSetStorage.ReplicaSet,

View File

@ -24,13 +24,14 @@ import (
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/registry/generic"
_ "k8s.io/kubernetes/federation/apis/federation/install" _ "k8s.io/kubernetes/federation/apis/federation/install"
clusteretcd "k8s.io/kubernetes/federation/registry/cluster/etcd" clusteretcd "k8s.io/kubernetes/federation/registry/cluster/etcd"
) )
func installFederationAPIs(g *genericapiserver.GenericAPIServer, restOptionsFactory restOptionsFactory) { func installFederationAPIs(g *genericapiserver.GenericAPIServer, optsGetter generic.RESTOptionsGetter) {
clusterStorage, clusterStatusStorage := clusteretcd.NewREST(restOptionsFactory.NewFor(federation.Resource("clusters"))) clusterStorage, clusterStatusStorage := clusteretcd.NewREST(optsGetter)
federationResources := map[string]rest.Storage{ federationResources := map[string]rest.Storage{
"clusters": clusterStorage, "clusters": clusterStorage,
"clusters/status": clusterStatusStorage, "clusters/status": clusterStatusStorage,

View File

@ -188,7 +188,7 @@ func Run(s *options.ServerRunOptions) error {
routes.Logs{}.Install(m.HandlerContainer) routes.Logs{}.Install(m.HandlerContainer)
// TODO: Refactor this code to share it with kube-apiserver rather than duplicating it here. // TODO: Refactor this code to share it with kube-apiserver rather than duplicating it here.
restOptionsFactory := restOptionsFactory{ restOptionsFactory := &restOptionsFactory{
storageFactory: storageFactory, storageFactory: storageFactory,
enableGarbageCollection: s.GenericServerRunOptions.EnableGarbageCollection, enableGarbageCollection: s.GenericServerRunOptions.EnableGarbageCollection,
deleteCollectionWorkers: s.GenericServerRunOptions.DeleteCollectionWorkers, deleteCollectionWorkers: s.GenericServerRunOptions.DeleteCollectionWorkers,
@ -215,10 +215,10 @@ type restOptionsFactory struct {
enableGarbageCollection bool enableGarbageCollection bool
} }
func (f restOptionsFactory) NewFor(resource schema.GroupResource) generic.RESTOptions { func (f *restOptionsFactory) GetRESTOptions(resource schema.GroupResource) (generic.RESTOptions, error) {
config, err := f.storageFactory.NewConfig(resource) config, err := f.storageFactory.NewConfig(resource)
if err != nil { if err != nil {
glog.Fatalf("Unable to find storage config for %v, due to %v", resource, err.Error()) return generic.RESTOptions{}, fmt.Errorf("Unable to find storage config for %v, due to %v", resource, err.Error())
} }
return generic.RESTOptions{ return generic.RESTOptions{
StorageConfig: config, StorageConfig: config,
@ -226,5 +226,5 @@ func (f restOptionsFactory) NewFor(resource schema.GroupResource) generic.RESTOp
DeleteCollectionWorkers: f.deleteCollectionWorkers, DeleteCollectionWorkers: f.deleteCollectionWorkers,
EnableGarbageCollection: f.enableGarbageCollection, EnableGarbageCollection: f.enableGarbageCollection,
ResourcePrefix: f.storageFactory.ResourcePrefix(resource), ResourcePrefix: f.storageFactory.ResourcePrefix(resource),
} }, nil
} }

View File

@ -22,7 +22,6 @@ go_library(
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -24,7 +24,6 @@ import (
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
type REST struct { type REST struct {
@ -45,45 +44,24 @@ func (r *StatusREST) Update(ctx api.Context, name string, objInfo rest.UpdatedOb
} }
// NewREST returns a RESTStorage object that will work against clusters. // NewREST returns a RESTStorage object that will work against clusters.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &federation.ClusterList{} }
storageInterface, _ := opts.Decorator(
opts.StorageConfig,
100,
&federation.Cluster{},
prefix,
cluster.Strategy,
newListFunc,
cluster.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &federation.Cluster{} }, NewFunc: func() runtime.Object { return &federation.Cluster{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &federation.ClusterList{} },
KeyRootFunc: func(ctx api.Context) string {
return prefix
},
KeyFunc: func(ctx api.Context, name string) (string, error) {
return genericregistry.NoNamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*federation.Cluster).Name, nil return obj.(*federation.Cluster).Name, nil
}, },
PredicateFunc: cluster.MatchCluster, PredicateFunc: cluster.MatchCluster,
QualifiedResource: federation.Resource("clusters"), QualifiedResource: federation.Resource("clusters"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: cluster.Strategy, CreateStrategy: cluster.Strategy,
UpdateStrategy: cluster.Strategy, UpdateStrategy: cluster.Strategy,
DeleteStrategy: cluster.Strategy, DeleteStrategy: cluster.Strategy,
ReturnDeletedObject: true, ReturnDeletedObject: true,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: cluster.GetAttrs}
if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
statusStore := *store statusStore := *store

View File

@ -34,7 +34,9 @@ func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
restOptions := generic.RESTOptions{ restOptions := generic.RESTOptions{
StorageConfig: storageConfig, StorageConfig: storageConfig,
Decorator: generic.UndecoratedStorage, Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1} DeleteCollectionWorkers: 1,
ResourcePrefix: "clusters",
}
storage, _ := NewREST(restOptions) storage, _ := NewREST(restOptions)
return storage, server return storage, server
} }

View File

@ -262,6 +262,7 @@ pkg/util/metrics
pkg/util/netsh pkg/util/netsh
pkg/util/ratelimit pkg/util/ratelimit
pkg/util/replicaset pkg/util/replicaset
pkg/util/restoptions
pkg/util/validation/field pkg/util/validation/field
pkg/util/workqueue pkg/util/workqueue
pkg/version/prometheus pkg/version/prometheus

View File

@ -86,8 +86,10 @@ func (r *registryGetter) GetSecret(namespace, name string) (*v1.Secret, error) {
// NewGetterFromStorageInterface returns a ServiceAccountTokenGetter that // NewGetterFromStorageInterface returns a ServiceAccountTokenGetter that
// uses the specified storage to retrieve service accounts and secrets. // uses the specified storage to retrieve service accounts and secrets.
func NewGetterFromStorageInterface(config *storagebackend.Config, saPrefix, secretPrefix string) serviceaccount.ServiceAccountTokenGetter { func NewGetterFromStorageInterface(config *storagebackend.Config, saPrefix, secretPrefix string) serviceaccount.ServiceAccountTokenGetter {
saOpts := generic.RESTOptions{StorageConfig: config, Decorator: generic.UndecoratedStorage, ResourcePrefix: saPrefix}
secretOpts := generic.RESTOptions{StorageConfig: config, Decorator: generic.UndecoratedStorage, ResourcePrefix: secretPrefix}
return NewGetterFromRegistries( return NewGetterFromRegistries(
serviceaccountregistry.NewRegistry(serviceaccountetcd.NewREST(generic.RESTOptions{StorageConfig: config, Decorator: generic.UndecoratedStorage, ResourcePrefix: saPrefix})), serviceaccountregistry.NewRegistry(serviceaccountetcd.NewREST(saOpts)),
secret.NewRegistry(secretetcd.NewREST(generic.RESTOptions{StorageConfig: config, Decorator: generic.UndecoratedStorage, ResourcePrefix: secretPrefix})), secret.NewRegistry(secretetcd.NewREST(secretOpts)),
) )
} }

View File

@ -110,6 +110,7 @@ var specialDefaultResourcePrefixes = map[schema.GroupResource]string{
schema.GroupResource{Group: "", Resource: "nodes"}: "minions", schema.GroupResource{Group: "", Resource: "nodes"}: "minions",
schema.GroupResource{Group: "", Resource: "services"}: "services/specs", schema.GroupResource{Group: "", Resource: "services"}: "services/specs",
schema.GroupResource{Group: "extensions", Resource: "ingresses"}: "ingress", schema.GroupResource{Group: "extensions", Resource: "ingresses"}: "ingress",
schema.GroupResource{Group: "extensions", Resource: "podsecuritypolicies"}: "podsecuritypolicy",
} }
func NewDefaultStorageFactory(config storagebackend.Config, defaultMediaType string, defaultSerializer runtime.StorageSerializer, resourceEncodingConfig ResourceEncodingConfig, resourceConfig APIResourceConfigSource) *DefaultStorageFactory { func NewDefaultStorageFactory(config storagebackend.Config, defaultMediaType string, defaultSerializer runtime.StorageSerializer, resourceEncodingConfig ResourceEncodingConfig, resourceConfig APIResourceConfigSource) *DefaultStorageFactory {

View File

@ -56,7 +56,6 @@ go_library(
"//pkg/healthz:go_default_library", "//pkg/healthz:go_default_library",
"//pkg/kubelet/client:go_default_library", "//pkg/kubelet/client:go_default_library",
"//pkg/master/thirdparty:go_default_library", "//pkg/master/thirdparty:go_default_library",
"//pkg/registry:go_default_library",
"//pkg/registry/apps/rest:go_default_library", "//pkg/registry/apps/rest:go_default_library",
"//pkg/registry/authentication/rest:go_default_library", "//pkg/registry/authentication/rest:go_default_library",
"//pkg/registry/authorization/rest:go_default_library", "//pkg/registry/authorization/rest:go_default_library",

View File

@ -43,7 +43,6 @@ import (
"k8s.io/kubernetes/pkg/healthz" "k8s.io/kubernetes/pkg/healthz"
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client" kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
"k8s.io/kubernetes/pkg/master/thirdparty" "k8s.io/kubernetes/pkg/master/thirdparty"
"k8s.io/kubernetes/pkg/registry"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/routes" "k8s.io/kubernetes/pkg/routes"
@ -219,7 +218,7 @@ func (c completedConfig) New() (*Master, error) {
GenericAPIServer: s, GenericAPIServer: s,
} }
restOptionsFactory := restOptionsFactory{ restOptionsFactory := &restOptionsFactory{
deleteCollectionWorkers: c.DeleteCollectionWorkers, deleteCollectionWorkers: c.DeleteCollectionWorkers,
enableGarbageCollection: c.GenericConfig.EnableGarbageCollection, enableGarbageCollection: c.GenericConfig.EnableGarbageCollection,
storageFactory: c.StorageFactory, storageFactory: c.StorageFactory,
@ -242,7 +241,7 @@ func (c completedConfig) New() (*Master, error) {
ServiceNodePortRange: c.ServiceNodePortRange, ServiceNodePortRange: c.ServiceNodePortRange,
LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig, LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig,
} }
m.InstallLegacyAPI(c.Config, restOptionsFactory.NewFor, legacyRESTStorageProvider) m.InstallLegacyAPI(c.Config, restOptionsFactory, legacyRESTStorageProvider)
} }
restStorageProviders := []RESTStorageProvider{ restStorageProviders := []RESTStorageProvider{
@ -257,7 +256,7 @@ func (c completedConfig) New() (*Master, error) {
rbacrest.RESTStorageProvider{}, rbacrest.RESTStorageProvider{},
storagerest.RESTStorageProvider{}, storagerest.RESTStorageProvider{},
} }
m.InstallAPIs(c.Config.APIResourceConfigSource, restOptionsFactory.NewFor, restStorageProviders...) m.InstallAPIs(c.Config.APIResourceConfigSource, restOptionsFactory, restStorageProviders...)
if c.Tunneler != nil { if c.Tunneler != nil {
m.installTunneler(c.Tunneler, corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig).Nodes()) m.installTunneler(c.Tunneler, corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig).Nodes())
@ -266,7 +265,7 @@ func (c completedConfig) New() (*Master, error) {
return m, nil return m, nil
} }
func (m *Master) InstallLegacyAPI(c *Config, restOptionsGetter registry.RESTOptionsGetter, legacyRESTStorageProvider corerest.LegacyRESTStorageProvider) { func (m *Master) InstallLegacyAPI(c *Config, restOptionsGetter generic.RESTOptionsGetter, legacyRESTStorageProvider corerest.LegacyRESTStorageProvider) {
legacyRESTStorage, apiGroupInfo, err := legacyRESTStorageProvider.NewLegacyRESTStorage(restOptionsGetter) legacyRESTStorage, apiGroupInfo, err := legacyRESTStorageProvider.NewLegacyRESTStorage(restOptionsGetter)
if err != nil { if err != nil {
glog.Fatalf("Error building core storage: %v", err) glog.Fatalf("Error building core storage: %v", err)
@ -297,11 +296,11 @@ func (m *Master) installTunneler(tunneler genericapiserver.Tunneler, nodeClient
// RESTStorageProvider is a factory type for REST storage. // RESTStorageProvider is a factory type for REST storage.
type RESTStorageProvider interface { type RESTStorageProvider interface {
GroupName() string GroupName() string
NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool)
} }
// InstallAPIs will install the APIs for the restStorageProviders if they are enabled. // InstallAPIs will install the APIs for the restStorageProviders if they are enabled.
func (m *Master) InstallAPIs(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter, restStorageProviders ...RESTStorageProvider) { func (m *Master) InstallAPIs(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter, restStorageProviders ...RESTStorageProvider) {
apiGroupsInfo := []genericapiserver.APIGroupInfo{} apiGroupsInfo := []genericapiserver.APIGroupInfo{}
for _, restStorageBuilder := range restStorageProviders { for _, restStorageBuilder := range restStorageProviders {
@ -344,10 +343,10 @@ type restOptionsFactory struct {
storageDecorator generic.StorageDecorator storageDecorator generic.StorageDecorator
} }
func (f restOptionsFactory) NewFor(resource schema.GroupResource) generic.RESTOptions { func (f *restOptionsFactory) GetRESTOptions(resource schema.GroupResource) (generic.RESTOptions, error) {
storageConfig, err := f.storageFactory.NewConfig(resource) storageConfig, err := f.storageFactory.NewConfig(resource)
if err != nil { if err != nil {
glog.Fatalf("Unable to find storage destination for %v, due to %v", resource, err.Error()) return generic.RESTOptions{}, fmt.Errorf("Unable to find storage destination for %v, due to %v", resource, err.Error())
} }
return generic.RESTOptions{ return generic.RESTOptions{
@ -356,7 +355,7 @@ func (f restOptionsFactory) NewFor(resource schema.GroupResource) generic.RESTOp
DeleteCollectionWorkers: f.deleteCollectionWorkers, DeleteCollectionWorkers: f.deleteCollectionWorkers,
EnableGarbageCollection: f.enableGarbageCollection, EnableGarbageCollection: f.enableGarbageCollection,
ResourcePrefix: f.storageFactory.ResourcePrefix(resource), ResourcePrefix: f.storageFactory.ResourcePrefix(resource),
} }, nil
} }
type nodeAddressProvider struct { type nodeAddressProvider struct {

View File

@ -12,13 +12,6 @@ load(
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = ["doc.go"],
"doc.go",
"interfaces.go",
],
tags = ["automanaged"], tags = ["automanaged"],
deps = [
"//pkg/registry/generic:go_default_library",
"//pkg/runtime/schema:go_default_library",
],
) )

View File

@ -20,11 +20,9 @@ go_library(
"//pkg/apis/apps:go_default_library", "//pkg/apis/apps:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/registry/apps/petset:go_default_library", "//pkg/registry/apps/petset:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -22,11 +22,9 @@ import (
appsapi "k8s.io/kubernetes/pkg/apis/apps" appsapi "k8s.io/kubernetes/pkg/apis/apps"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/registry/apps/petset" "k8s.io/kubernetes/pkg/registry/apps/petset"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
// rest implements a RESTStorage for replication controllers against etcd // rest implements a RESTStorage for replication controllers against etcd
@ -35,56 +33,25 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against replication controllers. // NewREST returns a RESTStorage object that will work against replication controllers.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &appsapi.StatefulSetList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.StatefulSet),
&appsapi.StatefulSet{},
prefix,
petset.Strategy,
newListFunc,
petset.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &appsapi.StatefulSet{} }, NewFunc: func() runtime.Object { return &appsapi.StatefulSet{} },
NewListFunc: func() runtime.Object { return &appsapi.StatefulSetList{} },
// NewListFunc returns an object capable of storing results of an etcd list.
NewListFunc: newListFunc,
// Produces a statefulSet 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 statefulSet 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)
},
// Retrieve the name field of a replication controller
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*appsapi.StatefulSet).Name, nil return obj.(*appsapi.StatefulSet).Name, nil
}, },
// Used to match objects based on labels/fields for list and watch
PredicateFunc: petset.MatchStatefulSet, PredicateFunc: petset.MatchStatefulSet,
QualifiedResource: appsapi.Resource("statefulsets"), QualifiedResource: appsapi.Resource("statefulsets"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
// Used to validate controller creation
CreateStrategy: petset.Strategy, CreateStrategy: petset.Strategy,
// Used to validate controller updates
UpdateStrategy: petset.Strategy, UpdateStrategy: petset.Strategy,
DeleteStrategy: petset.Strategy, DeleteStrategy: petset.Strategy,
Storage: storageInterface,
DestroyFunc: dFunc,
} }
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: petset.GetAttrs}
if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
}
statusStore := *store statusStore := *store
statusStore.UpdateStrategy = petset.StatusStrategy statusStore.UpdateStrategy = petset.StatusStrategy
return &REST{store}, &StatusREST{store: &statusStore} return &REST{store}, &StatusREST{store: &statusStore}

View File

@ -19,7 +19,7 @@ go_library(
"//pkg/apis/apps:go_default_library", "//pkg/apis/apps:go_default_library",
"//pkg/apis/apps/v1beta1:go_default_library", "//pkg/apis/apps/v1beta1:go_default_library",
"//pkg/genericapiserver:go_default_library", "//pkg/genericapiserver:go_default_library",
"//pkg/registry:go_default_library",
"//pkg/registry/apps/petset/etcd:go_default_library", "//pkg/registry/apps/petset/etcd:go_default_library",
"//pkg/registry/generic:go_default_library",
], ],
) )

View File

@ -21,13 +21,13 @@ import (
"k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/apps"
appsapiv1beta1 "k8s.io/kubernetes/pkg/apis/apps/v1beta1" appsapiv1beta1 "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/registry"
statefulsetetcd "k8s.io/kubernetes/pkg/registry/apps/petset/etcd" statefulsetetcd "k8s.io/kubernetes/pkg/registry/apps/petset/etcd"
"k8s.io/kubernetes/pkg/registry/generic"
) )
type RESTStorageProvider struct{} type RESTStorageProvider struct{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apps.GroupName) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apps.GroupName)
if apiResourceConfigSource.AnyResourcesForVersionEnabled(appsapiv1beta1.SchemeGroupVersion) { if apiResourceConfigSource.AnyResourcesForVersionEnabled(appsapiv1beta1.SchemeGroupVersion) {
@ -38,12 +38,12 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapise
return apiGroupInfo, true return apiGroupInfo, true
} }
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) map[string]rest.Storage { func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
version := appsapiv1beta1.SchemeGroupVersion version := appsapiv1beta1.SchemeGroupVersion
storage := map[string]rest.Storage{} storage := map[string]rest.Storage{}
if apiResourceConfigSource.ResourceEnabled(version.WithResource("statefulsets")) { if apiResourceConfigSource.ResourceEnabled(version.WithResource("statefulsets")) {
statefulsetStorage, statefulsetStatusStorage := statefulsetetcd.NewREST(restOptionsGetter(apps.Resource("statefulsets"))) statefulsetStorage, statefulsetStatusStorage := statefulsetetcd.NewREST(restOptionsGetter)
storage["statefulsets"] = statefulsetStorage storage["statefulsets"] = statefulsetStorage
storage["statefulsets/status"] = statefulsetStatusStorage storage["statefulsets/status"] = statefulsetStatusStorage
} }

View File

@ -20,7 +20,7 @@ go_library(
"//pkg/apis/authentication/v1beta1:go_default_library", "//pkg/apis/authentication/v1beta1:go_default_library",
"//pkg/auth/authenticator:go_default_library", "//pkg/auth/authenticator:go_default_library",
"//pkg/genericapiserver:go_default_library", "//pkg/genericapiserver:go_default_library",
"//pkg/registry:go_default_library",
"//pkg/registry/authentication/tokenreview:go_default_library", "//pkg/registry/authentication/tokenreview:go_default_library",
"//pkg/registry/generic:go_default_library",
], ],
) )

View File

@ -22,15 +22,15 @@ import (
authenticationv1beta1 "k8s.io/kubernetes/pkg/apis/authentication/v1beta1" authenticationv1beta1 "k8s.io/kubernetes/pkg/apis/authentication/v1beta1"
"k8s.io/kubernetes/pkg/auth/authenticator" "k8s.io/kubernetes/pkg/auth/authenticator"
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/registry"
"k8s.io/kubernetes/pkg/registry/authentication/tokenreview" "k8s.io/kubernetes/pkg/registry/authentication/tokenreview"
"k8s.io/kubernetes/pkg/registry/generic"
) )
type RESTStorageProvider struct { type RESTStorageProvider struct {
Authenticator authenticator.Request Authenticator authenticator.Request
} }
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
// TODO figure out how to make the swagger generation stable, while allowing this endpoint to be disabled. // TODO figure out how to make the swagger generation stable, while allowing this endpoint to be disabled.
// if p.Authenticator == nil { // if p.Authenticator == nil {
// return genericapiserver.APIGroupInfo{}, false // return genericapiserver.APIGroupInfo{}, false
@ -46,7 +46,7 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapise
return apiGroupInfo, true return apiGroupInfo, true
} }
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) map[string]rest.Storage { func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
version := authenticationv1beta1.SchemeGroupVersion version := authenticationv1beta1.SchemeGroupVersion
storage := map[string]rest.Storage{} storage := map[string]rest.Storage{}

View File

@ -20,9 +20,9 @@ go_library(
"//pkg/apis/authorization/v1beta1:go_default_library", "//pkg/apis/authorization/v1beta1:go_default_library",
"//pkg/auth/authorizer:go_default_library", "//pkg/auth/authorizer:go_default_library",
"//pkg/genericapiserver:go_default_library", "//pkg/genericapiserver:go_default_library",
"//pkg/registry:go_default_library",
"//pkg/registry/authorization/localsubjectaccessreview:go_default_library", "//pkg/registry/authorization/localsubjectaccessreview:go_default_library",
"//pkg/registry/authorization/selfsubjectaccessreview:go_default_library", "//pkg/registry/authorization/selfsubjectaccessreview:go_default_library",
"//pkg/registry/authorization/subjectaccessreview:go_default_library", "//pkg/registry/authorization/subjectaccessreview:go_default_library",
"//pkg/registry/generic:go_default_library",
], ],
) )

View File

@ -22,17 +22,17 @@ import (
authorizationv1beta1 "k8s.io/kubernetes/pkg/apis/authorization/v1beta1" authorizationv1beta1 "k8s.io/kubernetes/pkg/apis/authorization/v1beta1"
"k8s.io/kubernetes/pkg/auth/authorizer" "k8s.io/kubernetes/pkg/auth/authorizer"
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/registry"
"k8s.io/kubernetes/pkg/registry/authorization/localsubjectaccessreview" "k8s.io/kubernetes/pkg/registry/authorization/localsubjectaccessreview"
"k8s.io/kubernetes/pkg/registry/authorization/selfsubjectaccessreview" "k8s.io/kubernetes/pkg/registry/authorization/selfsubjectaccessreview"
"k8s.io/kubernetes/pkg/registry/authorization/subjectaccessreview" "k8s.io/kubernetes/pkg/registry/authorization/subjectaccessreview"
"k8s.io/kubernetes/pkg/registry/generic"
) )
type RESTStorageProvider struct { type RESTStorageProvider struct {
Authorizer authorizer.Authorizer Authorizer authorizer.Authorizer
} }
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
if p.Authorizer == nil { if p.Authorizer == nil {
return genericapiserver.APIGroupInfo{}, false return genericapiserver.APIGroupInfo{}, false
} }
@ -47,7 +47,7 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapise
return apiGroupInfo, true return apiGroupInfo, true
} }
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) map[string]rest.Storage { func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
version := authorizationv1beta1.SchemeGroupVersion version := authorizationv1beta1.SchemeGroupVersion
storage := map[string]rest.Storage{} storage := map[string]rest.Storage{}

View File

@ -20,11 +20,9 @@ go_library(
"//pkg/apis/autoscaling:go_default_library", "//pkg/apis/autoscaling:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/registry/autoscaling/horizontalpodautoscaler:go_default_library", "//pkg/registry/autoscaling/horizontalpodautoscaler:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -22,11 +22,9 @@ import (
"k8s.io/kubernetes/pkg/apis/autoscaling" "k8s.io/kubernetes/pkg/apis/autoscaling"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/registry/autoscaling/horizontalpodautoscaler" "k8s.io/kubernetes/pkg/registry/autoscaling/horizontalpodautoscaler"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
type REST struct { type REST struct {
@ -34,55 +32,25 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against horizontal pod autoscalers. // NewREST returns a RESTStorage object that will work against horizontal pod autoscalers.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &autoscaling.HorizontalPodAutoscalerList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.HorizontalPodAutoscalers),
&autoscaling.HorizontalPodAutoscaler{},
prefix,
horizontalpodautoscaler.Strategy,
newListFunc,
horizontalpodautoscaler.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &autoscaling.HorizontalPodAutoscaler{} }, NewFunc: func() runtime.Object { return &autoscaling.HorizontalPodAutoscaler{} },
// NewListFunc returns an object capable of storing results of an etcd list. NewListFunc: func() runtime.Object { return &autoscaling.HorizontalPodAutoscalerList{} },
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)
},
// Retrieve the name field of an autoscaler
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*autoscaling.HorizontalPodAutoscaler).Name, nil return obj.(*autoscaling.HorizontalPodAutoscaler).Name, nil
}, },
// Used to match objects based on labels/fields for list
PredicateFunc: horizontalpodautoscaler.MatchAutoscaler, PredicateFunc: horizontalpodautoscaler.MatchAutoscaler,
QualifiedResource: autoscaling.Resource("horizontalpodautoscalers"), QualifiedResource: autoscaling.Resource("horizontalpodautoscalers"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
// Used to validate autoscaler creation
CreateStrategy: horizontalpodautoscaler.Strategy, CreateStrategy: horizontalpodautoscaler.Strategy,
// Used to validate autoscaler updates
UpdateStrategy: horizontalpodautoscaler.Strategy, UpdateStrategy: horizontalpodautoscaler.Strategy,
DeleteStrategy: horizontalpodautoscaler.Strategy, DeleteStrategy: horizontalpodautoscaler.Strategy,
Storage: storageInterface,
DestroyFunc: dFunc,
} }
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: horizontalpodautoscaler.GetAttrs}
if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
}
statusStore := *store statusStore := *store
statusStore.UpdateStrategy = horizontalpodautoscaler.StatusStrategy statusStore.UpdateStrategy = horizontalpodautoscaler.StatusStrategy
return &REST{store}, &StatusREST{store: &statusStore} return &REST{store}, &StatusREST{store: &statusStore}

View File

@ -33,7 +33,12 @@ import (
func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, autoscaling.GroupName) etcdStorage, server := registrytest.NewEtcdStorage(t, autoscaling.GroupName)
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "horizontalpodautoscalers",
}
horizontalPodAutoscalerStorage, statusStorage := NewREST(restOptions) horizontalPodAutoscalerStorage, statusStorage := NewREST(restOptions)
return horizontalPodAutoscalerStorage, statusStorage, server return horizontalPodAutoscalerStorage, statusStorage, server
} }

View File

@ -19,7 +19,7 @@ go_library(
"//pkg/apis/autoscaling:go_default_library", "//pkg/apis/autoscaling:go_default_library",
"//pkg/apis/autoscaling/v1:go_default_library", "//pkg/apis/autoscaling/v1:go_default_library",
"//pkg/genericapiserver:go_default_library", "//pkg/genericapiserver:go_default_library",
"//pkg/registry:go_default_library",
"//pkg/registry/autoscaling/horizontalpodautoscaler/etcd:go_default_library", "//pkg/registry/autoscaling/horizontalpodautoscaler/etcd:go_default_library",
"//pkg/registry/generic:go_default_library",
], ],
) )

View File

@ -21,13 +21,13 @@ import (
"k8s.io/kubernetes/pkg/apis/autoscaling" "k8s.io/kubernetes/pkg/apis/autoscaling"
autoscalingapiv1 "k8s.io/kubernetes/pkg/apis/autoscaling/v1" autoscalingapiv1 "k8s.io/kubernetes/pkg/apis/autoscaling/v1"
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/registry"
horizontalpodautoscaleretcd "k8s.io/kubernetes/pkg/registry/autoscaling/horizontalpodautoscaler/etcd" horizontalpodautoscaleretcd "k8s.io/kubernetes/pkg/registry/autoscaling/horizontalpodautoscaler/etcd"
"k8s.io/kubernetes/pkg/registry/generic"
) )
type RESTStorageProvider struct{} type RESTStorageProvider struct{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(autoscaling.GroupName) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(autoscaling.GroupName)
if apiResourceConfigSource.AnyResourcesForVersionEnabled(autoscalingapiv1.SchemeGroupVersion) { if apiResourceConfigSource.AnyResourcesForVersionEnabled(autoscalingapiv1.SchemeGroupVersion) {
@ -38,12 +38,12 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapise
return apiGroupInfo, true return apiGroupInfo, true
} }
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) map[string]rest.Storage { func (p RESTStorageProvider) v1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
version := autoscalingapiv1.SchemeGroupVersion version := autoscalingapiv1.SchemeGroupVersion
storage := map[string]rest.Storage{} storage := map[string]rest.Storage{}
if apiResourceConfigSource.ResourceEnabled(version.WithResource("horizontalpodautoscalers")) { if apiResourceConfigSource.ResourceEnabled(version.WithResource("horizontalpodautoscalers")) {
hpaStorage, hpaStatusStorage := horizontalpodautoscaleretcd.NewREST(restOptionsGetter(autoscaling.Resource("horizontalpodautoscalers"))) hpaStorage, hpaStatusStorage := horizontalpodautoscaleretcd.NewREST(restOptionsGetter)
storage["horizontalpodautoscalers"] = hpaStorage storage["horizontalpodautoscalers"] = hpaStorage
storage["horizontalpodautoscalers/status"] = hpaStatusStorage storage["horizontalpodautoscalers/status"] = hpaStatusStorage
} }

View File

@ -20,11 +20,9 @@ go_library(
"//pkg/apis/batch:go_default_library", "//pkg/apis/batch:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/registry/batch/cronjob:go_default_library", "//pkg/registry/batch/cronjob:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -22,11 +22,9 @@ import (
"k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/batch"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/registry/batch/cronjob" "k8s.io/kubernetes/pkg/registry/batch/cronjob"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
// REST implements a RESTStorage for scheduled jobs against etcd // REST implements a RESTStorage for scheduled jobs against etcd
@ -35,55 +33,23 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against CronJobs. // NewREST returns a RESTStorage object that will work against CronJobs.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &batch.CronJobList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.CronJobs),
&batch.CronJob{},
prefix,
cronjob.Strategy,
newListFunc,
cronjob.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &batch.CronJob{} }, NewFunc: func() runtime.Object { return &batch.CronJob{} },
NewListFunc: func() runtime.Object { return &batch.CronJobList{} },
// 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)
},
// Retrieve the name field of a scheduled job
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*batch.CronJob).Name, nil return obj.(*batch.CronJob).Name, nil
}, },
// Used to match objects based on labels/fields for list and watch
PredicateFunc: cronjob.MatchCronJob, PredicateFunc: cronjob.MatchCronJob,
QualifiedResource: batch.Resource("cronjobs"), QualifiedResource: batch.Resource("cronjobs"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
// Used to validate scheduled job creation
CreateStrategy: cronjob.Strategy, CreateStrategy: cronjob.Strategy,
// Used to validate scheduled job updates
UpdateStrategy: cronjob.Strategy, UpdateStrategy: cronjob.Strategy,
DeleteStrategy: cronjob.Strategy, DeleteStrategy: cronjob.Strategy,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: cronjob.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
statusStore := *store statusStore := *store

View File

@ -20,11 +20,9 @@ go_library(
"//pkg/apis/batch:go_default_library", "//pkg/apis/batch:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/registry/batch/job:go_default_library", "//pkg/registry/batch/job:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -22,11 +22,9 @@ import (
"k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/batch"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/registry/batch/job" "k8s.io/kubernetes/pkg/registry/batch/job"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
// REST implements a RESTStorage for jobs against etcd // REST implements a RESTStorage for jobs against etcd
@ -35,55 +33,23 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against Jobs. // NewREST returns a RESTStorage object that will work against Jobs.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &batch.JobList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.Jobs),
&batch.Job{},
prefix,
job.Strategy,
newListFunc,
job.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &batch.Job{} }, NewFunc: func() runtime.Object { return &batch.Job{} },
NewListFunc: func() runtime.Object { return &batch.JobList{} },
// 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)
},
// Retrieve the name field of a job
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*batch.Job).Name, nil return obj.(*batch.Job).Name, nil
}, },
// Used to match objects based on labels/fields for list and watch
PredicateFunc: job.MatchJob, PredicateFunc: job.MatchJob,
QualifiedResource: batch.Resource("jobs"), QualifiedResource: batch.Resource("jobs"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
// Used to validate job creation
CreateStrategy: job.Strategy, CreateStrategy: job.Strategy,
// Used to validate job updates
UpdateStrategy: job.Strategy, UpdateStrategy: job.Strategy,
DeleteStrategy: job.Strategy, DeleteStrategy: job.Strategy,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: job.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
statusStore := *store statusStore := *store

View File

@ -33,7 +33,12 @@ import (
func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, extensions.GroupName) etcdStorage, server := registrytest.NewEtcdStorage(t, extensions.GroupName)
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "jobs",
}
jobStorage, statusStorage := NewREST(restOptions) jobStorage, statusStorage := NewREST(restOptions)
return jobStorage, statusStorage, server return jobStorage, statusStorage, server
} }

View File

@ -20,9 +20,9 @@ go_library(
"//pkg/apis/batch/v1:go_default_library", "//pkg/apis/batch/v1:go_default_library",
"//pkg/apis/batch/v2alpha1:go_default_library", "//pkg/apis/batch/v2alpha1:go_default_library",
"//pkg/genericapiserver:go_default_library", "//pkg/genericapiserver:go_default_library",
"//pkg/registry:go_default_library",
"//pkg/registry/batch/cronjob/etcd:go_default_library", "//pkg/registry/batch/cronjob/etcd:go_default_library",
"//pkg/registry/batch/job/etcd:go_default_library", "//pkg/registry/batch/job/etcd:go_default_library",
"//pkg/registry/generic:go_default_library",
"//pkg/runtime/schema:go_default_library", "//pkg/runtime/schema:go_default_library",
], ],
) )

View File

@ -22,15 +22,15 @@ import (
batchapiv1 "k8s.io/kubernetes/pkg/apis/batch/v1" batchapiv1 "k8s.io/kubernetes/pkg/apis/batch/v1"
batchapiv2alpha1 "k8s.io/kubernetes/pkg/apis/batch/v2alpha1" batchapiv2alpha1 "k8s.io/kubernetes/pkg/apis/batch/v2alpha1"
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/registry"
cronjobetcd "k8s.io/kubernetes/pkg/registry/batch/cronjob/etcd" cronjobetcd "k8s.io/kubernetes/pkg/registry/batch/cronjob/etcd"
jobetcd "k8s.io/kubernetes/pkg/registry/batch/job/etcd" jobetcd "k8s.io/kubernetes/pkg/registry/batch/job/etcd"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/runtime/schema" "k8s.io/kubernetes/pkg/runtime/schema"
) )
type RESTStorageProvider struct{} type RESTStorageProvider struct{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(batch.GroupName) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(batch.GroupName)
if apiResourceConfigSource.AnyResourcesForVersionEnabled(batchapiv2alpha1.SchemeGroupVersion) { if apiResourceConfigSource.AnyResourcesForVersionEnabled(batchapiv2alpha1.SchemeGroupVersion) {
@ -49,29 +49,29 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapise
return apiGroupInfo, true return apiGroupInfo, true
} }
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) map[string]rest.Storage { func (p RESTStorageProvider) v1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
version := batchapiv1.SchemeGroupVersion version := batchapiv1.SchemeGroupVersion
storage := map[string]rest.Storage{} storage := map[string]rest.Storage{}
if apiResourceConfigSource.ResourceEnabled(version.WithResource("jobs")) { if apiResourceConfigSource.ResourceEnabled(version.WithResource("jobs")) {
jobsStorage, jobsStatusStorage := jobetcd.NewREST(restOptionsGetter(batch.Resource("jobs"))) jobsStorage, jobsStatusStorage := jobetcd.NewREST(restOptionsGetter)
storage["jobs"] = jobsStorage storage["jobs"] = jobsStorage
storage["jobs/status"] = jobsStatusStorage storage["jobs/status"] = jobsStatusStorage
} }
return storage return storage
} }
func (p RESTStorageProvider) v2alpha1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) map[string]rest.Storage { func (p RESTStorageProvider) v2alpha1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
version := batchapiv2alpha1.SchemeGroupVersion version := batchapiv2alpha1.SchemeGroupVersion
storage := map[string]rest.Storage{} storage := map[string]rest.Storage{}
if apiResourceConfigSource.ResourceEnabled(version.WithResource("jobs")) { if apiResourceConfigSource.ResourceEnabled(version.WithResource("jobs")) {
jobsStorage, jobsStatusStorage := jobetcd.NewREST(restOptionsGetter(batch.Resource("jobs"))) jobsStorage, jobsStatusStorage := jobetcd.NewREST(restOptionsGetter)
storage["jobs"] = jobsStorage storage["jobs"] = jobsStorage
storage["jobs/status"] = jobsStatusStorage storage["jobs/status"] = jobsStatusStorage
} }
if apiResourceConfigSource.ResourceEnabled(version.WithResource("cronjobs")) { if apiResourceConfigSource.ResourceEnabled(version.WithResource("cronjobs")) {
cronJobsStorage, cronJobsStatusStorage := cronjobetcd.NewREST(restOptionsGetter(batch.Resource("cronjobs"))) cronJobsStorage, cronJobsStatusStorage := cronjobetcd.NewREST(restOptionsGetter)
storage["cronjobs"] = cronJobsStorage storage["cronjobs"] = cronJobsStorage
storage["cronjobs/status"] = cronJobsStatusStorage storage["cronjobs/status"] = cronJobsStatusStorage
storage["scheduledjobs"] = cronJobsStorage storage["scheduledjobs"] = cronJobsStorage

View File

@ -28,6 +28,7 @@ import (
type Resource string type Resource string
const ( const (
APIServices Resource = "apiservices"
CertificateSigningRequests Resource = "certificatesigningrequests" CertificateSigningRequests Resource = "certificatesigningrequests"
ClusterRoles Resource = "clusterroles" ClusterRoles Resource = "clusterroles"
ClusterRoleBindings Resource = "clusterrolebindings" ClusterRoleBindings Resource = "clusterrolebindings"
@ -90,6 +91,7 @@ func InitializeWatchCacheSizes(expectedRAMCapacityMB int) {
watchCacheSizes[Nodes] = maxInt(5*clusterSize, 1000) watchCacheSizes[Nodes] = maxInt(5*clusterSize, 1000)
watchCacheSizes[Pods] = maxInt(50*clusterSize, 1000) watchCacheSizes[Pods] = maxInt(50*clusterSize, 1000)
watchCacheSizes[Services] = maxInt(5*clusterSize, 1000) watchCacheSizes[Services] = maxInt(5*clusterSize, 1000)
watchCacheSizes[APIServices] = maxInt(5*clusterSize, 1000)
} }
func SetWatchCacheSizes(cacheSizes []string) { func SetWatchCacheSizes(cacheSizes []string) {
@ -110,7 +112,7 @@ func SetWatchCacheSizes(cacheSizes []string) {
} }
} }
func GetWatchCacheSizeByResource(resource Resource) int { func GetWatchCacheSizeByResource(resource Resource) int { // TODO this should use schema.GroupResource for lookups
if value, found := watchCacheSizes[resource]; found { if value, found := watchCacheSizes[resource]; found {
return value return value
} }

View File

@ -18,13 +18,9 @@ go_library(
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/api/rest:go_default_library", "//pkg/api/rest:go_default_library",
"//pkg/apis/certificates:go_default_library", "//pkg/apis/certificates:go_default_library",
"//pkg/fields:go_default_library",
"//pkg/labels:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/certificates/certificates:go_default_library", "//pkg/registry/certificates/certificates:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -20,14 +20,10 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/certificates" "k8s.io/kubernetes/pkg/apis/certificates"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/cachesize"
csrregistry "k8s.io/kubernetes/pkg/registry/certificates/certificates" csrregistry "k8s.io/kubernetes/pkg/registry/certificates/certificates"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
// REST implements a RESTStorage for CertificateSigningRequest against etcd // REST implements a RESTStorage for CertificateSigningRequest against etcd
@ -36,46 +32,23 @@ type REST struct {
} }
// NewREST returns a registry which will store CertificateSigningRequest in the given helper // NewREST returns a registry which will store CertificateSigningRequest in the given helper
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST, *ApprovalREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, *ApprovalREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &certificates.CertificateSigningRequestList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.CertificateSigningRequests),
&certificates.CertificateSigningRequest{},
prefix,
csrregistry.Strategy,
newListFunc,
csrregistry.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &certificates.CertificateSigningRequest{} }, NewFunc: func() runtime.Object { return &certificates.CertificateSigningRequest{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &certificates.CertificateSigningRequestList{} },
KeyRootFunc: func(ctx api.Context) string {
return prefix
},
KeyFunc: func(ctx api.Context, id string) (string, error) {
return genericregistry.NoNamespaceKeyFunc(ctx, prefix, id)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*certificates.CertificateSigningRequest).Name, nil return obj.(*certificates.CertificateSigningRequest).Name, nil
}, },
PredicateFunc: func(label labels.Selector, field fields.Selector) storage.SelectionPredicate { PredicateFunc: csrregistry.Matcher,
return csrregistry.Matcher(label, field)
},
QualifiedResource: certificates.Resource("certificatesigningrequests"), QualifiedResource: certificates.Resource("certificatesigningrequests"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: csrregistry.Strategy, CreateStrategy: csrregistry.Strategy,
UpdateStrategy: csrregistry.Strategy, UpdateStrategy: csrregistry.Strategy,
DeleteStrategy: csrregistry.Strategy, DeleteStrategy: csrregistry.Strategy,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: csrregistry.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
// Subresources use the same store and creation strategy, which only // Subresources use the same store and creation strategy, which only

View File

@ -19,7 +19,7 @@ go_library(
"//pkg/apis/certificates:go_default_library", "//pkg/apis/certificates:go_default_library",
"//pkg/apis/certificates/v1alpha1:go_default_library", "//pkg/apis/certificates/v1alpha1:go_default_library",
"//pkg/genericapiserver:go_default_library", "//pkg/genericapiserver:go_default_library",
"//pkg/registry:go_default_library",
"//pkg/registry/certificates/certificates/etcd:go_default_library", "//pkg/registry/certificates/certificates/etcd:go_default_library",
"//pkg/registry/generic:go_default_library",
], ],
) )

View File

@ -21,13 +21,13 @@ import (
"k8s.io/kubernetes/pkg/apis/certificates" "k8s.io/kubernetes/pkg/apis/certificates"
certificatesapiv1alpha1 "k8s.io/kubernetes/pkg/apis/certificates/v1alpha1" certificatesapiv1alpha1 "k8s.io/kubernetes/pkg/apis/certificates/v1alpha1"
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/registry"
certificateetcd "k8s.io/kubernetes/pkg/registry/certificates/certificates/etcd" certificateetcd "k8s.io/kubernetes/pkg/registry/certificates/certificates/etcd"
"k8s.io/kubernetes/pkg/registry/generic"
) )
type RESTStorageProvider struct{} type RESTStorageProvider struct{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) { func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(certificates.GroupName) apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(certificates.GroupName)
if apiResourceConfigSource.AnyResourcesForVersionEnabled(certificatesapiv1alpha1.SchemeGroupVersion) { if apiResourceConfigSource.AnyResourcesForVersionEnabled(certificatesapiv1alpha1.SchemeGroupVersion) {
@ -38,12 +38,12 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapise
return apiGroupInfo, true return apiGroupInfo, true
} }
func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter registry.RESTOptionsGetter) map[string]rest.Storage { func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
version := certificatesapiv1alpha1.SchemeGroupVersion version := certificatesapiv1alpha1.SchemeGroupVersion
storage := map[string]rest.Storage{} storage := map[string]rest.Storage{}
if apiResourceConfigSource.ResourceEnabled(version.WithResource("certificatesigningrequests")) { if apiResourceConfigSource.ResourceEnabled(version.WithResource("certificatesigningrequests")) {
csrStorage, csrStatusStorage, csrApprovalStorage := certificateetcd.NewREST(restOptionsGetter(certificates.Resource("certificatesigningrequests"))) csrStorage, csrStatusStorage, csrApprovalStorage := certificateetcd.NewREST(restOptionsGetter)
storage["certificatesigningrequests"] = csrStorage storage["certificatesigningrequests"] = csrStorage
storage["certificatesigningrequests/status"] = csrStatusStorage storage["certificatesigningrequests/status"] = csrStatusStorage
storage["certificatesigningrequests/approval"] = csrApprovalStorage storage["certificatesigningrequests/approval"] = csrApprovalStorage

View File

@ -16,12 +16,10 @@ go_library(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/configmap:go_default_library", "//pkg/registry/core/configmap:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -18,12 +18,10 @@ package etcd
import ( import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/configmap" "k8s.io/kubernetes/pkg/registry/core/configmap"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
// REST implements a RESTStorage for ConfigMap against etcd // REST implements a RESTStorage for ConfigMap against etcd
@ -32,59 +30,23 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work with ConfigMap objects. // NewREST returns a RESTStorage object that will work with ConfigMap objects.
func NewREST(opts generic.RESTOptions) *REST { func NewREST(optsGetter generic.RESTOptionsGetter) *REST {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.ConfigMapList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.ConfigMaps),
&api.ConfigMap{},
prefix,
configmap.Strategy,
newListFunc,
configmap.GetAttrs,
storage.NoTriggerPublisher)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { NewFunc: func() runtime.Object { return &api.ConfigMap{} },
return &api.ConfigMap{} NewListFunc: func() runtime.Object { return &api.ConfigMapList{} },
},
// NewListFunc returns an object to store 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)
},
// Retrieves the name field of a ConfigMap object.
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.ConfigMap).Name, nil return obj.(*api.ConfigMap).Name, nil
}, },
// Matches objects based on labels/fields for list and watch
PredicateFunc: configmap.MatchConfigMap, PredicateFunc: configmap.MatchConfigMap,
QualifiedResource: api.Resource("configmaps"), QualifiedResource: api.Resource("configmaps"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: configmap.Strategy, CreateStrategy: configmap.Strategy,
UpdateStrategy: configmap.Strategy, UpdateStrategy: configmap.Strategy,
DeleteStrategy: configmap.Strategy, DeleteStrategy: configmap.Strategy,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: configmap.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
return &REST{store} return &REST{store}
} }

View File

@ -30,7 +30,12 @@ import (
func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "configmaps",
}
return NewREST(restOptions), server return NewREST(restOptions), server
} }

View File

@ -22,12 +22,10 @@ go_library(
"//pkg/apis/autoscaling/validation:go_default_library", "//pkg/apis/autoscaling/validation:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/labels:go_default_library", "//pkg/labels:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/controller:go_default_library", "//pkg/registry/core/controller:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -28,12 +28,10 @@ import (
"k8s.io/kubernetes/pkg/apis/autoscaling/validation" "k8s.io/kubernetes/pkg/apis/autoscaling/validation"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/controller" "k8s.io/kubernetes/pkg/registry/core/controller"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
// ControllerStorage includes dummy storage for Replication Controllers and for Scale subresource. // ControllerStorage includes dummy storage for Replication Controllers and for Scale subresource.
@ -43,8 +41,8 @@ type ControllerStorage struct {
Scale *ScaleREST Scale *ScaleREST
} }
func NewStorage(opts generic.RESTOptions) ControllerStorage { func NewStorage(optsGetter generic.RESTOptionsGetter) ControllerStorage {
controllerREST, statusREST := NewREST(opts) controllerREST, statusREST := NewREST(optsGetter)
controllerRegistry := controller.NewRegistry(controllerREST) controllerRegistry := controller.NewRegistry(controllerREST)
return ControllerStorage{ return ControllerStorage{
@ -59,57 +57,25 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against replication controllers. // NewREST returns a RESTStorage object that will work against replication controllers.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.ReplicationControllerList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.Controllers),
&api.ReplicationController{},
prefix,
controller.Strategy,
newListFunc,
controller.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.ReplicationController{} }, NewFunc: func() runtime.Object { return &api.ReplicationController{} },
NewListFunc: func() runtime.Object { return &api.ReplicationControllerList{} },
// 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)
},
// Retrieve the name field of a replication controller
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.ReplicationController).Name, nil return obj.(*api.ReplicationController).Name, nil
}, },
// Used to match objects based on labels/fields for list and watch
PredicateFunc: controller.MatchController, PredicateFunc: controller.MatchController,
QualifiedResource: api.Resource("replicationcontrollers"), QualifiedResource: api.Resource("replicationcontrollers"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
// Used to validate controller creation
CreateStrategy: controller.Strategy, CreateStrategy: controller.Strategy,
// Used to validate controller updates
UpdateStrategy: controller.Strategy, UpdateStrategy: controller.Strategy,
DeleteStrategy: controller.Strategy, DeleteStrategy: controller.Strategy,
Storage: storageInterface,
DestroyFunc: dFunc,
} }
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: controller.GetAttrs}
if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
}
statusStore := *store statusStore := *store
statusStore.UpdateStrategy = controller.StatusStrategy statusStore.UpdateStrategy = controller.StatusStrategy

View File

@ -40,7 +40,12 @@ const (
func newStorage(t *testing.T) (ControllerStorage, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (ControllerStorage, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "replicationcontrollers",
}
storage := NewStorage(restOptions) storage := NewStorage(restOptions)
return storage, server return storage, server
} }

View File

@ -16,12 +16,10 @@ go_library(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/endpoint:go_default_library", "//pkg/registry/core/endpoint:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -18,12 +18,10 @@ package etcd
import ( import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/endpoint" "k8s.io/kubernetes/pkg/registry/core/endpoint"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
type REST struct { type REST struct {
@ -31,44 +29,23 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against endpoints. // NewREST returns a RESTStorage object that will work against endpoints.
func NewREST(opts generic.RESTOptions) *REST { func NewREST(optsGetter generic.RESTOptionsGetter) *REST {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.EndpointsList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.Endpoints),
&api.Endpoints{},
prefix,
endpoint.Strategy,
newListFunc,
endpoint.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Endpoints{} }, NewFunc: func() runtime.Object { return &api.Endpoints{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &api.EndpointsList{} },
KeyRootFunc: func(ctx api.Context) string {
return genericregistry.NamespaceKeyRootFunc(ctx, prefix)
},
KeyFunc: func(ctx api.Context, name string) (string, error) {
return genericregistry.NamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.Endpoints).Name, nil return obj.(*api.Endpoints).Name, nil
}, },
PredicateFunc: endpoint.MatchEndpoints, PredicateFunc: endpoint.MatchEndpoints,
QualifiedResource: api.Resource("endpoints"), QualifiedResource: api.Resource("endpoints"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: endpoint.Strategy, CreateStrategy: endpoint.Strategy,
UpdateStrategy: endpoint.Strategy, UpdateStrategy: endpoint.Strategy,
DeleteStrategy: endpoint.Strategy, DeleteStrategy: endpoint.Strategy,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: endpoint.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
return &REST{store} return &REST{store}
} }

View File

@ -30,7 +30,12 @@ import (
func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "endpoints",
}
return NewREST(restOptions), server return NewREST(restOptions), server
} }

View File

@ -29,22 +29,20 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against events. // NewREST returns a RESTStorage object that will work against events.
func NewREST(opts generic.RESTOptions, ttl uint64) *REST { func NewREST(optsGetter generic.RESTOptionsGetter, ttl uint64) *REST {
prefix := "/" + opts.ResourcePrefix resource := api.Resource("events")
opts, err := optsGetter.GetRESTOptions(resource)
if err != nil {
panic(err) // TODO: Propagate error up
}
// We explicitly do NOT do any decoration here - switching on Cacher // We explicitly do NOT do any decoration here - switching on Cacher
// for events will lead to too high memory consumption. // for events will lead to too high memory consumption.
storageInterface, dFunc := generic.NewRawStorage(opts.StorageConfig) opts.Decorator = generic.UndecoratedStorage // TODO use watchCacheSize=-1 to signal UndecoratedStorage
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Event{} }, NewFunc: func() runtime.Object { return &api.Event{} },
NewListFunc: func() runtime.Object { return &api.EventList{} }, NewListFunc: func() runtime.Object { return &api.EventList{} },
KeyRootFunc: func(ctx api.Context) string {
return genericregistry.NamespaceKeyRootFunc(ctx, prefix)
},
KeyFunc: func(ctx api.Context, id string) (string, error) {
return genericregistry.NamespaceKeyFunc(ctx, prefix, id)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.Event).Name, nil return obj.(*api.Event).Name, nil
}, },
@ -52,17 +50,15 @@ func NewREST(opts generic.RESTOptions, ttl uint64) *REST {
TTLFunc: func(runtime.Object, uint64, bool) (uint64, error) { TTLFunc: func(runtime.Object, uint64, bool) (uint64, error) {
return ttl, nil return ttl, nil
}, },
QualifiedResource: api.Resource("events"), QualifiedResource: resource,
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: event.Strategy, CreateStrategy: event.Strategy,
UpdateStrategy: event.Strategy, UpdateStrategy: event.Strategy,
DeleteStrategy: event.Strategy, DeleteStrategy: event.Strategy,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: opts, AttrFunc: event.GetAttrs} // Pass in opts to use UndecoratedStorage
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
return &REST{store} return &REST{store}
} }

View File

@ -30,7 +30,12 @@ var testTTL uint64 = 60
func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "events",
}
return NewREST(restOptions, testTTL), server return NewREST(restOptions, testTTL), server
} }

View File

@ -16,12 +16,10 @@ go_library(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/limitrange:go_default_library", "//pkg/registry/core/limitrange:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -18,12 +18,10 @@ package etcd
import ( import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/limitrange" "k8s.io/kubernetes/pkg/registry/core/limitrange"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
type REST struct { type REST struct {
@ -31,45 +29,24 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against horizontal pod autoscalers. // NewREST returns a RESTStorage object that will work against horizontal pod autoscalers.
func NewREST(opts generic.RESTOptions) *REST { func NewREST(optsGetter generic.RESTOptionsGetter) *REST {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.LimitRangeList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.LimitRanges),
&api.LimitRange{},
prefix,
limitrange.Strategy,
newListFunc,
limitrange.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.LimitRange{} }, NewFunc: func() runtime.Object { return &api.LimitRange{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &api.LimitRangeList{} },
KeyRootFunc: func(ctx api.Context) string {
return genericregistry.NamespaceKeyRootFunc(ctx, prefix)
},
KeyFunc: func(ctx api.Context, id string) (string, error) {
return genericregistry.NamespaceKeyFunc(ctx, prefix, id)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.LimitRange).Name, nil return obj.(*api.LimitRange).Name, nil
}, },
PredicateFunc: limitrange.MatchLimitRange, PredicateFunc: limitrange.MatchLimitRange,
QualifiedResource: api.Resource("limitranges"), QualifiedResource: api.Resource("limitranges"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: limitrange.Strategy, CreateStrategy: limitrange.Strategy,
UpdateStrategy: limitrange.Strategy, UpdateStrategy: limitrange.Strategy,
DeleteStrategy: limitrange.Strategy, DeleteStrategy: limitrange.Strategy,
ExportStrategy: limitrange.Strategy, ExportStrategy: limitrange.Strategy,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: limitrange.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
return &REST{store} return &REST{store}
} }

View File

@ -31,7 +31,12 @@ import (
func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "limitranges",
}
return NewREST(restOptions), server return NewREST(restOptions), server
} }

View File

@ -20,7 +20,6 @@ go_library(
"//pkg/api/errors/storage:go_default_library", "//pkg/api/errors/storage:go_default_library",
"//pkg/api/rest:go_default_library", "//pkg/api/rest:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/namespace:go_default_library", "//pkg/registry/core/namespace:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",

View File

@ -24,7 +24,6 @@ import (
storageerr "k8s.io/kubernetes/pkg/api/errors/storage" storageerr "k8s.io/kubernetes/pkg/api/errors/storage"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/namespace" "k8s.io/kubernetes/pkg/registry/core/namespace"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
@ -49,45 +48,24 @@ type FinalizeREST struct {
} }
// NewREST returns a RESTStorage object that will work against namespaces. // NewREST returns a RESTStorage object that will work against namespaces.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST, *FinalizeREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, *FinalizeREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.NamespaceList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.Namespaces),
&api.Namespace{},
prefix,
namespace.Strategy,
newListFunc,
namespace.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Namespace{} }, NewFunc: func() runtime.Object { return &api.Namespace{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &api.NamespaceList{} },
KeyRootFunc: func(ctx api.Context) string {
return prefix
},
KeyFunc: func(ctx api.Context, name string) (string, error) {
return genericregistry.NoNamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.Namespace).Name, nil return obj.(*api.Namespace).Name, nil
}, },
PredicateFunc: namespace.MatchNamespace, PredicateFunc: namespace.MatchNamespace,
QualifiedResource: api.Resource("namespaces"), QualifiedResource: api.Resource("namespaces"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: namespace.Strategy, CreateStrategy: namespace.Strategy,
UpdateStrategy: namespace.Strategy, UpdateStrategy: namespace.Strategy,
DeleteStrategy: namespace.Strategy, DeleteStrategy: namespace.Strategy,
ReturnDeletedObject: true, ReturnDeletedObject: true,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: namespace.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
statusStore := *store statusStore := *store

View File

@ -20,7 +20,6 @@ go_library(
"//pkg/api/v1:go_default_library", "//pkg/api/v1:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/kubelet/client:go_default_library", "//pkg/kubelet/client:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/node:go_default_library", "//pkg/registry/core/node:go_default_library",
"//pkg/registry/core/node/rest:go_default_library", "//pkg/registry/core/node/rest:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",

View File

@ -26,7 +26,6 @@ import (
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/kubelet/client" "k8s.io/kubernetes/pkg/kubelet/client"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/node" "k8s.io/kubernetes/pkg/registry/core/node"
noderest "k8s.io/kubernetes/pkg/registry/core/node/rest" noderest "k8s.io/kubernetes/pkg/registry/core/node/rest"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
@ -69,44 +68,24 @@ func (r *StatusREST) Update(ctx api.Context, name string, objInfo rest.UpdatedOb
} }
// NewStorage returns a NodeStorage object that will work against nodes. // NewStorage returns a NodeStorage object that will work against nodes.
func NewStorage(opts generic.RESTOptions, kubeletClientConfig client.KubeletClientConfig, proxyTransport http.RoundTripper) (*NodeStorage, error) { func NewStorage(optsGetter generic.RESTOptionsGetter, kubeletClientConfig client.KubeletClientConfig, proxyTransport http.RoundTripper) (*NodeStorage, error) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.NodeList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.Nodes),
&api.Node{},
prefix,
node.Strategy,
newListFunc,
node.GetAttrs,
node.NodeNameTriggerFunc)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Node{} }, NewFunc: func() runtime.Object { return &api.Node{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &api.NodeList{} },
KeyRootFunc: func(ctx api.Context) string {
return prefix
},
KeyFunc: func(ctx api.Context, name string) (string, error) {
return genericregistry.NoNamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.Node).Name, nil return obj.(*api.Node).Name, nil
}, },
PredicateFunc: node.MatchNode, PredicateFunc: node.MatchNode,
QualifiedResource: api.Resource("nodes"), QualifiedResource: api.Resource("nodes"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: node.Strategy, CreateStrategy: node.Strategy,
UpdateStrategy: node.Strategy, UpdateStrategy: node.Strategy,
DeleteStrategy: node.Strategy, DeleteStrategy: node.Strategy,
ExportStrategy: node.Strategy, ExportStrategy: node.Strategy,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: node.GetAttrs, TriggerFunc: node.NodeNameTriggerFunc}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
return nil, err
} }
statusStore := *store statusStore := *store

View File

@ -32,7 +32,12 @@ import (
func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "nodes",
}
storage, err := NewStorage(restOptions, kubeletclient.KubeletClientConfig{}, nil) storage, err := NewStorage(restOptions, kubeletclient.KubeletClientConfig{}, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -18,12 +18,10 @@ go_library(
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/api/rest:go_default_library", "//pkg/api/rest:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/persistentvolume:go_default_library", "//pkg/registry/core/persistentvolume:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -20,12 +20,10 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/persistentvolume" "k8s.io/kubernetes/pkg/registry/core/persistentvolume"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
type REST struct { type REST struct {
@ -33,45 +31,24 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against persistent volumes. // NewREST returns a RESTStorage object that will work against persistent volumes.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.PersistentVolumeList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.PersistentVolumes),
&api.PersistentVolume{},
prefix,
persistentvolume.Strategy,
newListFunc,
persistentvolume.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.PersistentVolume{} }, NewFunc: func() runtime.Object { return &api.PersistentVolume{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &api.PersistentVolumeList{} },
KeyRootFunc: func(ctx api.Context) string {
return prefix
},
KeyFunc: func(ctx api.Context, name string) (string, error) {
return genericregistry.NoNamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.PersistentVolume).Name, nil return obj.(*api.PersistentVolume).Name, nil
}, },
PredicateFunc: persistentvolume.MatchPersistentVolumes, PredicateFunc: persistentvolume.MatchPersistentVolumes,
QualifiedResource: api.Resource("persistentvolumes"), QualifiedResource: api.Resource("persistentvolumes"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: persistentvolume.Strategy, CreateStrategy: persistentvolume.Strategy,
UpdateStrategy: persistentvolume.Strategy, UpdateStrategy: persistentvolume.Strategy,
DeleteStrategy: persistentvolume.Strategy, DeleteStrategy: persistentvolume.Strategy,
ReturnDeletedObject: true, ReturnDeletedObject: true,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: persistentvolume.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
statusStore := *store statusStore := *store

View File

@ -34,7 +34,12 @@ import (
func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "persistentvolumes",
}
persistentVolumeStorage, statusStorage := NewREST(restOptions) persistentVolumeStorage, statusStorage := NewREST(restOptions)
return persistentVolumeStorage, statusStorage, server return persistentVolumeStorage, statusStorage, server
} }

View File

@ -18,12 +18,10 @@ go_library(
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/api/rest:go_default_library", "//pkg/api/rest:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/persistentvolumeclaim:go_default_library", "//pkg/registry/core/persistentvolumeclaim:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -20,12 +20,10 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/persistentvolumeclaim" "k8s.io/kubernetes/pkg/registry/core/persistentvolumeclaim"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
type REST struct { type REST struct {
@ -33,45 +31,24 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against persistent volume claims. // NewREST returns a RESTStorage object that will work against persistent volume claims.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.PersistentVolumeClaimList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.PersistentVolumeClaims),
&api.PersistentVolumeClaim{},
prefix,
persistentvolumeclaim.Strategy,
newListFunc,
persistentvolumeclaim.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} }, NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &api.PersistentVolumeClaimList{} },
KeyRootFunc: func(ctx api.Context) string {
return genericregistry.NamespaceKeyRootFunc(ctx, prefix)
},
KeyFunc: func(ctx api.Context, name string) (string, error) {
return genericregistry.NamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.PersistentVolumeClaim).Name, nil return obj.(*api.PersistentVolumeClaim).Name, nil
}, },
PredicateFunc: persistentvolumeclaim.MatchPersistentVolumeClaim, PredicateFunc: persistentvolumeclaim.MatchPersistentVolumeClaim,
QualifiedResource: api.Resource("persistentvolumeclaims"), QualifiedResource: api.Resource("persistentvolumeclaims"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: persistentvolumeclaim.Strategy, CreateStrategy: persistentvolumeclaim.Strategy,
UpdateStrategy: persistentvolumeclaim.Strategy, UpdateStrategy: persistentvolumeclaim.Strategy,
DeleteStrategy: persistentvolumeclaim.Strategy, DeleteStrategy: persistentvolumeclaim.Strategy,
ReturnDeletedObject: true, ReturnDeletedObject: true,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: persistentvolumeclaim.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
statusStore := *store statusStore := *store

View File

@ -34,7 +34,12 @@ import (
func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "persistentvolumeclaims",
}
persistentVolumeClaimStorage, statusStorage := NewREST(restOptions) persistentVolumeClaimStorage, statusStorage := NewREST(restOptions)
return persistentVolumeClaimStorage, statusStorage, server return persistentVolumeClaimStorage, statusStorage, server
} }

View File

@ -29,7 +29,6 @@ go_library(
"//pkg/client/retry:go_default_library", "//pkg/client/retry:go_default_library",
"//pkg/kubelet/client:go_default_library", "//pkg/kubelet/client:go_default_library",
"//pkg/labels:go_default_library", "//pkg/labels:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/pod:go_default_library", "//pkg/registry/core/pod:go_default_library",
"//pkg/registry/core/pod/rest:go_default_library", "//pkg/registry/core/pod/rest:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",

View File

@ -29,7 +29,6 @@ import (
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
policyclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/policy/internalversion" policyclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/policy/internalversion"
"k8s.io/kubernetes/pkg/kubelet/client" "k8s.io/kubernetes/pkg/kubelet/client"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/pod" "k8s.io/kubernetes/pkg/registry/core/pod"
podrest "k8s.io/kubernetes/pkg/registry/core/pod/rest" podrest "k8s.io/kubernetes/pkg/registry/core/pod/rest"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
@ -58,45 +57,24 @@ type REST struct {
} }
// NewStorage returns a RESTStorage object that will work against pods. // NewStorage returns a RESTStorage object that will work against pods.
func NewStorage(opts generic.RESTOptions, k client.ConnectionInfoGetter, proxyTransport http.RoundTripper, podDisruptionBudgetClient policyclient.PodDisruptionBudgetsGetter) PodStorage { func NewStorage(optsGetter generic.RESTOptionsGetter, k client.ConnectionInfoGetter, proxyTransport http.RoundTripper, podDisruptionBudgetClient policyclient.PodDisruptionBudgetsGetter) PodStorage {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.PodList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.Pods),
&api.Pod{},
prefix,
pod.Strategy,
newListFunc,
pod.GetAttrs,
pod.NodeNameTriggerFunc,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Pod{} }, NewFunc: func() runtime.Object { return &api.Pod{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &api.PodList{} },
KeyRootFunc: func(ctx api.Context) string {
return genericregistry.NamespaceKeyRootFunc(ctx, prefix)
},
KeyFunc: func(ctx api.Context, name string) (string, error) {
return genericregistry.NamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.Pod).Name, nil return obj.(*api.Pod).Name, nil
}, },
PredicateFunc: pod.MatchPod, PredicateFunc: pod.MatchPod,
QualifiedResource: api.Resource("pods"), QualifiedResource: api.Resource("pods"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: pod.Strategy, CreateStrategy: pod.Strategy,
UpdateStrategy: pod.Strategy, UpdateStrategy: pod.Strategy,
DeleteStrategy: pod.Strategy, DeleteStrategy: pod.Strategy,
ReturnDeletedObject: true, ReturnDeletedObject: true,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: pod.GetAttrs, TriggerFunc: pod.NodeNameTriggerFunc}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
statusStore := *store statusStore := *store

View File

@ -39,7 +39,12 @@ import (
func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 3} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 3,
ResourcePrefix: "pods",
}
storage := NewStorage(restOptions, nil, nil, nil) storage := NewStorage(restOptions, nil, nil, nil)
return storage.Pod, storage.Binding, storage.Status, server return storage.Pod, storage.Binding, storage.Status, server
} }
@ -147,7 +152,12 @@ func (f FailDeletionStorage) Delete(ctx context.Context, key string, out runtime
func newFailDeleteStorage(t *testing.T, called *bool) (*REST, *etcdtesting.EtcdTestServer) { func newFailDeleteStorage(t *testing.T, called *bool) (*REST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 3} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 3,
ResourcePrefix: "pods",
}
storage := NewStorage(restOptions, nil, nil, nil) storage := NewStorage(restOptions, nil, nil, nil)
storage.Pod.Store.Storage = FailDeletionStorage{storage.Pod.Store.Storage, called} storage.Pod.Store.Storage = FailDeletionStorage{storage.Pod.Store.Storage, called}
return storage.Pod, server return storage.Pod, server

View File

@ -16,12 +16,10 @@ go_library(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/podtemplate:go_default_library", "//pkg/registry/core/podtemplate:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -18,12 +18,10 @@ package etcd
import ( import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/podtemplate" "k8s.io/kubernetes/pkg/registry/core/podtemplate"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
type REST struct { type REST struct {
@ -31,37 +29,15 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against pod templates. // NewREST returns a RESTStorage object that will work against pod templates.
func NewREST(opts generic.RESTOptions) *REST { func NewREST(optsGetter generic.RESTOptionsGetter) *REST {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.PodTemplateList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.PodTemplates),
&api.PodTemplate{},
prefix,
podtemplate.Strategy,
newListFunc,
podtemplate.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.PodTemplate{} }, NewFunc: func() runtime.Object { return &api.PodTemplate{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &api.PodTemplateList{} },
KeyRootFunc: func(ctx api.Context) string {
return genericregistry.NamespaceKeyRootFunc(ctx, prefix)
},
KeyFunc: func(ctx api.Context, name string) (string, error) {
return genericregistry.NamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.PodTemplate).Name, nil return obj.(*api.PodTemplate).Name, nil
}, },
PredicateFunc: podtemplate.MatchPodTemplate, PredicateFunc: podtemplate.MatchPodTemplate,
QualifiedResource: api.Resource("podtemplates"), QualifiedResource: api.Resource("podtemplates"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: podtemplate.Strategy, CreateStrategy: podtemplate.Strategy,
UpdateStrategy: podtemplate.Strategy, UpdateStrategy: podtemplate.Strategy,
@ -69,9 +45,10 @@ func NewREST(opts generic.RESTOptions) *REST {
ExportStrategy: podtemplate.Strategy, ExportStrategy: podtemplate.Strategy,
ReturnDeletedObject: true, ReturnDeletedObject: true,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: podtemplate.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
return &REST{store} return &REST{store}
} }

View File

@ -30,7 +30,12 @@ import (
func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "podtemplates",
}
return NewREST(restOptions), server return NewREST(restOptions), server
} }

View File

@ -18,12 +18,10 @@ go_library(
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/api/rest:go_default_library", "//pkg/api/rest:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/resourcequota:go_default_library", "//pkg/registry/core/resourcequota:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -20,12 +20,10 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/resourcequota" "k8s.io/kubernetes/pkg/registry/core/resourcequota"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
type REST struct { type REST struct {
@ -33,45 +31,24 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against resource quotas. // NewREST returns a RESTStorage object that will work against resource quotas.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.ResourceQuotaList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.ResourceQuotas),
&api.ResourceQuota{},
prefix,
resourcequota.Strategy,
newListFunc,
resourcequota.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.ResourceQuota{} }, NewFunc: func() runtime.Object { return &api.ResourceQuota{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &api.ResourceQuotaList{} },
KeyRootFunc: func(ctx api.Context) string {
return genericregistry.NamespaceKeyRootFunc(ctx, prefix)
},
KeyFunc: func(ctx api.Context, name string) (string, error) {
return genericregistry.NamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.ResourceQuota).Name, nil return obj.(*api.ResourceQuota).Name, nil
}, },
PredicateFunc: resourcequota.MatchResourceQuota, PredicateFunc: resourcequota.MatchResourceQuota,
QualifiedResource: api.Resource("resourcequotas"), QualifiedResource: api.Resource("resourcequotas"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: resourcequota.Strategy, CreateStrategy: resourcequota.Strategy,
UpdateStrategy: resourcequota.Strategy, UpdateStrategy: resourcequota.Strategy,
DeleteStrategy: resourcequota.Strategy, DeleteStrategy: resourcequota.Strategy,
ReturnDeletedObject: true, ReturnDeletedObject: true,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: resourcequota.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
statusStore := *store statusStore := *store

View File

@ -33,7 +33,12 @@ import (
func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "resourcequotas",
}
resourceQuotaStorage, statusStorage := NewREST(restOptions) resourceQuotaStorage, statusStorage := NewREST(restOptions)
return resourceQuotaStorage, statusStorage, server return resourceQuotaStorage, statusStorage, server
} }

View File

@ -24,7 +24,6 @@ go_library(
"//pkg/genericapiserver:go_default_library", "//pkg/genericapiserver:go_default_library",
"//pkg/kubelet/client:go_default_library", "//pkg/kubelet/client:go_default_library",
"//pkg/master/ports:go_default_library", "//pkg/master/ports:go_default_library",
"//pkg/registry:go_default_library",
"//pkg/registry/core/componentstatus:go_default_library", "//pkg/registry/core/componentstatus:go_default_library",
"//pkg/registry/core/configmap/etcd:go_default_library", "//pkg/registry/core/configmap/etcd:go_default_library",
"//pkg/registry/core/controller/etcd:go_default_library", "//pkg/registry/core/controller/etcd:go_default_library",
@ -48,6 +47,7 @@ go_library(
"//pkg/registry/core/service/ipallocator:go_default_library", "//pkg/registry/core/service/ipallocator:go_default_library",
"//pkg/registry/core/service/portallocator:go_default_library", "//pkg/registry/core/service/portallocator:go_default_library",
"//pkg/registry/core/serviceaccount/etcd:go_default_library", "//pkg/registry/core/serviceaccount/etcd:go_default_library",
"//pkg/registry/generic:go_default_library",
"//pkg/runtime/schema:go_default_library", "//pkg/runtime/schema:go_default_library",
"//pkg/storage/etcd/util:go_default_library", "//pkg/storage/etcd/util:go_default_library",
"//pkg/util/net:go_default_library", "//pkg/util/net:go_default_library",

View File

@ -36,7 +36,6 @@ import (
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client" kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
"k8s.io/kubernetes/pkg/master/ports" "k8s.io/kubernetes/pkg/master/ports"
"k8s.io/kubernetes/pkg/registry"
"k8s.io/kubernetes/pkg/registry/core/componentstatus" "k8s.io/kubernetes/pkg/registry/core/componentstatus"
configmapetcd "k8s.io/kubernetes/pkg/registry/core/configmap/etcd" configmapetcd "k8s.io/kubernetes/pkg/registry/core/configmap/etcd"
controlleretcd "k8s.io/kubernetes/pkg/registry/core/controller/etcd" controlleretcd "k8s.io/kubernetes/pkg/registry/core/controller/etcd"
@ -57,9 +56,10 @@ import (
"k8s.io/kubernetes/pkg/registry/core/service/allocator" "k8s.io/kubernetes/pkg/registry/core/service/allocator"
etcdallocator "k8s.io/kubernetes/pkg/registry/core/service/allocator/etcd" etcdallocator "k8s.io/kubernetes/pkg/registry/core/service/allocator/etcd"
serviceetcd "k8s.io/kubernetes/pkg/registry/core/service/etcd" serviceetcd "k8s.io/kubernetes/pkg/registry/core/service/etcd"
ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" "k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
"k8s.io/kubernetes/pkg/registry/core/service/portallocator" "k8s.io/kubernetes/pkg/registry/core/service/portallocator"
serviceaccountetcd "k8s.io/kubernetes/pkg/registry/core/serviceaccount/etcd" serviceaccountetcd "k8s.io/kubernetes/pkg/registry/core/serviceaccount/etcd"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/runtime/schema" "k8s.io/kubernetes/pkg/runtime/schema"
etcdutil "k8s.io/kubernetes/pkg/storage/etcd/util" etcdutil "k8s.io/kubernetes/pkg/storage/etcd/util"
utilnet "k8s.io/kubernetes/pkg/util/net" utilnet "k8s.io/kubernetes/pkg/util/net"
@ -89,7 +89,7 @@ type LegacyRESTStorage struct {
ServiceNodePortAllocator rangeallocation.RangeRegistry ServiceNodePortAllocator rangeallocation.RangeRegistry
} }
func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(restOptionsGetter registry.RESTOptionsGetter) (LegacyRESTStorage, genericapiserver.APIGroupInfo, error) { func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(restOptionsGetter generic.RESTOptionsGetter) (LegacyRESTStorage, genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.APIGroupInfo{ apiGroupInfo := genericapiserver.APIGroupInfo{
GroupMeta: *registered.GroupOrDie(api.GroupName), GroupMeta: *registered.GroupOrDie(api.GroupName),
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{}, VersionedResourcesStorageMap: map[string]map[string]rest.Storage{},
@ -114,36 +114,36 @@ func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(restOptionsGetter regist
} }
restStorage := LegacyRESTStorage{} restStorage := LegacyRESTStorage{}
podTemplateStorage := podtemplateetcd.NewREST(restOptionsGetter(api.Resource("podTemplates"))) podTemplateStorage := podtemplateetcd.NewREST(restOptionsGetter)
eventStorage := eventetcd.NewREST(restOptionsGetter(api.Resource("events")), uint64(c.EventTTL.Seconds())) eventStorage := eventetcd.NewREST(restOptionsGetter, uint64(c.EventTTL.Seconds()))
limitRangeStorage := limitrangeetcd.NewREST(restOptionsGetter(api.Resource("limitRanges"))) limitRangeStorage := limitrangeetcd.NewREST(restOptionsGetter)
resourceQuotaStorage, resourceQuotaStatusStorage := resourcequotaetcd.NewREST(restOptionsGetter(api.Resource("resourceQuotas"))) resourceQuotaStorage, resourceQuotaStatusStorage := resourcequotaetcd.NewREST(restOptionsGetter)
secretStorage := secretetcd.NewREST(restOptionsGetter(api.Resource("secrets"))) secretStorage := secretetcd.NewREST(restOptionsGetter)
serviceAccountStorage := serviceaccountetcd.NewREST(restOptionsGetter(api.Resource("serviceAccounts"))) serviceAccountStorage := serviceaccountetcd.NewREST(restOptionsGetter)
persistentVolumeStorage, persistentVolumeStatusStorage := pvetcd.NewREST(restOptionsGetter(api.Resource("persistentVolumes"))) persistentVolumeStorage, persistentVolumeStatusStorage := pvetcd.NewREST(restOptionsGetter)
persistentVolumeClaimStorage, persistentVolumeClaimStatusStorage := pvcetcd.NewREST(restOptionsGetter(api.Resource("persistentVolumeClaims"))) persistentVolumeClaimStorage, persistentVolumeClaimStatusStorage := pvcetcd.NewREST(restOptionsGetter)
configMapStorage := configmapetcd.NewREST(restOptionsGetter(api.Resource("configMaps"))) configMapStorage := configmapetcd.NewREST(restOptionsGetter)
namespaceStorage, namespaceStatusStorage, namespaceFinalizeStorage := namespaceetcd.NewREST(restOptionsGetter(api.Resource("namespaces"))) namespaceStorage, namespaceStatusStorage, namespaceFinalizeStorage := namespaceetcd.NewREST(restOptionsGetter)
endpointsStorage := endpointsetcd.NewREST(restOptionsGetter(api.Resource("endpoints"))) endpointsStorage := endpointsetcd.NewREST(restOptionsGetter)
endpointRegistry := endpoint.NewRegistry(endpointsStorage) endpointRegistry := endpoint.NewRegistry(endpointsStorage)
nodeStorage, err := nodeetcd.NewStorage(restOptionsGetter(api.Resource("nodes")), c.KubeletClientConfig, c.ProxyTransport) nodeStorage, err := nodeetcd.NewStorage(restOptionsGetter, c.KubeletClientConfig, c.ProxyTransport)
if err != nil { if err != nil {
return LegacyRESTStorage{}, genericapiserver.APIGroupInfo{}, err return LegacyRESTStorage{}, genericapiserver.APIGroupInfo{}, err
} }
podStorage := podetcd.NewStorage( podStorage := podetcd.NewStorage(
restOptionsGetter(api.Resource("pods")), restOptionsGetter,
nodeStorage.KubeletConnectionInfo, nodeStorage.KubeletConnectionInfo,
c.ProxyTransport, c.ProxyTransport,
podDisruptionClient, podDisruptionClient,
) )
serviceRESTStorage, serviceStatusStorage := serviceetcd.NewREST(restOptionsGetter(api.Resource("services"))) serviceRESTStorage, serviceStatusStorage := serviceetcd.NewREST(restOptionsGetter)
serviceRegistry := service.NewRegistry(serviceRESTStorage) serviceRegistry := service.NewRegistry(serviceRESTStorage)
var serviceClusterIPRegistry rangeallocation.RangeRegistry var serviceClusterIPRegistry rangeallocation.RangeRegistry
@ -176,7 +176,7 @@ func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(restOptionsGetter regist
}) })
restStorage.ServiceNodePortAllocator = serviceNodePortRegistry restStorage.ServiceNodePortAllocator = serviceNodePortRegistry
controllerStorage := controlleretcd.NewStorage(restOptionsGetter(api.Resource("replicationControllers"))) controllerStorage := controlleretcd.NewStorage(restOptionsGetter)
serviceRest := service.NewStorage(serviceRegistry, endpointRegistry, ServiceClusterIPAllocator, ServiceNodePortAllocator, c.ProxyTransport) serviceRest := service.NewStorage(serviceRegistry, endpointRegistry, ServiceClusterIPAllocator, ServiceNodePortAllocator, c.ProxyTransport)

View File

@ -16,12 +16,10 @@ go_library(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/secret:go_default_library", "//pkg/registry/core/secret:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -18,12 +18,10 @@ package etcd
import ( import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/secret" "k8s.io/kubernetes/pkg/registry/core/secret"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
type REST struct { type REST struct {
@ -31,44 +29,23 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against secrets. // NewREST returns a RESTStorage object that will work against secrets.
func NewREST(opts generic.RESTOptions) *REST { func NewREST(optsGetter generic.RESTOptionsGetter) *REST {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.SecretList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.Secrets),
&api.Secret{},
prefix,
secret.Strategy,
newListFunc,
secret.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Secret{} }, NewFunc: func() runtime.Object { return &api.Secret{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &api.SecretList{} },
KeyRootFunc: func(ctx api.Context) string {
return genericregistry.NamespaceKeyRootFunc(ctx, prefix)
},
KeyFunc: func(ctx api.Context, id string) (string, error) {
return genericregistry.NamespaceKeyFunc(ctx, prefix, id)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.Secret).Name, nil return obj.(*api.Secret).Name, nil
}, },
PredicateFunc: secret.Matcher, PredicateFunc: secret.Matcher,
QualifiedResource: api.Resource("secrets"), QualifiedResource: api.Resource("secrets"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: secret.Strategy, CreateStrategy: secret.Strategy,
UpdateStrategy: secret.Strategy, UpdateStrategy: secret.Strategy,
DeleteStrategy: secret.Strategy, DeleteStrategy: secret.Strategy,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: secret.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
return &REST{store} return &REST{store}
} }

View File

@ -30,7 +30,12 @@ import (
func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "secrets",
}
return NewREST(restOptions), server return NewREST(restOptions), server
} }

View File

@ -18,12 +18,10 @@ go_library(
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/api/rest:go_default_library", "//pkg/api/rest:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/service:go_default_library", "//pkg/registry/core/service:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -20,12 +20,10 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/service" "k8s.io/kubernetes/pkg/registry/core/service"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
type REST struct { type REST struct {
@ -33,46 +31,26 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against services. // NewREST returns a RESTStorage object that will work against services.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.ServiceList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.Services),
&api.Service{},
prefix,
service.Strategy,
newListFunc,
service.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.Service{} }, NewFunc: func() runtime.Object { return &api.Service{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &api.ServiceList{} },
KeyRootFunc: func(ctx api.Context) string {
return genericregistry.NamespaceKeyRootFunc(ctx, prefix)
},
KeyFunc: func(ctx api.Context, name string) (string, error) {
return genericregistry.NamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.Service).Name, nil return obj.(*api.Service).Name, nil
}, },
PredicateFunc: service.MatchServices, PredicateFunc: service.MatchServices,
QualifiedResource: api.Resource("services"), QualifiedResource: api.Resource("services"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: service.Strategy, CreateStrategy: service.Strategy,
UpdateStrategy: service.Strategy, UpdateStrategy: service.Strategy,
DeleteStrategy: service.Strategy, DeleteStrategy: service.Strategy,
ExportStrategy: service.Strategy, ExportStrategy: service.Strategy,
Storage: storageInterface,
DestroyFunc: dFunc,
} }
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: service.GetAttrs}
if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
}
statusStore := *store statusStore := *store
statusStore.UpdateStrategy = service.StatusStrategy statusStore.UpdateStrategy = service.StatusStrategy
return &REST{store}, &StatusREST{store: &statusStore} return &REST{store}, &StatusREST{store: &statusStore}

View File

@ -31,7 +31,12 @@ import (
func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "services",
}
serviceStorage, statusStorage := NewREST(restOptions) serviceStorage, statusStorage := NewREST(restOptions)
return serviceStorage, statusStorage, server return serviceStorage, statusStorage, server
} }

View File

@ -16,12 +16,10 @@ go_library(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/serviceaccount:go_default_library", "//pkg/registry/core/serviceaccount:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -18,12 +18,10 @@ package etcd
import ( import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/serviceaccount" "k8s.io/kubernetes/pkg/registry/core/serviceaccount"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
type REST struct { type REST struct {
@ -31,45 +29,24 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against service accounts. // NewREST returns a RESTStorage object that will work against service accounts.
func NewREST(opts generic.RESTOptions) *REST { func NewREST(optsGetter generic.RESTOptionsGetter) *REST {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &api.ServiceAccountList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.ServiceAccounts),
&api.ServiceAccount{},
prefix,
serviceaccount.Strategy,
newListFunc,
serviceaccount.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &api.ServiceAccount{} }, NewFunc: func() runtime.Object { return &api.ServiceAccount{} },
NewListFunc: newListFunc, NewListFunc: func() runtime.Object { return &api.ServiceAccountList{} },
KeyRootFunc: func(ctx api.Context) string {
return genericregistry.NamespaceKeyRootFunc(ctx, prefix)
},
KeyFunc: func(ctx api.Context, name string) (string, error) {
return genericregistry.NamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.ServiceAccount).Name, nil return obj.(*api.ServiceAccount).Name, nil
}, },
PredicateFunc: serviceaccount.Matcher, PredicateFunc: serviceaccount.Matcher,
QualifiedResource: api.Resource("serviceaccounts"), QualifiedResource: api.Resource("serviceaccounts"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
CreateStrategy: serviceaccount.Strategy, CreateStrategy: serviceaccount.Strategy,
UpdateStrategy: serviceaccount.Strategy, UpdateStrategy: serviceaccount.Strategy,
DeleteStrategy: serviceaccount.Strategy, DeleteStrategy: serviceaccount.Strategy,
ReturnDeletedObject: true, ReturnDeletedObject: true,
}
Storage: storageInterface, options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: serviceaccount.GetAttrs}
DestroyFunc: dFunc, if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
} }
return &REST{store} return &REST{store}
} }

View File

@ -30,7 +30,12 @@ import (
func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "") etcdStorage, server := registrytest.NewEtcdStorage(t, "")
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "serviceaccounts",
}
return NewREST(restOptions), server return NewREST(restOptions), server
} }

View File

@ -39,9 +39,9 @@ type ContainerStorage struct {
Scale *ScaleREST Scale *ScaleREST
} }
func NewStorage(opts generic.RESTOptions) ContainerStorage { func NewStorage(optsGetter generic.RESTOptionsGetter) ContainerStorage {
// scale does not set status, only updates spec so we ignore the status // scale does not set status, only updates spec so we ignore the status
controllerREST, _ := etcd.NewREST(opts) controllerREST, _ := etcd.NewREST(optsGetter)
rcRegistry := controller.NewRegistry(controllerREST) rcRegistry := controller.NewRegistry(controllerREST)
return ContainerStorage{ return ContainerStorage{

View File

@ -19,12 +19,10 @@ go_library(
"//pkg/api/rest:go_default_library", "//pkg/api/rest:go_default_library",
"//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/extensions/daemonset:go_default_library", "//pkg/registry/extensions/daemonset:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",
"//pkg/runtime:go_default_library", "//pkg/runtime:go_default_library",
"//pkg/storage:go_default_library",
], ],
) )

View File

@ -21,12 +21,10 @@ import (
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/extensions/daemonset" "k8s.io/kubernetes/pkg/registry/extensions/daemonset"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
) )
// rest implements a RESTStorage for DaemonSets against etcd // rest implements a RESTStorage for DaemonSets against etcd
@ -35,56 +33,25 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against DaemonSets. // NewREST returns a RESTStorage object that will work against DaemonSets.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &extensions.DaemonSetList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.Daemonsets),
&extensions.DaemonSet{},
prefix,
daemonset.Strategy,
newListFunc,
daemonset.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &extensions.DaemonSet{} }, NewFunc: func() runtime.Object { return &extensions.DaemonSet{} },
NewListFunc: func() runtime.Object { return &extensions.DaemonSetList{} },
// 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)
},
// Retrieve the name field of a daemon set
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*extensions.DaemonSet).Name, nil return obj.(*extensions.DaemonSet).Name, nil
}, },
// Used to match objects based on labels/fields for list and watch
PredicateFunc: daemonset.MatchDaemonSet, PredicateFunc: daemonset.MatchDaemonSet,
QualifiedResource: extensions.Resource("daemonsets"), QualifiedResource: extensions.Resource("daemonsets"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
// Used to validate daemon set creation
CreateStrategy: daemonset.Strategy, CreateStrategy: daemonset.Strategy,
// Used to validate daemon set updates
UpdateStrategy: daemonset.Strategy, UpdateStrategy: daemonset.Strategy,
DeleteStrategy: daemonset.Strategy, DeleteStrategy: daemonset.Strategy,
Storage: storageInterface,
DestroyFunc: dFunc,
} }
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: daemonset.GetAttrs}
if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
}
statusStore := *store statusStore := *store
statusStore.UpdateStrategy = daemonset.StatusStrategy statusStore.UpdateStrategy = daemonset.StatusStrategy

View File

@ -32,7 +32,12 @@ import (
func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) { func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, extensions.GroupName) etcdStorage, server := registrytest.NewEtcdStorage(t, extensions.GroupName)
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1} restOptions := generic.RESTOptions{
StorageConfig: etcdStorage,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 1,
ResourcePrefix: "daemonsets",
}
daemonSetStorage, statusStorage := NewREST(restOptions) daemonSetStorage, statusStorage := NewREST(restOptions)
return daemonSetStorage, statusStorage, server return daemonSetStorage, statusStorage, server
} }

View File

@ -22,7 +22,6 @@ go_library(
"//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions:go_default_library",
"//pkg/apis/extensions/validation:go_default_library", "//pkg/apis/extensions/validation:go_default_library",
"//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/registry/extensions/deployment:go_default_library", "//pkg/registry/extensions/deployment:go_default_library",
"//pkg/registry/generic:go_default_library", "//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/registry:go_default_library", "//pkg/registry/generic/registry:go_default_library",

View File

@ -27,7 +27,6 @@ import (
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions"
extvalidation "k8s.io/kubernetes/pkg/apis/extensions/validation" extvalidation "k8s.io/kubernetes/pkg/apis/extensions/validation"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/extensions/deployment" "k8s.io/kubernetes/pkg/registry/extensions/deployment"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry"
@ -43,8 +42,8 @@ type DeploymentStorage struct {
Rollback *RollbackREST Rollback *RollbackREST
} }
func NewStorage(opts generic.RESTOptions) DeploymentStorage { func NewStorage(optsGetter generic.RESTOptionsGetter) DeploymentStorage {
deploymentRest, deploymentStatusRest, deploymentRollbackRest := NewREST(opts) deploymentRest, deploymentStatusRest, deploymentRollbackRest := NewREST(optsGetter)
deploymentRegistry := deployment.NewRegistry(deploymentRest) deploymentRegistry := deployment.NewRegistry(deploymentRest)
return DeploymentStorage{ return DeploymentStorage{
@ -60,55 +59,25 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against deployments. // NewREST returns a RESTStorage object that will work against deployments.
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST, *RollbackREST) { func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, *RollbackREST) {
prefix := "/" + opts.ResourcePrefix
newListFunc := func() runtime.Object { return &extensions.DeploymentList{} }
storageInterface, dFunc := opts.Decorator(
opts.StorageConfig,
cachesize.GetWatchCacheSizeByResource(cachesize.Deployments),
&extensions.Deployment{},
prefix,
deployment.Strategy,
newListFunc,
deployment.GetAttrs,
storage.NoTriggerPublisher,
)
store := &genericregistry.Store{ store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &extensions.Deployment{} }, NewFunc: func() runtime.Object { return &extensions.Deployment{} },
// NewListFunc returns an object capable of storing results of an etcd list. NewListFunc: func() runtime.Object { return &extensions.DeploymentList{} },
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)
},
// Retrieve the name field of a deployment.
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*extensions.Deployment).Name, nil return obj.(*extensions.Deployment).Name, nil
}, },
// Used to match objects based on labels/fields for list.
PredicateFunc: deployment.MatchDeployment, PredicateFunc: deployment.MatchDeployment,
QualifiedResource: extensions.Resource("deployments"), QualifiedResource: extensions.Resource("deployments"),
EnableGarbageCollection: opts.EnableGarbageCollection,
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
// Used to validate deployment creation.
CreateStrategy: deployment.Strategy, CreateStrategy: deployment.Strategy,
// Used to validate deployment updates.
UpdateStrategy: deployment.Strategy, UpdateStrategy: deployment.Strategy,
DeleteStrategy: deployment.Strategy, DeleteStrategy: deployment.Strategy,
Storage: storageInterface,
DestroyFunc: dFunc,
} }
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: deployment.GetAttrs}
if err := store.CompleteWithOptions(options); err != nil {
panic(err) // TODO: Propagate error up
}
statusStore := *store statusStore := *store
statusStore.UpdateStrategy = deployment.StatusStrategy statusStore.UpdateStrategy = deployment.StatusStrategy
return &REST{store}, &StatusREST{store: &statusStore}, &RollbackREST{store: store} return &REST{store}, &StatusREST{store: &statusStore}, &RollbackREST{store: store}

Some files were not shown because too many files have changed in this diff Show More