moved admission interfaces WantsClientCert, WantsAuthorizer and WantsExternalKubeClientSet to apiserver
This commit is contained in:
		| @@ -467,9 +467,28 @@ func BuildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transp | |||||||
| 		return nil, nil, nil, nil, nil, fmt.Errorf("failed to create admission plugin initializer: %v", err) | 		return nil, nil, nil, nil, nil, fmt.Errorf("failed to create admission plugin initializer: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// TODO: this is the wrong cert/key pair. | ||||||
|  | 	// Given the generic case of webhook admission from a generic apiserver, | ||||||
|  | 	// this key pair should be signed by the the API server's client CA. | ||||||
|  | 	// Read client cert/key for plugins that need to make calls out | ||||||
|  | 	certBytes, keyBytes := []byte{}, []byte{} | ||||||
|  | 	if len(s.ProxyClientCertFile) > 0 && len(s.ProxyClientKeyFile) > 0 { | ||||||
|  | 		var err error | ||||||
|  | 		certBytes, err = ioutil.ReadFile(s.ProxyClientCertFile) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, nil, nil, nil, nil, fmt.Errorf("failed to read proxy client cert file from: %s, err: %v", s.ProxyClientCertFile, err) | ||||||
|  | 		} | ||||||
|  | 		keyBytes, err = ioutil.ReadFile(s.ProxyClientKeyFile) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, nil, nil, nil, nil, fmt.Errorf("failed to read proxy client key file from: %s, err: %v", s.ProxyClientKeyFile, err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	err = s.Admission.ApplyTo( | 	err = s.Admission.ApplyTo( | ||||||
| 		genericConfig, | 		genericConfig, | ||||||
| 		versionedInformers, | 		versionedInformers, | ||||||
|  | 		certBytes, | ||||||
|  | 		keyBytes, | ||||||
| 		pluginInitializer) | 		pluginInitializer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, nil, nil, nil, nil, fmt.Errorf("failed to initialize admission: %v", err) | 		return nil, nil, nil, nil, nil, fmt.Errorf("failed to initialize admission: %v", err) | ||||||
| @@ -498,19 +517,6 @@ func BuildAdmissionPluginInitializer(s *options.ServerRunOptions, client interna | |||||||
|  |  | ||||||
| 	pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, externalClient, sharedInformers, apiAuthorizer, cloudConfig, restMapper, quotaRegistry) | 	pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, externalClient, sharedInformers, apiAuthorizer, cloudConfig, restMapper, quotaRegistry) | ||||||
|  |  | ||||||
| 	// Read client cert/key for plugins that need to make calls out |  | ||||||
| 	if len(s.ProxyClientCertFile) > 0 && len(s.ProxyClientKeyFile) > 0 { |  | ||||||
| 		certBytes, err := ioutil.ReadFile(s.ProxyClientCertFile) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		keyBytes, err := ioutil.ReadFile(s.ProxyClientKeyFile) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		pluginInitializer = pluginInitializer.SetClientCert(certBytes, keyBytes) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	pluginInitializer = pluginInitializer.SetServiceResolver(serviceResolver) | 	pluginInitializer = pluginInitializer.SetServiceResolver(serviceResolver) | ||||||
| 	pluginInitializer = pluginInitializer.SetProxyTransport(proxyTransport) | 	pluginInitializer = pluginInitializer.SetProxyTransport(proxyTransport) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -219,6 +219,8 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error { | |||||||
| 	err = s.Admission.ApplyTo( | 	err = s.Admission.ApplyTo( | ||||||
| 		genericConfig, | 		genericConfig, | ||||||
| 		versionedInformers, | 		versionedInformers, | ||||||
|  | 		nil, | ||||||
|  | 		nil, | ||||||
| 		pluginInitializer, | 		pluginInitializer, | ||||||
| 	) | 	) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ go_test( | |||||||
|     library = ":go_default_library", |     library = ":go_default_library", | ||||||
|     deps = [ |     deps = [ | ||||||
|         "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", |         "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", | ||||||
|  |         "//vendor/k8s.io/apiserver/pkg/admission/initializer:go_default_library", | ||||||
|         "//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", |         "//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
| @@ -25,6 +26,7 @@ go_library( | |||||||
|         "//pkg/quota:go_default_library", |         "//pkg/quota:go_default_library", | ||||||
|         "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", |         "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", | ||||||
|         "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", |         "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", | ||||||
|  |         "//vendor/k8s.io/apiserver/pkg/admission/initializer:go_default_library", | ||||||
|         "//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", |         "//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", | ||||||
|         "//vendor/k8s.io/client-go/kubernetes:go_default_library", |         "//vendor/k8s.io/client-go/kubernetes:go_default_library", | ||||||
|     ], |     ], | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"k8s.io/apiserver/pkg/admission" | 	"k8s.io/apiserver/pkg/admission" | ||||||
|  | 	genericadmissioninit "k8s.io/apiserver/pkg/admission/initializer" | ||||||
| 	"k8s.io/apiserver/pkg/authorization/authorizer" | 	"k8s.io/apiserver/pkg/authorization/authorizer" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -51,7 +52,7 @@ func (self *WantAuthorizerAdmission) SetAuthorizer(a authorizer.Authorizer) { | |||||||
| } | } | ||||||
|  |  | ||||||
| var _ admission.Interface = &WantAuthorizerAdmission{} | var _ admission.Interface = &WantAuthorizerAdmission{} | ||||||
| var _ WantsAuthorizer = &WantAuthorizerAdmission{} | var _ genericadmissioninit.WantsAuthorizer = &WantAuthorizerAdmission{} | ||||||
|  |  | ||||||
| // TestWantsAuthorizer ensures that the authorizer is injected when the WantsAuthorizer | // TestWantsAuthorizer ensures that the authorizer is injected when the WantsAuthorizer | ||||||
| // interface is implemented. | // interface is implemented. | ||||||
| @@ -106,19 +107,3 @@ func TestWantsServiceResolver(t *testing.T) { | |||||||
| 		t.Errorf("plumbing fail - %v %v#", ok, got) | 		t.Errorf("plumbing fail - %v %v#", ok, got) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| type clientCertWanter struct { |  | ||||||
| 	doNothingAdmission |  | ||||||
| 	gotCert, gotKey []byte |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (s *clientCertWanter) SetClientCert(cert, key []byte) { s.gotCert, s.gotKey = cert, key } |  | ||||||
|  |  | ||||||
| func TestWantsClientCert(t *testing.T) { |  | ||||||
| 	i := &PluginInitializer{} |  | ||||||
| 	ccw := &clientCertWanter{} |  | ||||||
| 	i.SetClientCert([]byte("cert"), []byte("key")).Initialize(ccw) |  | ||||||
| 	if string(ccw.gotCert) != "cert" || string(ccw.gotKey) != "key" { |  | ||||||
| 		t.Errorf("plumbing fail - %v %v", ccw.gotCert, ccw.gotKey) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ import ( | |||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/api/meta" | 	"k8s.io/apimachinery/pkg/api/meta" | ||||||
| 	"k8s.io/apiserver/pkg/admission" | 	"k8s.io/apiserver/pkg/admission" | ||||||
|  | 	admissioninit "k8s.io/apiserver/pkg/admission/initializer" | ||||||
| 	"k8s.io/apiserver/pkg/authorization/authorizer" | 	"k8s.io/apiserver/pkg/authorization/authorizer" | ||||||
| 	clientset "k8s.io/client-go/kubernetes" | 	clientset "k8s.io/client-go/kubernetes" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||||
| @@ -37,24 +38,12 @@ type WantsInternalKubeClientSet interface { | |||||||
| 	admission.Validator | 	admission.Validator | ||||||
| } | } | ||||||
|  |  | ||||||
| // WantsExternalKubeClientSet defines a function which sets ClientSet for admission plugins that need it |  | ||||||
| type WantsExternalKubeClientSet interface { |  | ||||||
| 	SetExternalKubeClientSet(clientset.Interface) |  | ||||||
| 	admission.Validator |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // WantsInternalKubeInformerFactory defines a function which sets InformerFactory for admission plugins that need it | // WantsInternalKubeInformerFactory defines a function which sets InformerFactory for admission plugins that need it | ||||||
| type WantsInternalKubeInformerFactory interface { | type WantsInternalKubeInformerFactory interface { | ||||||
| 	SetInternalKubeInformerFactory(informers.SharedInformerFactory) | 	SetInternalKubeInformerFactory(informers.SharedInformerFactory) | ||||||
| 	admission.Validator | 	admission.Validator | ||||||
| } | } | ||||||
|  |  | ||||||
| // WantsAuthorizer defines a function which sets Authorizer for admission plugins that need it. |  | ||||||
| type WantsAuthorizer interface { |  | ||||||
| 	SetAuthorizer(authorizer.Authorizer) |  | ||||||
| 	admission.Validator |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // WantsCloudConfig defines a function which sets CloudConfig for admission plugins that need it. | // WantsCloudConfig defines a function which sets CloudConfig for admission plugins that need it. | ||||||
| type WantsCloudConfig interface { | type WantsCloudConfig interface { | ||||||
| 	SetCloudConfig([]byte) | 	SetCloudConfig([]byte) | ||||||
| @@ -77,12 +66,6 @@ type WantsServiceResolver interface { | |||||||
| 	SetServiceResolver(ServiceResolver) | 	SetServiceResolver(ServiceResolver) | ||||||
| } | } | ||||||
|  |  | ||||||
| // WantsClientCert defines a fuction that accepts a cert & key for admission |  | ||||||
| // plugins that need to make calls and prove their identity. |  | ||||||
| type WantsClientCert interface { |  | ||||||
| 	SetClientCert(cert, key []byte) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ServiceResolver knows how to convert a service reference into an actual | // ServiceResolver knows how to convert a service reference into an actual | ||||||
| // location. | // location. | ||||||
| type ServiceResolver interface { | type ServiceResolver interface { | ||||||
| @@ -106,8 +89,6 @@ type PluginInitializer struct { | |||||||
| 	serviceResolver ServiceResolver | 	serviceResolver ServiceResolver | ||||||
|  |  | ||||||
| 	// for proving we are apiserver in call-outs | 	// for proving we are apiserver in call-outs | ||||||
| 	clientCert     []byte |  | ||||||
| 	clientKey      []byte |  | ||||||
| 	proxyTransport *http.Transport | 	proxyTransport *http.Transport | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -142,14 +123,6 @@ func (i *PluginInitializer) SetServiceResolver(s ServiceResolver) *PluginInitial | |||||||
| 	return i | 	return i | ||||||
| } | } | ||||||
|  |  | ||||||
| // SetClientCert sets the client cert & key (identity used for calling out to |  | ||||||
| // web hooks) which is needed by some plugins. |  | ||||||
| func (i *PluginInitializer) SetClientCert(cert, key []byte) *PluginInitializer { |  | ||||||
| 	i.clientCert = cert |  | ||||||
| 	i.clientKey = key |  | ||||||
| 	return i |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // SetProxyTransport sets the proxyTransport which is needed by some plugins. | // SetProxyTransport sets the proxyTransport which is needed by some plugins. | ||||||
| func (i *PluginInitializer) SetProxyTransport(proxyTransport *http.Transport) *PluginInitializer { | func (i *PluginInitializer) SetProxyTransport(proxyTransport *http.Transport) *PluginInitializer { | ||||||
| 	i.proxyTransport = proxyTransport | 	i.proxyTransport = proxyTransport | ||||||
| @@ -163,7 +136,7 @@ func (i *PluginInitializer) Initialize(plugin admission.Interface) { | |||||||
| 		wants.SetInternalKubeClientSet(i.internalClient) | 		wants.SetInternalKubeClientSet(i.internalClient) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if wants, ok := plugin.(WantsExternalKubeClientSet); ok { | 	if wants, ok := plugin.(admissioninit.WantsExternalKubeClientSet); ok { | ||||||
| 		wants.SetExternalKubeClientSet(i.externalClient) | 		wants.SetExternalKubeClientSet(i.externalClient) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -171,7 +144,7 @@ func (i *PluginInitializer) Initialize(plugin admission.Interface) { | |||||||
| 		wants.SetInternalKubeInformerFactory(i.informers) | 		wants.SetInternalKubeInformerFactory(i.informers) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if wants, ok := plugin.(WantsAuthorizer); ok { | 	if wants, ok := plugin.(admissioninit.WantsAuthorizer); ok { | ||||||
| 		wants.SetAuthorizer(i.authorizer) | 		wants.SetAuthorizer(i.authorizer) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -191,13 +164,6 @@ func (i *PluginInitializer) Initialize(plugin admission.Interface) { | |||||||
| 		wants.SetServiceResolver(i.serviceResolver) | 		wants.SetServiceResolver(i.serviceResolver) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if wants, ok := plugin.(WantsClientCert); ok { |  | ||||||
| 		if i.clientCert == nil || i.clientKey == nil { |  | ||||||
| 			panic("An admission plugin wants a client cert/key, but they were not provided.") |  | ||||||
| 		} |  | ||||||
| 		wants.SetClientCert(i.clientCert, i.clientKey) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if wants, ok := plugin.(WantsProxyTransport); ok { | 	if wants, ok := plugin.(WantsProxyTransport); ok { | ||||||
| 		wants.SetProxyTransport(i.proxyTransport) | 		wants.SetProxyTransport(i.proxyTransport) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ go_library( | |||||||
|         "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", |         "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", | ||||||
|         "//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", |         "//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", | ||||||
|         "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", |         "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", | ||||||
|  |         "//vendor/k8s.io/apiserver/pkg/admission/initializer:go_default_library", | ||||||
|         "//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library", |         "//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library", | ||||||
|         "//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", |         "//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", | ||||||
|     ], |     ], | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/labels" | 	"k8s.io/apimachinery/pkg/labels" | ||||||
| 	"k8s.io/apimachinery/pkg/util/validation/field" | 	"k8s.io/apimachinery/pkg/util/validation/field" | ||||||
| 	"k8s.io/apiserver/pkg/admission" | 	"k8s.io/apiserver/pkg/admission" | ||||||
|  | 	genericadmissioninit "k8s.io/apiserver/pkg/admission/initializer" | ||||||
| 	"k8s.io/apiserver/pkg/authentication/user" | 	"k8s.io/apiserver/pkg/authentication/user" | ||||||
| 	"k8s.io/apiserver/pkg/authorization/authorizer" | 	"k8s.io/apiserver/pkg/authorization/authorizer" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| @@ -82,7 +83,7 @@ func (plugin *podSecurityPolicyPlugin) Validate() error { | |||||||
| } | } | ||||||
|  |  | ||||||
| var _ admission.Interface = &podSecurityPolicyPlugin{} | var _ admission.Interface = &podSecurityPolicyPlugin{} | ||||||
| var _ kubeapiserveradmission.WantsAuthorizer = &podSecurityPolicyPlugin{} | var _ genericadmissioninit.WantsAuthorizer = &podSecurityPolicyPlugin{} | ||||||
| var _ kubeapiserveradmission.WantsInternalKubeInformerFactory = &podSecurityPolicyPlugin{} | var _ kubeapiserveradmission.WantsInternalKubeInformerFactory = &podSecurityPolicyPlugin{} | ||||||
|  |  | ||||||
| // NewPlugin creates a new PSP admission plugin. | // NewPlugin creates a new PSP admission plugin. | ||||||
|   | |||||||
| @@ -52,6 +52,7 @@ go_library( | |||||||
|         "//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library", |         "//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library", | ||||||
|         "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", |         "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", | ||||||
|         "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", |         "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", | ||||||
|  |         "//vendor/k8s.io/apiserver/pkg/admission/initializer:go_default_library", | ||||||
|         "//vendor/k8s.io/client-go/kubernetes:go_default_library", |         "//vendor/k8s.io/client-go/kubernetes:go_default_library", | ||||||
|         "//vendor/k8s.io/client-go/rest:go_default_library", |         "//vendor/k8s.io/client-go/rest:go_default_library", | ||||||
|     ], |     ], | ||||||
|   | |||||||
| @@ -38,6 +38,7 @@ import ( | |||||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	"k8s.io/apiserver/pkg/admission" | 	"k8s.io/apiserver/pkg/admission" | ||||||
|  | 	genericadmissioninit "k8s.io/apiserver/pkg/admission/initializer" | ||||||
| 	clientset "k8s.io/client-go/kubernetes" | 	clientset "k8s.io/client-go/kubernetes" | ||||||
| 	"k8s.io/client-go/rest" | 	"k8s.io/client-go/rest" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| @@ -114,8 +115,8 @@ type GenericAdmissionWebhook struct { | |||||||
|  |  | ||||||
| var ( | var ( | ||||||
| 	_ = admissioninit.WantsServiceResolver(&GenericAdmissionWebhook{}) | 	_ = admissioninit.WantsServiceResolver(&GenericAdmissionWebhook{}) | ||||||
| 	_ = admissioninit.WantsClientCert(&GenericAdmissionWebhook{}) | 	_ = genericadmissioninit.WantsClientCert(&GenericAdmissionWebhook{}) | ||||||
| 	_ = admissioninit.WantsExternalKubeClientSet(&GenericAdmissionWebhook{}) | 	_ = genericadmissioninit.WantsExternalKubeClientSet(&GenericAdmissionWebhook{}) | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func (a *GenericAdmissionWebhook) SetProxyTransport(pt *http.Transport) { | func (a *GenericAdmissionWebhook) SetProxyTransport(pt *http.Transport) { | ||||||
| @@ -140,6 +141,9 @@ func (a *GenericAdmissionWebhook) SetExternalKubeClientSet(client clientset.Inte | |||||||
| } | } | ||||||
|  |  | ||||||
| func (a *GenericAdmissionWebhook) Validate() error { | func (a *GenericAdmissionWebhook) Validate() error { | ||||||
|  | 	if a.clientCert == nil || a.clientKey == nil { | ||||||
|  | 		return fmt.Errorf("the GenericAdmissionWebhook admission plugin requires a client certificate and the private key to be provided") | ||||||
|  | 	} | ||||||
| 	if a.hookSource == nil { | 	if a.hookSource == nil { | ||||||
| 		return fmt.Errorf("the GenericAdmissionWebhook admission plugin requires a Kubernetes client to be provided") | 		return fmt.Errorf("the GenericAdmissionWebhook admission plugin requires a Kubernetes client to be provided") | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -27,14 +27,21 @@ type pluginInitializer struct { | |||||||
| 	externalClient    kubernetes.Interface | 	externalClient    kubernetes.Interface | ||||||
| 	externalInformers informers.SharedInformerFactory | 	externalInformers informers.SharedInformerFactory | ||||||
| 	authorizer        authorizer.Authorizer | 	authorizer        authorizer.Authorizer | ||||||
|  | 	// serverIdentifyingClientCert used to provide identity when calling out to admission plugins | ||||||
|  | 	serverIdentifyingClientCert []byte | ||||||
|  | 	// serverIdentifyingClientKey private key for the client certificate used when calling out to admission plugins | ||||||
|  | 	serverIdentifyingClientKey []byte | ||||||
| } | } | ||||||
|  |  | ||||||
| // New creates an instance of admission plugins initializer. | // New creates an instance of admission plugins initializer. | ||||||
| func New(extClientset kubernetes.Interface, extInformers informers.SharedInformerFactory, authz authorizer.Authorizer) (pluginInitializer, error) { | // TODO(p0lyn0mial): make the parameters public, this construction seems to be redundant. | ||||||
|  | func New(extClientset kubernetes.Interface, extInformers informers.SharedInformerFactory, authz authorizer.Authorizer, serverIdentifyingClientCert, serverIdentifyingClientKey []byte) (pluginInitializer, error) { | ||||||
| 	return pluginInitializer{ | 	return pluginInitializer{ | ||||||
| 		externalClient:              extClientset, | 		externalClient:              extClientset, | ||||||
| 		externalInformers:           extInformers, | 		externalInformers:           extInformers, | ||||||
| 		authorizer:                  authz, | 		authorizer:                  authz, | ||||||
|  | 		serverIdentifyingClientCert: serverIdentifyingClientCert, | ||||||
|  | 		serverIdentifyingClientKey:  serverIdentifyingClientKey, | ||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -52,6 +59,10 @@ func (i pluginInitializer) Initialize(plugin admission.Interface) { | |||||||
| 	if wants, ok := plugin.(WantsAuthorizer); ok { | 	if wants, ok := plugin.(WantsAuthorizer); ok { | ||||||
| 		wants.SetAuthorizer(i.authorizer) | 		wants.SetAuthorizer(i.authorizer) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if wants, ok := plugin.(WantsClientCert); ok { | ||||||
|  | 		wants.SetClientCert(i.serverIdentifyingClientCert, i.serverIdentifyingClientKey) | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| var _ admission.PluginInitializer = pluginInitializer{} | var _ admission.PluginInitializer = pluginInitializer{} | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ import ( | |||||||
| // TestWantsAuthorizer ensures that the authorizer is injected | // TestWantsAuthorizer ensures that the authorizer is injected | ||||||
| // when the WantsAuthorizer interface is implemented by a plugin. | // when the WantsAuthorizer interface is implemented by a plugin. | ||||||
| func TestWantsAuthorizer(t *testing.T) { | func TestWantsAuthorizer(t *testing.T) { | ||||||
| 	target, err := initializer.New(nil, nil, &TestAuthorizer{}) | 	target, err := initializer.New(nil, nil, &TestAuthorizer{}, nil, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error()) | 		t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error()) | ||||||
| 	} | 	} | ||||||
| @@ -46,7 +46,7 @@ func TestWantsAuthorizer(t *testing.T) { | |||||||
| // when the WantsExternalKubeClientSet interface is implemented by a plugin. | // when the WantsExternalKubeClientSet interface is implemented by a plugin. | ||||||
| func TestWantsExternalKubeClientSet(t *testing.T) { | func TestWantsExternalKubeClientSet(t *testing.T) { | ||||||
| 	cs := &fake.Clientset{} | 	cs := &fake.Clientset{} | ||||||
| 	target, err := initializer.New(cs, nil, &TestAuthorizer{}) | 	target, err := initializer.New(cs, nil, &TestAuthorizer{}, nil, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error()) | 		t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error()) | ||||||
| 	} | 	} | ||||||
| @@ -62,7 +62,7 @@ func TestWantsExternalKubeClientSet(t *testing.T) { | |||||||
| func TestWantsExternalKubeInformerFactory(t *testing.T) { | func TestWantsExternalKubeInformerFactory(t *testing.T) { | ||||||
| 	cs := &fake.Clientset{} | 	cs := &fake.Clientset{} | ||||||
| 	sf := informers.NewSharedInformerFactory(cs, time.Duration(1)*time.Second) | 	sf := informers.NewSharedInformerFactory(cs, time.Duration(1)*time.Second) | ||||||
| 	target, err := initializer.New(cs, sf, &TestAuthorizer{}) | 	target, err := initializer.New(cs, sf, &TestAuthorizer{}, nil, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error()) | 		t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error()) | ||||||
| 	} | 	} | ||||||
| @@ -73,6 +73,20 @@ func TestWantsExternalKubeInformerFactory(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // TestWantsClientCert ensures that the client certificate and key are injected | ||||||
|  | // when the WantsClientCert interface is implemented by a plugin. | ||||||
|  | func TestWantsClientCert(t *testing.T) { | ||||||
|  | 	target, err := initializer.New(nil, nil, nil, []byte("cert"), []byte("key")) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error()) | ||||||
|  | 	} | ||||||
|  | 	wantClientCert := &clientCertWanter{} | ||||||
|  | 	target.Initialize(wantClientCert) | ||||||
|  | 	if string(wantClientCert.gotCert) != "cert" || string(wantClientCert.gotKey) != "key" { | ||||||
|  | 		t.Errorf("expected client cert to be initialized, clientCert = %v, clientKey = %v", wantClientCert.gotCert, wantClientCert.gotKey) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| // WantExternalKubeInformerFactory is a test stub that fulfills the WantsExternalKubeInformerFactory interface | // WantExternalKubeInformerFactory is a test stub that fulfills the WantsExternalKubeInformerFactory interface | ||||||
| type WantExternalKubeInformerFactory struct { | type WantExternalKubeInformerFactory struct { | ||||||
| 	sf informers.SharedInformerFactory | 	sf informers.SharedInformerFactory | ||||||
| @@ -114,9 +128,19 @@ func (self *WantAuthorizerAdmission) Validate() error                       { re | |||||||
| var _ admission.Interface = &WantAuthorizerAdmission{} | var _ admission.Interface = &WantAuthorizerAdmission{} | ||||||
| var _ initializer.WantsAuthorizer = &WantAuthorizerAdmission{} | var _ initializer.WantsAuthorizer = &WantAuthorizerAdmission{} | ||||||
|  |  | ||||||
| // TestAuthorizer is a test stub for testing that fulfills the authorizer interface. | // TestAuthorizer is a test stub that fulfills the WantsAuthorizer interface. | ||||||
| type TestAuthorizer struct{} | type TestAuthorizer struct{} | ||||||
|  |  | ||||||
| func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized bool, reason string, err error) { | func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized bool, reason string, err error) { | ||||||
| 	return false, "", nil | 	return false, "", nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // wantClientCert is a test stub for testing that fulfulls the WantsClientCert interface. | ||||||
|  | type clientCertWanter struct { | ||||||
|  | 	gotCert, gotKey []byte | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *clientCertWanter) SetClientCert(cert, key []byte)     { s.gotCert, s.gotKey = cert, key } | ||||||
|  | func (s *clientCertWanter) Admit(a admission.Attributes) error { return nil } | ||||||
|  | func (s *clientCertWanter) Handles(o admission.Operation) bool { return false } | ||||||
|  | func (s *clientCertWanter) Validate() error                    { return nil } | ||||||
|   | |||||||
| @@ -40,3 +40,10 @@ type WantsAuthorizer interface { | |||||||
| 	SetAuthorizer(authorizer.Authorizer) | 	SetAuthorizer(authorizer.Authorizer) | ||||||
| 	admission.Validator | 	admission.Validator | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // WantsClientCert defines a fuction that accepts a cert & key for admission | ||||||
|  | // plugins that need to make calls and prove their identity. | ||||||
|  | type WantsClientCert interface { | ||||||
|  | 	SetClientCert(cert, key []byte) | ||||||
|  | 	admission.Validator | ||||||
|  | } | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ func newHandlerForTestWithClock(c clientset.Interface, cacheClock clock.Clock) ( | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, f, err | 		return nil, f, err | ||||||
| 	} | 	} | ||||||
| 	pluginInitializer, err := kubeadmission.New(c, f, nil) | 	pluginInitializer, err := kubeadmission.New(c, f, nil, nil, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return handler, f, err | 		return handler, f, err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -73,9 +73,14 @@ func (a *AdmissionOptions) AddFlags(fs *pflag.FlagSet) { | |||||||
| // In addition the method lazily initializes a generic plugin that is appended to the list of pluginInitializers | // In addition the method lazily initializes a generic plugin that is appended to the list of pluginInitializers | ||||||
| // note this method uses: | // note this method uses: | ||||||
| //  genericconfig.LoopbackClientConfig | //  genericconfig.LoopbackClientConfig | ||||||
| //  genericconfig.SharedInformerFactory |  | ||||||
| //  genericconfig.Authorizer | //  genericconfig.Authorizer | ||||||
| func (a *AdmissionOptions) ApplyTo(c *server.Config, informers informers.SharedInformerFactory, pluginInitializers ...admission.PluginInitializer) error { | func (a *AdmissionOptions) ApplyTo( | ||||||
|  | 	c *server.Config, | ||||||
|  | 	informers informers.SharedInformerFactory, | ||||||
|  | 	serverIdentifyingClientCert []byte, | ||||||
|  | 	serverIdentifyingClientKey []byte, | ||||||
|  | 	pluginInitializers ...admission.PluginInitializer, | ||||||
|  | ) error { | ||||||
| 	pluginNames := a.PluginNames | 	pluginNames := a.PluginNames | ||||||
| 	if len(a.PluginNames) == 0 { | 	if len(a.PluginNames) == 0 { | ||||||
| 		pluginNames = a.enabledPluginNames() | 		pluginNames = a.enabledPluginNames() | ||||||
| @@ -90,7 +95,7 @@ func (a *AdmissionOptions) ApplyTo(c *server.Config, informers informers.SharedI | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	genericInitializer, err := initializer.New(clientset, informers, c.Authorizer) | 	genericInitializer, err := initializer.New(clientset, informers, c.Authorizer, serverIdentifyingClientCert, serverIdentifyingClientKey) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -119,7 +119,7 @@ func (o WardleServerOptions) Config() (*apiserver.Config, error) { | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := o.Admission.ApplyTo(&serverConfig.Config, serverConfig.SharedInformerFactory, admissionInitializer); err != nil { | 	if err := o.Admission.ApplyTo(&serverConfig.Config, serverConfig.SharedInformerFactory, nil, nil, admissionInitializer); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 p0lyn0mial
					p0lyn0mial