Commit 949440b4 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #43698 from sttts/sttts-non-global-admission-plugin-registry

Automatic merge from submit-queue Non global admission plugin registry For testing the global state is a problem. This PR turns the actual registry into a struct that must be instantiated. For the beginning, we do this in `pkg/kubeapiserver/admission`. In some follow-up (where we hunt down all globals some day), we will move this into the genericapiserver.
parents 9db7953c 63f547e1
......@@ -19,6 +19,7 @@ go_library(
"//pkg/api:go_default_library",
"//pkg/api/validation:go_default_library",
"//pkg/features:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//pkg/kubeapiserver/options:go_default_library",
"//pkg/kubelet/client:go_default_library",
"//pkg/master/ports:go_default_library",
......
......@@ -26,6 +26,7 @@ import (
"k8s.io/apiserver/pkg/storage/storagebackend"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/validation"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
"k8s.io/kubernetes/pkg/master/ports"
......@@ -71,7 +72,7 @@ type ServerRunOptions struct {
// NewServerRunOptions creates a new ServerRunOptions object with default parameters
func NewServerRunOptions() *ServerRunOptions {
s := ServerRunOptions{
GenericServerRunOptions: genericoptions.NewServerRunOptions(),
GenericServerRunOptions: genericoptions.NewServerRunOptions(&kubeapiserveradmission.Plugins),
Etcd: genericoptions.NewEtcdOptions(storagebackend.NewDefaultConfig(kubeoptions.DefaultEtcdPathPrefix, api.Scheme, nil)),
SecureServing: kubeoptions.NewSecureServingOptions(),
InsecureServing: kubeoptions.NewInsecureServingOptions(),
......
......@@ -64,7 +64,7 @@ import (
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi"
"k8s.io/kubernetes/pkg/kubeapiserver"
kubeadmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator"
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
......@@ -359,7 +359,12 @@ func BuildGenericConfig(s *options.ServerRunOptions) (*genericapiserver.Config,
genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName)
}
genericConfig.AdmissionControl, err = BuildAdmission(s, client, sharedInformers, genericConfig.Authorizer)
genericConfig.AdmissionControl, err = BuildAdmission(s,
s.GenericServerRunOptions.AdmissionPlugins,
client,
sharedInformers,
genericConfig.Authorizer,
)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to initialize admission: %v", err)
}
......@@ -368,7 +373,7 @@ func BuildGenericConfig(s *options.ServerRunOptions) (*genericapiserver.Config,
}
// BuildAdmission constructs the admission chain
func BuildAdmission(s *options.ServerRunOptions, client internalclientset.Interface, sharedInformers informers.SharedInformerFactory, apiAuthorizer authorizer.Authorizer) (admission.Interface, error) {
func BuildAdmission(s *options.ServerRunOptions, plugins *admission.Plugins, client internalclientset.Interface, sharedInformers informers.SharedInformerFactory, apiAuthorizer authorizer.Authorizer) (admission.Interface, error) {
admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",")
var cloudConfig []byte
var err error
......@@ -379,12 +384,12 @@ func BuildAdmission(s *options.ServerRunOptions, client internalclientset.Interf
glog.Fatalf("Error reading from cloud configuration file %s: %#v", s.CloudProvider.CloudConfigFile, err)
}
}
pluginInitializer := kubeadmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer, cloudConfig)
pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer, cloudConfig)
admissionConfigProvider, err := admission.ReadAdmissionConfiguration(admissionControlPluginNames, s.GenericServerRunOptions.AdmissionControlConfigFile)
if err != nil {
return nil, fmt.Errorf("failed to read plugin config: %v", err)
}
return admission.NewFromPlugins(admissionControlPluginNames, admissionConfigProvider, pluginInitializer)
return plugins.NewFromPlugins(admissionControlPluginNames, admissionConfigProvider, pluginInitializer)
}
// BuildAuthenticator constructs the authenticator
......
......@@ -17,6 +17,7 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//pkg/features:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//pkg/kubeapiserver/options:go_default_library",
"//vendor:github.com/spf13/pflag",
"//vendor:k8s.io/apiserver/pkg/server/options",
......
......@@ -23,6 +23,7 @@ import (
genericoptions "k8s.io/apiserver/pkg/server/options"
"k8s.io/apiserver/pkg/storage/storagebackend"
"k8s.io/kubernetes/pkg/api"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
// add the kubernetes feature gates
......@@ -51,7 +52,7 @@ type ServerRunOptions struct {
// NewServerRunOptions creates a new ServerRunOptions object with default values.
func NewServerRunOptions() *ServerRunOptions {
s := ServerRunOptions{
GenericServerRunOptions: genericoptions.NewServerRunOptions(),
GenericServerRunOptions: genericoptions.NewServerRunOptions(&kubeapiserveradmission.Plugins),
Etcd: genericoptions.NewEtcdOptions(storagebackend.NewDefaultConfig(kubeoptions.DefaultEtcdPathPrefix, api.Scheme, nil)),
SecureServing: kubeoptions.NewSecureServingOptions(),
InsecureServing: kubeoptions.NewInsecureServingOptions(),
......
......@@ -199,7 +199,7 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
if err != nil {
return fmt.Errorf("failed to read plugin config: %v", err)
}
admissionController, err := admission.NewFromPlugins(admissionControlPluginNames, admissionConfigProvider, pluginInitializer)
admissionController, err := kubeapiserveradmission.Plugins.NewFromPlugins(admissionControlPluginNames, admissionConfigProvider, pluginInitializer)
if err != nil {
return fmt.Errorf("failed to initialize plugins: %v", err)
}
......
......@@ -21,7 +21,10 @@ go_test(
go_library(
name = "go_default_library",
srcs = ["initializer.go"],
srcs = [
"initializer.go",
"registry.go",
],
tags = ["automanaged"],
deps = [
"//pkg/client/clientset_generated/internalclientset:go_default_library",
......
/*
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 admission
import (
"k8s.io/apiserver/pkg/admission"
)
// Plugins is a global registry for admission plugins.
var Plugins = admission.Plugins{}
......@@ -12,7 +12,10 @@ go_library(
name = "go_default_library",
srcs = ["admission.go"],
tags = ["automanaged"],
deps = ["//vendor:k8s.io/apiserver/pkg/admission"],
deps = [
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apiserver/pkg/admission",
],
)
go_test(
......
......@@ -20,10 +20,11 @@ import (
"io"
"k8s.io/apiserver/pkg/admission"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
func init() {
admission.RegisterPlugin("AlwaysAdmit", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("AlwaysAdmit", func(config io.Reader) (admission.Interface, error) {
return NewAlwaysAdmit(), nil
})
}
......
......@@ -14,6 +14,7 @@ go_library(
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apiserver/pkg/admission",
],
......
......@@ -30,10 +30,11 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apiserver/pkg/admission"
"k8s.io/kubernetes/pkg/api"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
func init() {
admission.RegisterPlugin("AlwaysPullImages", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("AlwaysPullImages", func(config io.Reader) (admission.Interface, error) {
return NewAlwaysPullImages(), nil
})
}
......
......@@ -17,6 +17,7 @@ go_library(
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apiserver/pkg/admission",
......
......@@ -24,10 +24,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission"
"k8s.io/kubernetes/pkg/api"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
func init() {
admission.RegisterPlugin("LimitPodHardAntiAffinityTopology", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("LimitPodHardAntiAffinityTopology", func(config io.Reader) (admission.Interface, error) {
return NewInterPodAntiAffinity(), nil
})
}
......
......@@ -28,6 +28,7 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//pkg/api/helper:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apiserver/pkg/admission",
......
......@@ -26,6 +26,7 @@ import (
"k8s.io/apiserver/pkg/admission"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/helper"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
var (
......@@ -39,7 +40,7 @@ var (
)
func init() {
admission.RegisterPlugin("DefaultTolerationSeconds", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("DefaultTolerationSeconds", func(config io.Reader) (admission.Interface, error) {
return NewDefaultTolerationSeconds(), nil
})
}
......
......@@ -12,7 +12,10 @@ go_library(
name = "go_default_library",
srcs = ["admission.go"],
tags = ["automanaged"],
deps = ["//vendor:k8s.io/apiserver/pkg/admission"],
deps = [
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apiserver/pkg/admission",
],
)
go_test(
......
......@@ -21,10 +21,11 @@ import (
"io"
"k8s.io/apiserver/pkg/admission"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
func init() {
admission.RegisterPlugin("AlwaysDeny", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("AlwaysDeny", func(config io.Reader) (admission.Interface, error) {
return NewAlwaysDeny(), nil
})
}
......
......@@ -30,13 +30,13 @@ import (
)
func init() {
admission.RegisterPlugin("DenyEscalatingExec", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("DenyEscalatingExec", func(config io.Reader) (admission.Interface, error) {
return NewDenyEscalatingExec(), nil
})
// This is for legacy support of the DenyExecOnPrivileged admission controller. Most
// of the time DenyEscalatingExec should be preferred.
admission.RegisterPlugin("DenyExecOnPrivileged", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("DenyExecOnPrivileged", func(config io.Reader) (admission.Interface, error) {
return NewDenyExecOnPrivileged(), nil
})
}
......
......@@ -13,6 +13,7 @@ go_library(
srcs = ["gc_admission.go"],
tags = ["automanaged"],
deps = [
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/equality",
"//vendor:k8s.io/apimachinery/pkg/api/meta",
"//vendor:k8s.io/apimachinery/pkg/runtime",
......
......@@ -25,10 +25,11 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authorization/authorizer"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
func init() {
admission.RegisterPlugin("OwnerReferencesPermissionEnforcement", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("OwnerReferencesPermissionEnforcement", func(config io.Reader) (admission.Interface, error) {
return &gcPermissionsEnforcement{
Handler: admission.NewHandler(admission.Create, admission.Update),
}, nil
......
......@@ -20,6 +20,7 @@ go_library(
"//pkg/api:go_default_library",
"//pkg/apis/imagepolicy/install:go_default_library",
"//pkg/apis/imagepolicy/v1alpha1:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
......
......@@ -39,6 +39,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/imagepolicy/v1alpha1"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
// install the clientgo image policy API for use with api registry
_ "k8s.io/kubernetes/pkg/apis/imagepolicy/install"
......@@ -49,7 +50,7 @@ var (
)
func init() {
admission.RegisterPlugin("ImagePolicyWebhook", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("ImagePolicyWebhook", func(config io.Reader) (admission.Interface, error) {
newImagePolicyWebhook, err := NewImagePolicyWebhook(config)
if err != nil {
return nil, err
......
......@@ -20,6 +20,7 @@ go_library(
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:cloud.google.com/go/compute/metadata",
"//vendor:github.com/golang/glog",
"//vendor:github.com/hawkular/hawkular-client-go/metrics",
......
......@@ -29,6 +29,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apiserver/pkg/admission"
"k8s.io/kubernetes/pkg/api"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
var (
......@@ -46,7 +47,7 @@ const (
// WARNING: this feature is experimental and will definitely change.
func init() {
admission.RegisterPlugin("InitialResources", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("InitialResources", func(config io.Reader) (admission.Interface, error) {
// TODO: remove the usage of flags in favor of reading versioned configuration
s, err := newDataSource(*source)
if err != nil {
......
......@@ -44,7 +44,7 @@ const (
)
func init() {
admission.RegisterPlugin("LimitRanger", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("LimitRanger", func(config io.Reader) (admission.Interface, error) {
return NewLimitRanger(&DefaultLimitRangerActions{})
})
}
......
......@@ -31,7 +31,7 @@ import (
)
func init() {
admission.RegisterPlugin("NamespaceAutoProvision", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("NamespaceAutoProvision", func(config io.Reader) (admission.Interface, error) {
return NewProvision(), nil
})
}
......
......@@ -31,7 +31,7 @@ import (
)
func init() {
admission.RegisterPlugin("NamespaceExists", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("NamespaceExists", func(config io.Reader) (admission.Interface, error) {
return NewExists(), nil
})
}
......
......@@ -51,7 +51,7 @@ const (
)
func init() {
admission.RegisterPlugin(PluginName, func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) {
return NewLifecycle(sets.NewString(metav1.NamespaceDefault, metav1.NamespaceSystem, metav1.NamespacePublic))
})
}
......
......@@ -33,7 +33,7 @@ import (
)
func init() {
admission.RegisterPlugin("PersistentVolumeLabel", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("PersistentVolumeLabel", func(config io.Reader) (admission.Interface, error) {
persistentVolumeLabelAdmission := NewPersistentVolumeLabel()
return persistentVolumeLabelAdmission, nil
})
......
......@@ -40,7 +40,7 @@ import (
var NamespaceNodeSelectors = []string{"scheduler.alpha.kubernetes.io/node-selector"}
func init() {
admission.RegisterPlugin("PodNodeSelector", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("PodNodeSelector", func(config io.Reader) (admission.Interface, error) {
// TODO move this to a versioned configuration file format.
pluginConfig := readConfig(config)
plugin := NewPodNodeSelector(pluginConfig.PodNodeSelectorPluginConfig)
......
......@@ -41,7 +41,7 @@ const (
)
func init() {
admission.RegisterPlugin(pluginName, func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register(pluginName, func(config io.Reader) (admission.Interface, error) {
return NewPlugin(), nil
})
}
......
......@@ -37,7 +37,7 @@ import (
)
func init() {
admission.RegisterPlugin("PodTolerationRestriction", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("PodTolerationRestriction", func(config io.Reader) (admission.Interface, error) {
pluginConfig, err := loadConfiguration(config)
if err != nil {
return nil, err
......
......@@ -33,7 +33,7 @@ import (
)
func init() {
admission.RegisterPlugin("ResourceQuota",
kubeapiserveradmission.Plugins.Register("ResourceQuota",
func(config io.Reader) (admission.Interface, error) {
// load the configuration provided (if any)
configuration, err := LoadConfiguration(config)
......
......@@ -45,7 +45,7 @@ const (
)
func init() {
admission.RegisterPlugin(PluginName, func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) {
plugin := NewPlugin(psp.NewSimpleStrategyFactory(), getMatchingPolicies, true)
return plugin, nil
})
......
......@@ -14,6 +14,7 @@ go_library(
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apiserver/pkg/admission",
],
......
......@@ -23,10 +23,11 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apiserver/pkg/admission"
"k8s.io/kubernetes/pkg/api"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
func init() {
admission.RegisterPlugin("SecurityContextDeny", func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register("SecurityContextDeny", func(config io.Reader) (admission.Interface, error) {
return NewSecurityContextDeny(), nil
})
}
......
......@@ -55,7 +55,7 @@ const DefaultAPITokenMountPath = "/var/run/secrets/kubernetes.io/serviceaccount"
const PluginName = "ServiceAccount"
func init() {
admission.RegisterPlugin(PluginName, func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) {
serviceAccountAdmission := NewServiceAccount()
return serviceAccountAdmission, nil
})
......
......@@ -39,7 +39,7 @@ const (
)
func init() {
admission.RegisterPlugin(PluginName, func(config io.Reader) (admission.Interface, error) {
kubeapiserveradmission.Plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) {
plugin := newPlugin()
return plugin, nil
})
......
......@@ -34,11 +34,13 @@ import (
// the parameter is nil.
type Factory func(config io.Reader) (Interface, error)
type Plugins struct {
lock sync.Mutex
registry map[string]Factory
}
// All registered admission options.
var (
pluginsMutex sync.Mutex
plugins = make(map[string]Factory)
// PluginEnabledFn checks whether a plugin is enabled. By default, if you ask about it, it's enabled.
PluginEnabledFn = func(name string, config io.Reader) bool {
return true
......@@ -48,39 +50,42 @@ var (
// PluginEnabledFunc is a function type that can provide an external check on whether an admission plugin may be enabled
type PluginEnabledFunc func(name string, config io.Reader) bool
// GetPlugins enumerates the names of all registered plugins.
func GetPlugins() []string {
pluginsMutex.Lock()
defer pluginsMutex.Unlock()
// Registered enumerates the names of all registered plugins.
func (ps *Plugins) Registered() []string {
ps.lock.Lock()
defer ps.lock.Unlock()
keys := []string{}
for k := range plugins {
for k := range ps.registry {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}
// RegisterPlugin registers a plugin Factory by name. This
// Register registers a plugin Factory by name. This
// is expected to happen during app startup.
func RegisterPlugin(name string, plugin Factory) {
pluginsMutex.Lock()
defer pluginsMutex.Unlock()
_, found := plugins[name]
func (ps *Plugins) Register(name string, plugin Factory) {
ps.lock.Lock()
defer ps.lock.Unlock()
_, found := ps.registry[name]
if found {
glog.Fatalf("Admission plugin %q was registered twice", name)
}
if ps.registry == nil {
ps.registry = map[string]Factory{}
}
glog.V(1).Infof("Registered admission plugin %q", name)
plugins[name] = plugin
ps.registry[name] = plugin
}
// getPlugin creates an instance of the named plugin. It returns `false` if the
// the name is not known. The error is returned only when the named provider was
// known but failed to initialize. The config parameter specifies the io.Reader
// handler of the configuration file for the cloud provider, or nil for no configuration.
func getPlugin(name string, config io.Reader) (Interface, bool, error) {
pluginsMutex.Lock()
defer pluginsMutex.Unlock()
f, found := plugins[name]
func (ps *Plugins) getPlugin(name string, config io.Reader) (Interface, bool, error) {
ps.lock.Lock()
defer ps.lock.Unlock()
f, found := ps.registry[name]
if !found {
return nil, false, nil
}
......@@ -113,7 +118,7 @@ func splitStream(config io.Reader) (io.Reader, io.Reader, error) {
// NewFromPlugins returns an admission.Interface that will enforce admission control decisions of all
// the given plugins.
func NewFromPlugins(pluginNames []string, configProvider ConfigProvider, pluginInitializer PluginInitializer) (Interface, error) {
func (ps *Plugins) NewFromPlugins(pluginNames []string, configProvider ConfigProvider, pluginInitializer PluginInitializer) (Interface, error) {
plugins := []Interface{}
for _, pluginName := range pluginNames {
pluginConfig, err := configProvider.ConfigFor(pluginName)
......@@ -121,7 +126,7 @@ func NewFromPlugins(pluginNames []string, configProvider ConfigProvider, pluginI
return nil, err
}
plugin, err := InitPlugin(pluginName, pluginConfig, pluginInitializer)
plugin, err := ps.InitPlugin(pluginName, pluginConfig, pluginInitializer)
if err != nil {
return nil, err
}
......@@ -133,13 +138,13 @@ func NewFromPlugins(pluginNames []string, configProvider ConfigProvider, pluginI
}
// InitPlugin creates an instance of the named interface.
func InitPlugin(name string, config io.Reader, pluginInitializer PluginInitializer) (Interface, error) {
func (ps *Plugins) InitPlugin(name string, config io.Reader, pluginInitializer PluginInitializer) (Interface, error) {
if name == "" {
glog.Info("No admission plugin specified.")
return nil, nil
}
plugin, found, err := getPlugin(name, config)
plugin, found, err := ps.getPlugin(name, config)
if err != nil {
return nil, fmt.Errorf("Couldn't init admission plugin %q: %v", name, err)
}
......
......@@ -46,16 +46,18 @@ type ServerRunOptions struct {
MinRequestTimeout int
TargetRAMMB int
WatchCacheSizes []string
AdmissionPlugins *admission.Plugins
}
func NewServerRunOptions() *ServerRunOptions {
func NewServerRunOptions(admissionPlugins *admission.Plugins) *ServerRunOptions {
defaults := server.NewConfig(serializer.CodecFactory{})
return &ServerRunOptions{
AdmissionControl: "AlwaysAdmit",
MaxRequestsInFlight: defaults.MaxRequestsInFlight,
MaxMutatingRequestsInFlight: defaults.MaxMutatingRequestsInFlight,
MinRequestTimeout: defaults.MinRequestTimeout,
AdmissionPlugins: admissionPlugins,
}
}
......@@ -96,7 +98,7 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.AdmissionControl, "admission-control", s.AdmissionControl, ""+
"Ordered list of plug-ins to do admission control of resources into cluster. "+
"Comma-delimited list of: "+strings.Join(admission.GetPlugins(), ", ")+".")
"Comma-delimited list of: "+strings.Join(s.AdmissionPlugins.Registered(), ", ")+".")
fs.StringVar(&s.AdmissionControlConfigFile, "admission-control-config-file", s.AdmissionControlConfigFile,
"File with admission control configuration.")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment