diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index dcd7d396c5f..c267c349458 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -275,7 +275,11 @@ func Run(s *options.ServerRunOptions) error { admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",") pluginInitializer := kubeadmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer) - admissionController, err := admission.NewFromPlugins(admissionControlPluginNames, s.GenericServerRunOptions.AdmissionControlConfigFile, pluginInitializer) + admissionConfigProvider, err := kubeadmission.ReadAdmissionConfiguration(admissionControlPluginNames, s.GenericServerRunOptions.AdmissionControlConfigFile) + if err != nil { + return fmt.Errorf("failed to read plugin config: %v", err) + } + admissionController, err := admission.NewFromPlugins(admissionControlPluginNames, admissionConfigProvider, pluginInitializer) if err != nil { return fmt.Errorf("failed to initialize plugins: %v", err) } diff --git a/federation/cmd/federation-apiserver/app/server.go b/federation/cmd/federation-apiserver/app/server.go index 8a3581efc44..b41c6210f49 100644 --- a/federation/cmd/federation-apiserver/app/server.go +++ b/federation/cmd/federation-apiserver/app/server.go @@ -160,7 +160,11 @@ func Run(s *options.ServerRunOptions) error { admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",") pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer) - admissionController, err := admission.NewFromPlugins(admissionControlPluginNames, s.GenericServerRunOptions.AdmissionControlConfigFile, pluginInitializer) + admissionConfigProvider, err := kubeapiserveradmission.ReadAdmissionConfiguration(admissionControlPluginNames, s.GenericServerRunOptions.AdmissionControlConfigFile) + if err != nil { + return fmt.Errorf("failed to read plugin config: %v", err) + } + admissionController, err := admission.NewFromPlugins(admissionControlPluginNames, admissionConfigProvider, pluginInitializer) if err != nil { return fmt.Errorf("failed to initialize plugins: %v", err) } diff --git a/pkg/admission/BUILD b/pkg/admission/BUILD index cf6d0f5a756..3e0e264b022 100644 --- a/pkg/admission/BUILD +++ b/pkg/admission/BUILD @@ -13,7 +13,6 @@ go_library( srcs = [ "attributes.go", "chain.go", - "config.go", "errors.go", "handler.go", "interfaces.go", @@ -21,10 +20,6 @@ go_library( ], tags = ["automanaged"], deps = [ - "//pkg/api:go_default_library", - "//pkg/apis/componentconfig:go_default_library", - "//pkg/apis/componentconfig/v1alpha1:go_default_library", - "//vendor:github.com/ghodss/yaml", "//vendor:github.com/golang/glog", "//vendor:k8s.io/apimachinery/pkg/api/errors", "//vendor:k8s.io/apimachinery/pkg/api/meta", @@ -38,17 +33,10 @@ go_library( go_test( name = "go_default_test", - srcs = [ - "chain_test.go", - "config_test.go", - ], + srcs = ["chain_test.go"], library = ":go_default_library", tags = ["automanaged"], - deps = [ - "//pkg/apis/componentconfig:go_default_library", - "//pkg/apis/componentconfig/install:go_default_library", - "//vendor:k8s.io/apimachinery/pkg/runtime/schema", - ], + deps = ["//vendor:k8s.io/apimachinery/pkg/runtime/schema"], ) filegroup( diff --git a/pkg/admission/interfaces.go b/pkg/admission/interfaces.go index 703d3c2ac0c..a8e671db514 100644 --- a/pkg/admission/interfaces.go +++ b/pkg/admission/interfaces.go @@ -17,6 +17,8 @@ limitations under the License. package admission import ( + "io" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/authentication/user" @@ -81,3 +83,8 @@ type PluginInitializer interface { type Validator interface { Validate() error } + +// ConfigProvider provides a way to get configuration for an admission plugin based on its name +type ConfigProvider interface { + ConfigFor(pluginName string) (io.Reader, error) +} diff --git a/pkg/admission/plugins.go b/pkg/admission/plugins.go index 5f557e55c2f..bb110f9ba82 100644 --- a/pkg/admission/plugins.go +++ b/pkg/admission/plugins.go @@ -113,16 +113,10 @@ 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, configFilePath string, pluginInitializer PluginInitializer) (Interface, error) { - // load config file path into a componentconfig.AdmissionConfiguration - admissionCfg, err := ReadAdmissionConfiguration(pluginNames, configFilePath) - if err != nil { - return nil, err - } - +func NewFromPlugins(pluginNames []string, configProvider ConfigProvider, pluginInitializer PluginInitializer) (Interface, error) { plugins := []Interface{} for _, pluginName := range pluginNames { - pluginConfig, err := GetAdmissionPluginConfiguration(admissionCfg, pluginName) + pluginConfig, err := configProvider.ConfigFor(pluginName) if err != nil { return nil, err } diff --git a/pkg/kubeapiserver/admission/BUILD b/pkg/kubeapiserver/admission/BUILD index 7f42213e1bb..7f427890072 100644 --- a/pkg/kubeapiserver/admission/BUILD +++ b/pkg/kubeapiserver/admission/BUILD @@ -10,23 +10,38 @@ load( go_test( name = "go_default_test", - srcs = ["init_test.go"], + srcs = [ + "config_test.go", + "init_test.go", + ], library = ":go_default_library", tags = ["automanaged"], deps = [ "//pkg/admission:go_default_library", + "//pkg/apis/componentconfig:go_default_library", + "//pkg/apis/componentconfig/install:go_default_library", "//vendor:k8s.io/apiserver/pkg/authorization/authorizer", ], ) go_library( name = "go_default_library", - srcs = ["initializer.go"], + srcs = [ + "config.go", + "initializer.go", + ], tags = ["automanaged"], deps = [ "//pkg/admission:go_default_library", + "//pkg/api:go_default_library", + "//pkg/apis/componentconfig:go_default_library", + "//pkg/apis/componentconfig/v1alpha1:go_default_library", "//pkg/client/clientset_generated/internalclientset:go_default_library", "//pkg/controller/informers:go_default_library", + "//vendor:github.com/ghodss/yaml", + "//vendor:github.com/golang/glog", + "//vendor:k8s.io/apimachinery/pkg/runtime", + "//vendor:k8s.io/apimachinery/pkg/util/sets", "//vendor:k8s.io/apiserver/pkg/authorization/authorizer", ], ) diff --git a/pkg/admission/config.go b/pkg/kubeapiserver/admission/config.go similarity index 91% rename from pkg/admission/config.go rename to pkg/kubeapiserver/admission/config.go index 3c93049a0d4..4e0cf266bed 100644 --- a/pkg/admission/config.go +++ b/pkg/kubeapiserver/admission/config.go @@ -30,6 +30,7 @@ import ( "bytes" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apis/componentconfig" componentconfigv1alpha1 "k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1" @@ -57,9 +58,9 @@ func makeAbs(path, base string) (string, error) { // set of pluginNames whose config location references the specified configFilePath. // It does this to preserve backward compatibility when admission control files were opaque. // It returns an error if the file did not exist. -func ReadAdmissionConfiguration(pluginNames []string, configFilePath string) (*componentconfig.AdmissionConfiguration, error) { +func ReadAdmissionConfiguration(pluginNames []string, configFilePath string) (admission.ConfigProvider, error) { if configFilePath == "" { - return &componentconfig.AdmissionConfiguration{}, nil + return configProvider{config: &componentconfig.AdmissionConfiguration{}}, nil } // a file was provided, so we just read it. data, err := ioutil.ReadFile(configFilePath) @@ -86,7 +87,7 @@ func ReadAdmissionConfiguration(pluginNames []string, configFilePath string) (*c } decodedConfig.Plugins[i].Path = absPath } - return decodedConfig, nil + return configProvider{config: decodedConfig}, nil } // we got an error where the decode wasn't related to a missing type if !(runtime.IsMissingVersion(err) || runtime.IsMissingKind(err) || runtime.IsNotRegisteredError(err)) { @@ -109,9 +110,13 @@ func ReadAdmissionConfiguration(pluginNames []string, configFilePath string) (*c api.Scheme.Default(externalConfig) internalConfig := &componentconfig.AdmissionConfiguration{} if err := api.Scheme.Convert(externalConfig, internalConfig, nil); err != nil { - return internalConfig, err + return nil, err } - return internalConfig, nil + return configProvider{config: internalConfig}, nil +} + +type configProvider struct { + config *componentconfig.AdmissionConfiguration } // GetAdmissionPluginConfigurationFor returns a reader that holds the admission plugin configuration. @@ -141,13 +146,13 @@ func GetAdmissionPluginConfigurationFor(pluginCfg componentconfig.AdmissionPlugi // GetAdmissionPluginConfiguration takes the admission configuration and returns a reader // for the specified plugin. If no specific configuration is present, we return a nil reader. -func GetAdmissionPluginConfiguration(cfg *componentconfig.AdmissionConfiguration, pluginName string) (io.Reader, error) { +func (p configProvider) ConfigFor(pluginName string) (io.Reader, error) { // there is no config, so there is no potential config - if cfg == nil { + if p.config == nil { return nil, nil } // look for matching plugin and get configuration - for _, pluginCfg := range cfg.Plugins { + for _, pluginCfg := range p.config.Plugins { if pluginName != pluginCfg.Name { continue } diff --git a/pkg/admission/config_test.go b/pkg/kubeapiserver/admission/config_test.go similarity index 96% rename from pkg/admission/config_test.go rename to pkg/kubeapiserver/admission/config_test.go index edccd362565..41b4f358321 100644 --- a/pkg/admission/config_test.go +++ b/pkg/kubeapiserver/admission/config_test.go @@ -141,8 +141,8 @@ func TestReadAdmissionConfiguration(t *testing.T) { if err != nil { t.Fatalf("unexpected err: %v", err) } - if !reflect.DeepEqual(config, testCase.ExpectedAdmissionConfig) { - t.Errorf("%s: Expected:\n\t%#v\nGot:\n\t%#v", testName, testCase.ExpectedAdmissionConfig, config) + if !reflect.DeepEqual(config.(configProvider).config, testCase.ExpectedAdmissionConfig) { + t.Errorf("%s: Expected:\n\t%#v\nGot:\n\t%#v", testName, testCase.ExpectedAdmissionConfig, config.(configProvider).config) } } }