remove api dependency from admission

This commit is contained in:
deads2k 2017-01-17 16:35:28 -05:00
parent fe69dcf861
commit 52ec66ee85
8 changed files with 53 additions and 36 deletions

View File

@ -275,7 +275,11 @@ func Run(s *options.ServerRunOptions) error {
admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",") admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",")
pluginInitializer := kubeadmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer) 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 { if err != nil {
return fmt.Errorf("failed to initialize plugins: %v", err) return fmt.Errorf("failed to initialize plugins: %v", err)
} }

View File

@ -160,7 +160,11 @@ func Run(s *options.ServerRunOptions) error {
admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",") admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",")
pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer) 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 { if err != nil {
return fmt.Errorf("failed to initialize plugins: %v", err) return fmt.Errorf("failed to initialize plugins: %v", err)
} }

View File

@ -13,7 +13,6 @@ go_library(
srcs = [ srcs = [
"attributes.go", "attributes.go",
"chain.go", "chain.go",
"config.go",
"errors.go", "errors.go",
"handler.go", "handler.go",
"interfaces.go", "interfaces.go",
@ -21,10 +20,6 @@ go_library(
], ],
tags = ["automanaged"], tags = ["automanaged"],
deps = [ 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:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/api/errors", "//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/api/meta", "//vendor:k8s.io/apimachinery/pkg/api/meta",
@ -38,17 +33,10 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = ["chain_test.go"],
"chain_test.go",
"config_test.go",
],
library = ":go_default_library", library = ":go_default_library",
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = ["//vendor:k8s.io/apimachinery/pkg/runtime/schema"],
"//pkg/apis/componentconfig:go_default_library",
"//pkg/apis/componentconfig/install:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
],
) )
filegroup( filegroup(

View File

@ -17,6 +17,8 @@ limitations under the License.
package admission package admission
import ( import (
"io"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
@ -81,3 +83,8 @@ type PluginInitializer interface {
type Validator interface { type Validator interface {
Validate() error 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)
}

View File

@ -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 // NewFromPlugins returns an admission.Interface that will enforce admission control decisions of all
// the given plugins. // the given plugins.
func NewFromPlugins(pluginNames []string, configFilePath string, pluginInitializer PluginInitializer) (Interface, error) { func NewFromPlugins(pluginNames []string, configProvider ConfigProvider, pluginInitializer PluginInitializer) (Interface, error) {
// load config file path into a componentconfig.AdmissionConfiguration
admissionCfg, err := ReadAdmissionConfiguration(pluginNames, configFilePath)
if err != nil {
return nil, err
}
plugins := []Interface{} plugins := []Interface{}
for _, pluginName := range pluginNames { for _, pluginName := range pluginNames {
pluginConfig, err := GetAdmissionPluginConfiguration(admissionCfg, pluginName) pluginConfig, err := configProvider.ConfigFor(pluginName)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -10,23 +10,38 @@ load(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["init_test.go"], srcs = [
"config_test.go",
"init_test.go",
],
library = ":go_default_library", library = ":go_default_library",
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/admission:go_default_library", "//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", "//vendor:k8s.io/apiserver/pkg/authorization/authorizer",
], ],
) )
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = ["initializer.go"], srcs = [
"config.go",
"initializer.go",
],
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/admission:go_default_library", "//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/client/clientset_generated/internalclientset:go_default_library",
"//pkg/controller/informers: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", "//vendor:k8s.io/apiserver/pkg/authorization/authorizer",
], ],
) )

View File

@ -30,6 +30,7 @@ import (
"bytes" "bytes"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/admission"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/componentconfig" "k8s.io/kubernetes/pkg/apis/componentconfig"
componentconfigv1alpha1 "k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1" 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. // set of pluginNames whose config location references the specified configFilePath.
// It does this to preserve backward compatibility when admission control files were opaque. // It does this to preserve backward compatibility when admission control files were opaque.
// It returns an error if the file did not exist. // 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 == "" { if configFilePath == "" {
return &componentconfig.AdmissionConfiguration{}, nil return configProvider{config: &componentconfig.AdmissionConfiguration{}}, nil
} }
// a file was provided, so we just read it. // a file was provided, so we just read it.
data, err := ioutil.ReadFile(configFilePath) data, err := ioutil.ReadFile(configFilePath)
@ -86,7 +87,7 @@ func ReadAdmissionConfiguration(pluginNames []string, configFilePath string) (*c
} }
decodedConfig.Plugins[i].Path = absPath 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 // we got an error where the decode wasn't related to a missing type
if !(runtime.IsMissingVersion(err) || runtime.IsMissingKind(err) || runtime.IsNotRegisteredError(err)) { 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) api.Scheme.Default(externalConfig)
internalConfig := &componentconfig.AdmissionConfiguration{} internalConfig := &componentconfig.AdmissionConfiguration{}
if err := api.Scheme.Convert(externalConfig, internalConfig, nil); err != nil { 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. // 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 // GetAdmissionPluginConfiguration takes the admission configuration and returns a reader
// for the specified plugin. If no specific configuration is present, we return a nil 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 // there is no config, so there is no potential config
if cfg == nil { if p.config == nil {
return nil, nil return nil, nil
} }
// look for matching plugin and get configuration // look for matching plugin and get configuration
for _, pluginCfg := range cfg.Plugins { for _, pluginCfg := range p.config.Plugins {
if pluginName != pluginCfg.Name { if pluginName != pluginCfg.Name {
continue continue
} }

View File

@ -141,8 +141,8 @@ func TestReadAdmissionConfiguration(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected err: %v", err) t.Fatalf("unexpected err: %v", err)
} }
if !reflect.DeepEqual(config, testCase.ExpectedAdmissionConfig) { if !reflect.DeepEqual(config.(configProvider).config, testCase.ExpectedAdmissionConfig) {
t.Errorf("%s: Expected:\n\t%#v\nGot:\n\t%#v", testName, testCase.ExpectedAdmissionConfig, config) t.Errorf("%s: Expected:\n\t%#v\nGot:\n\t%#v", testName, testCase.ExpectedAdmissionConfig, config.(configProvider).config)
} }
} }
} }