mirror of https://github.com/k3s-io/k3s
Merge pull request #29557 from deads2k/make-prefx-configurable
Automatic merge from submit-queue make the resource prefix in etcd configurable for cohabitation This looks big, its not as bad as it seems. When you have different resources cohabiting, the resource name used for the etcd directory needs to be configurable. HPA in two different groups worked fine before. Now we're looking at something like RC<->RS. They normally store into two different etcd directories. This code allows them to be configured to store into the same location. To maintain consistency across all resources, I allowed the `StorageFactory` to indicate which `ResourcePrefix` should be used inside `RESTOptions` which already contains storage information. @lavalamp affects cohabitation. @smarterclayton @mfojtik prereq for our rc<->rs and d<->dc story.pull/6/head
commit
2817674715
|
@ -38,6 +38,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
"k8s.io/kubernetes/pkg/apiserver"
|
||||
"k8s.io/kubernetes/pkg/apiserver/authenticator"
|
||||
"k8s.io/kubernetes/pkg/capabilities"
|
||||
|
@ -185,7 +186,7 @@ func Run(s *options.APIServer) error {
|
|||
if err != nil {
|
||||
glog.Fatalf("Unable to get serviceaccounts storage: %v", err)
|
||||
}
|
||||
serviceAccountGetter = serviceaccountcontroller.NewGetterFromStorageInterface(storage)
|
||||
serviceAccountGetter = serviceaccountcontroller.NewGetterFromStorageInterface(storage, storageFactory.ResourcePrefix(api.Resource("serviceaccounts")), storageFactory.ResourcePrefix(api.Resource("secrets")))
|
||||
}
|
||||
|
||||
authenticator, err := authenticator.New(authenticator.AuthenticatorConfig{
|
||||
|
@ -222,11 +223,11 @@ func Run(s *options.APIServer) error {
|
|||
|
||||
if modeEnabled(apiserver.ModeRBAC) {
|
||||
mustGetRESTOptions := func(resource string) generic.RESTOptions {
|
||||
s, err := storageFactory.New(api.Resource(resource))
|
||||
s, err := storageFactory.New(rbac.Resource(resource))
|
||||
if err != nil {
|
||||
glog.Fatalf("Unable to get %s storage: %v", resource, err)
|
||||
}
|
||||
return generic.RESTOptions{Storage: s, Decorator: generic.UndecoratedStorage}
|
||||
return generic.RESTOptions{Storage: s, Decorator: generic.UndecoratedStorage, ResourcePrefix: storageFactory.ResourcePrefix(rbac.Resource(resource))}
|
||||
}
|
||||
|
||||
// For initial bootstrapping go directly to etcd to avoid privillege escalation check.
|
||||
|
|
|
@ -168,5 +168,6 @@ func createRESTOptionsOrDie(s *genericoptions.ServerRunOptions, g *genericapiser
|
|||
Storage: storage,
|
||||
Decorator: g.StorageDecorator(),
|
||||
DeleteCollectionWorkers: s.DeleteCollectionWorkers,
|
||||
ResourcePrefix: f.ResourcePrefix(resource),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,9 +69,9 @@ func (r *registryGetter) GetSecret(namespace, name string) (*api.Secret, error)
|
|||
|
||||
// NewGetterFromStorageInterface returns a ServiceAccountTokenGetter that
|
||||
// uses the specified storage to retrieve service accounts and secrets.
|
||||
func NewGetterFromStorageInterface(s storage.Interface) serviceaccount.ServiceAccountTokenGetter {
|
||||
func NewGetterFromStorageInterface(s storage.Interface, saPrefix, secretPrefix string) serviceaccount.ServiceAccountTokenGetter {
|
||||
return NewGetterFromRegistries(
|
||||
serviceaccountregistry.NewRegistry(serviceaccountetcd.NewREST(generic.RESTOptions{Storage: s, Decorator: generic.UndecoratedStorage})),
|
||||
secret.NewRegistry(secretetcd.NewREST(generic.RESTOptions{Storage: s, Decorator: generic.UndecoratedStorage})),
|
||||
serviceaccountregistry.NewRegistry(serviceaccountetcd.NewREST(generic.RESTOptions{Storage: s, Decorator: generic.UndecoratedStorage, ResourcePrefix: saPrefix})),
|
||||
secret.NewRegistry(secretetcd.NewREST(generic.RESTOptions{Storage: s, Decorator: generic.UndecoratedStorage, ResourcePrefix: secretPrefix})),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package genericapiserver
|
|||
import (
|
||||
"fmt"
|
||||
"mime"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
|
@ -37,6 +38,12 @@ type StorageFactory interface {
|
|||
// New finds the storage destination for the given group and resource. It will
|
||||
// return an error if the group has no storage destination configured.
|
||||
New(groupResource unversioned.GroupResource) (storage.Interface, error)
|
||||
|
||||
// ResourcePrefix returns the overridden resource prefix for the GroupResource
|
||||
// This allows for cohabitation of resources with different native types and provides
|
||||
// centralized control over the shape of etcd directories
|
||||
ResourcePrefix(groupResource unversioned.GroupResource) string
|
||||
|
||||
// Backends gets all backends for all registered storage destinations.
|
||||
// Used for getting all instances for health validations.
|
||||
Backends() []string
|
||||
|
@ -78,8 +85,12 @@ type groupResourceOverrides struct {
|
|||
// etcdLocation contains the list of "special" locations that are used for particular GroupResources
|
||||
// These are merged on top of the StorageConfig when requesting the storage.Interface for a given GroupResource
|
||||
etcdLocation []string
|
||||
// etcdPrefix contains the list of "special" prefixes for a GroupResource. Resource=* means for the entire group
|
||||
// etcdPrefix is the base location for a GroupResource.
|
||||
etcdPrefix string
|
||||
// etcdResourcePrefix is the location to use to store a particular type under the `etcdPrefix` location
|
||||
// If empty, the default mapping is used. If the default mapping doesn't contain an entry, it will use
|
||||
// the ToLowered name of the resource, not including the group.
|
||||
etcdResourcePrefix string
|
||||
// mediaType is the desired serializer to choose. If empty, the default is chosen.
|
||||
mediaType string
|
||||
// serializer contains the list of "special" serializers for a GroupResource. Resource=* means for the entire group
|
||||
|
@ -123,6 +134,13 @@ func (s *DefaultStorageFactory) SetEtcdPrefix(groupResource unversioned.GroupRes
|
|||
s.Overrides[groupResource] = overrides
|
||||
}
|
||||
|
||||
// SetResourceEtcdPrefix sets the prefix for a resource, but not the base-dir. You'll end up in `etcdPrefix/resourceEtcdPrefix`.
|
||||
func (s *DefaultStorageFactory) SetResourceEtcdPrefix(groupResource unversioned.GroupResource, prefix string) {
|
||||
overrides := s.Overrides[groupResource]
|
||||
overrides.etcdResourcePrefix = prefix
|
||||
s.Overrides[groupResource] = overrides
|
||||
}
|
||||
|
||||
func (s *DefaultStorageFactory) SetSerializer(groupResource unversioned.GroupResource, mediaType string, serializer runtime.StorageSerializer) {
|
||||
overrides := s.Overrides[groupResource]
|
||||
overrides.mediaType = mediaType
|
||||
|
@ -268,3 +286,30 @@ func NewStorageCodec(storageMediaType string, ns runtime.StorageSerializer, stor
|
|||
}
|
||||
return runtime.NewCodec(encoder, decoder), nil
|
||||
}
|
||||
|
||||
var specialDefaultResourcePrefixes = map[unversioned.GroupResource]string{
|
||||
unversioned.GroupResource{Group: "", Resource: "replicationControllers"}: "controllers",
|
||||
unversioned.GroupResource{Group: "", Resource: "replicationcontrollers"}: "controllers",
|
||||
unversioned.GroupResource{Group: "", Resource: "endpoints"}: "services/endpoints",
|
||||
unversioned.GroupResource{Group: "", Resource: "nodes"}: "minions",
|
||||
unversioned.GroupResource{Group: "", Resource: "services"}: "services/specs",
|
||||
}
|
||||
|
||||
func (s *DefaultStorageFactory) ResourcePrefix(groupResource unversioned.GroupResource) string {
|
||||
chosenStorageResource := s.getStorageGroupResource(groupResource)
|
||||
groupOverride := s.Overrides[getAllResourcesAlias(chosenStorageResource)]
|
||||
exactResourceOverride := s.Overrides[chosenStorageResource]
|
||||
|
||||
etcdResourcePrefix := specialDefaultResourcePrefixes[chosenStorageResource]
|
||||
if len(groupOverride.etcdResourcePrefix) > 0 {
|
||||
etcdResourcePrefix = groupOverride.etcdResourcePrefix
|
||||
}
|
||||
if len(exactResourceOverride.etcdResourcePrefix) > 0 {
|
||||
etcdResourcePrefix = exactResourceOverride.etcdResourcePrefix
|
||||
}
|
||||
if len(etcdResourcePrefix) == 0 {
|
||||
etcdResourcePrefix = strings.ToLower(chosenStorageResource.Resource)
|
||||
}
|
||||
|
||||
return etcdResourcePrefix
|
||||
}
|
||||
|
|
|
@ -731,6 +731,7 @@ func (m *Master) GetRESTOptionsOrDie(c *Config, resource unversioned.GroupResour
|
|||
Storage: storage,
|
||||
Decorator: m.StorageDecorator(),
|
||||
DeleteCollectionWorkers: m.deleteCollectionWorkers,
|
||||
ResourcePrefix: c.StorageFactory.ResourcePrefix(resource),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against ClusterRole objects.
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/clusterroles"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &rbac.ClusterRoleList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -34,7 +34,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against ClusterRoleBinding objects.
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/clusterrolebindings"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &rbac.ClusterRoleBindingList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -32,7 +32,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work with ConfigMap objects.
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/configmaps"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.ConfigMapList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -59,7 +59,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against replication controllers.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/controllers"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.ReplicationControllerList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -35,7 +35,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against DaemonSets.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/daemonsets"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &extensions.DaemonSetList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -59,7 +59,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against deployments.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST, *RollbackREST) {
|
||||
prefix := "/deployments"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &extensions.DeploymentList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -41,7 +41,7 @@ const defaultReplicas = 100
|
|||
|
||||
func newStorage(t *testing.T) (*DeploymentStorage, *etcdtesting.EtcdTestServer) {
|
||||
etcdStorage, server := registrytest.NewEtcdStorage(t, extensions.GroupName)
|
||||
restOptions := generic.RESTOptions{Storage: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1}
|
||||
restOptions := generic.RESTOptions{Storage: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1, ResourcePrefix: "deployments"}
|
||||
deploymentStorage := NewStorage(restOptions)
|
||||
return &deploymentStorage, server
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against endpoints.
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/services/endpoints"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.EndpointsList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -30,7 +30,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against events.
|
||||
func NewREST(opts generic.RESTOptions, ttl uint64) *REST {
|
||||
prefix := "/events"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
// We explicitly do NOT do any decoration here - switching on Cacher
|
||||
// for events will lead to too high memory consumption.
|
||||
|
|
|
@ -32,7 +32,7 @@ import (
|
|||
|
||||
func newStorage(t *testing.T) (*ScaleREST, *etcdtesting.EtcdTestServer, storage.Interface) {
|
||||
etcdStorage, server := registrytest.NewEtcdStorage(t, "")
|
||||
restOptions := generic.RESTOptions{Storage: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1}
|
||||
restOptions := generic.RESTOptions{Storage: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1, ResourcePrefix: "controllers"}
|
||||
return NewStorage(restOptions).Scale, server, etcdStorage
|
||||
}
|
||||
|
||||
|
|
|
@ -25,4 +25,6 @@ type RESTOptions struct {
|
|||
Storage pkgstorage.Interface
|
||||
Decorator StorageDecorator
|
||||
DeleteCollectionWorkers int
|
||||
|
||||
ResourcePrefix string
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against horizontal pod autoscalers.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/horizontalpodautoscalers"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &autoscaling.HorizontalPodAutoscalerList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -35,7 +35,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against replication controllers.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/ingress"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &extensions.IngressList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -35,7 +35,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against Jobs.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/jobs"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &batch.JobList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -32,7 +32,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against horizontal pod autoscalers.
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/limitranges"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.LimitRangeList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -50,7 +50,7 @@ type FinalizeREST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against namespaces.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST, *FinalizeREST) {
|
||||
prefix := "/namespaces"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.NamespaceList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -31,7 +31,7 @@ import (
|
|||
|
||||
func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
|
||||
etcdStorage, server := registrytest.NewEtcdStorage(t, "")
|
||||
restOptions := generic.RESTOptions{Storage: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1}
|
||||
restOptions := generic.RESTOptions{Storage: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1, ResourcePrefix: "namespaces"}
|
||||
namespaceStorage, _, _ := NewREST(restOptions)
|
||||
return namespaceStorage, server
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against network policies.
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/networkpolicies"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &extensionsapi.NetworkPolicyList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -66,7 +66,7 @@ func (r *StatusREST) Update(ctx api.Context, name string, objInfo rest.UpdatedOb
|
|||
|
||||
// NewStorage returns a NodeStorage object that will work against nodes.
|
||||
func NewStorage(opts generic.RESTOptions, connection client.ConnectionInfoGetter, proxyTransport http.RoundTripper) NodeStorage {
|
||||
prefix := "/minions"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.NodeList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -33,7 +33,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against persistent volumes.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/persistentvolumes"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.PersistentVolumeList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -33,7 +33,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against persistent volume claims.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/persistentvolumeclaims"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.PersistentVolumeClaimList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -35,7 +35,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against replication controllers.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/petsets"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &appsapi.PetSetList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -33,7 +33,7 @@ import (
|
|||
|
||||
func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
|
||||
etcdStorage, server := registrytest.NewEtcdStorage(t, apps.GroupName)
|
||||
restOptions := generic.RESTOptions{Storage: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1}
|
||||
restOptions := generic.RESTOptions{Storage: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1, ResourcePrefix: "petsets"}
|
||||
petSetStorage, statusStorage := NewREST(restOptions)
|
||||
return petSetStorage, statusStorage, server
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ type REST struct {
|
|||
|
||||
// NewStorage returns a RESTStorage object that will work against pods.
|
||||
func NewStorage(opts generic.RESTOptions, k client.ConnectionInfoGetter, proxyTransport http.RoundTripper) PodStorage {
|
||||
prefix := "/pods"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.PodList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -35,7 +35,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against pod disruption budgets.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/poddisruptionbudgets"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &policyapi.PodDisruptionBudgetList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -34,7 +34,7 @@ import (
|
|||
|
||||
func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
|
||||
etcdStorage, server := registrytest.NewEtcdStorage(t, policy.GroupName)
|
||||
restOptions := generic.RESTOptions{Storage: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1}
|
||||
restOptions := generic.RESTOptions{Storage: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1, ResourcePrefix: "poddisruptionbudgets"}
|
||||
podDisruptionBudgetStorage, statusStorage := NewREST(restOptions)
|
||||
return podDisruptionBudgetStorage, statusStorage, server
|
||||
}
|
||||
|
|
|
@ -31,16 +31,16 @@ type REST struct {
|
|||
*registry.Store
|
||||
}
|
||||
|
||||
const Prefix = "/podsecuritypolicies"
|
||||
|
||||
// NewREST returns a RESTStorage object that will work against PodSecurityPolicy objects.
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &extensions.PodSecurityPolicyList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
opts.Storage,
|
||||
100,
|
||||
&extensions.PodSecurityPolicy{},
|
||||
Prefix,
|
||||
prefix,
|
||||
podsecuritypolicy.Strategy,
|
||||
newListFunc,
|
||||
storage.NoTriggerPublisher,
|
||||
|
@ -50,10 +50,10 @@ func NewREST(opts generic.RESTOptions) *REST {
|
|||
NewFunc: func() runtime.Object { return &extensions.PodSecurityPolicy{} },
|
||||
NewListFunc: newListFunc,
|
||||
KeyRootFunc: func(ctx api.Context) string {
|
||||
return Prefix
|
||||
return prefix
|
||||
},
|
||||
KeyFunc: func(ctx api.Context, name string) (string, error) {
|
||||
return registry.NoNamespaceKeyFunc(ctx, Prefix, name)
|
||||
return registry.NoNamespaceKeyFunc(ctx, prefix, name)
|
||||
},
|
||||
ObjectNameFunc: func(obj runtime.Object) (string, error) {
|
||||
return obj.(*extensions.PodSecurityPolicy).Name, nil
|
||||
|
|
|
@ -32,7 +32,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against pod templates.
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/podtemplates"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.PodTemplateList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -58,7 +58,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against ReplicaSet.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/replicasets"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &extensions.ReplicaSetList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -38,7 +38,7 @@ const defaultReplicas = 100
|
|||
|
||||
func newStorage(t *testing.T) (*ReplicaSetStorage, *etcdtesting.EtcdTestServer) {
|
||||
etcdStorage, server := registrytest.NewEtcdStorage(t, "extensions")
|
||||
restOptions := generic.RESTOptions{Storage: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1}
|
||||
restOptions := generic.RESTOptions{Storage: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1, ResourcePrefix: "replicasets"}
|
||||
replicaSetStorage := NewStorage(restOptions)
|
||||
return &replicaSetStorage, server
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against resource quotas.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/resourcequotas"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.ResourceQuotaList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -34,7 +34,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against Role objects.
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/roles"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &rbac.RoleList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -34,7 +34,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against RoleBinding objects.
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/rolebindings"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &rbac.RoleBindingList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -35,7 +35,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against ScheduledJobs.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/scheduledjobs"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &batch.ScheduledJobList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -32,7 +32,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against secrets.
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/secrets"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.SecretList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -33,7 +33,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against services.
|
||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/services/specs"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.ServiceList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -32,7 +32,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a RESTStorage object that will work against service accounts.
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/serviceaccounts"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
newListFunc := func() runtime.Object { return &api.ServiceAccountList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
|
|
|
@ -32,7 +32,7 @@ type REST struct {
|
|||
|
||||
// NewREST returns a registry which will store ThirdPartyResource in the given helper
|
||||
func NewREST(opts generic.RESTOptions) *REST {
|
||||
prefix := "/thirdpartyresources"
|
||||
prefix := "/" + opts.ResourcePrefix
|
||||
|
||||
// We explicitly do NOT do any decoration here yet.
|
||||
storageInterface := opts.Storage
|
||||
|
|
|
@ -81,7 +81,7 @@ func newRBACAuthorizer(t *testing.T, superUser string, config *master.Config) au
|
|||
if err != nil {
|
||||
t.Fatalf("failed to get storage: %v", err)
|
||||
}
|
||||
return generic.RESTOptions{Storage: storageInterface, Decorator: generic.UndecoratedStorage}
|
||||
return generic.RESTOptions{Storage: storageInterface, Decorator: generic.UndecoratedStorage, ResourcePrefix: resource}
|
||||
}
|
||||
|
||||
roleRegistry := role.NewRegistry(roleetcd.NewREST(newRESTOptions("roles")))
|
||||
|
|
Loading…
Reference in New Issue