diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index fe15e97fe2..892598dab6 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -314,7 +314,7 @@ func Run(s *options.APIServer) error { } sharedInformers := informers.NewSharedInformerFactory(client, 10*time.Minute) - pluginInitializer := admission.NewPluginInitializer(sharedInformers) + pluginInitializer := admission.NewPluginInitializer(sharedInformers, apiAuthorizer) admissionController, err := admission.NewFromPlugins(client, admissionControlPluginNames, s.AdmissionControlConfigFile, pluginInitializer) if err != nil { diff --git a/federation/cmd/federation-apiserver/app/server.go b/federation/cmd/federation-apiserver/app/server.go index 034555b95d..6e4877c1f1 100644 --- a/federation/cmd/federation-apiserver/app/server.go +++ b/federation/cmd/federation-apiserver/app/server.go @@ -204,7 +204,7 @@ func Run(s *options.ServerRunOptions) error { } sharedInformers := informers.NewSharedInformerFactory(client, 10*time.Minute) - pluginInitializer := admission.NewPluginInitializer(sharedInformers) + pluginInitializer := admission.NewPluginInitializer(sharedInformers, apiAuthorizer) admissionController, err := admission.NewFromPlugins(client, admissionControlPluginNames, s.AdmissionControlConfigFile, pluginInitializer) if err != nil { diff --git a/pkg/admission/init.go b/pkg/admission/init.go index 9fc40c13aa..de4e2db83b 100644 --- a/pkg/admission/init.go +++ b/pkg/admission/init.go @@ -17,6 +17,7 @@ limitations under the License. package admission import ( + "k8s.io/kubernetes/pkg/auth/authorizer" "k8s.io/kubernetes/pkg/controller/informers" ) @@ -27,13 +28,15 @@ type PluginInitializer interface { } type pluginInitializer struct { - informers informers.SharedInformerFactory + informers informers.SharedInformerFactory + authorizer authorizer.Authorizer } // NewPluginInitializer constructs new instance of PluginInitializer -func NewPluginInitializer(sharedInformers informers.SharedInformerFactory) PluginInitializer { +func NewPluginInitializer(sharedInformers informers.SharedInformerFactory, authz authorizer.Authorizer) PluginInitializer { plugInit := &pluginInitializer{ - informers: sharedInformers, + informers: sharedInformers, + authorizer: authz, } return plugInit } @@ -45,6 +48,10 @@ func (i *pluginInitializer) Initialize(plugins []Interface) { if wantsInformerFactory, ok := plugin.(WantsInformerFactory); ok { wantsInformerFactory.SetInformerFactory(i.informers) } + + if wantsAuthorizer, ok := plugin.(WantsAuthorizer); ok { + wantsAuthorizer.SetAuthorizer(i.authorizer) + } } } diff --git a/pkg/admission/init_test.go b/pkg/admission/init_test.go new file mode 100644 index 0000000000..685a77ac96 --- /dev/null +++ b/pkg/admission/init_test.go @@ -0,0 +1,59 @@ +/* +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 ( + "testing" + + "k8s.io/kubernetes/pkg/auth/authorizer" +) + +// TestAuthorizer is a testing struct for testing that fulfills the authorizer interface. +type TestAuthorizer struct{} + +func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized bool, reason string, err error) { + return false, "", nil +} + +var _ authorizer.Authorizer = &TestAuthorizer{} + +// WantAuthorizerAdmission is a testing struct that fulfills the WantsAuthorizer +// interface. +type WantAuthorizerAdmission struct { + auth authorizer.Authorizer +} + +func (self *WantAuthorizerAdmission) SetAuthorizer(a authorizer.Authorizer) { + self.auth = a +} +func (self *WantAuthorizerAdmission) Admit(a Attributes) error { return nil } +func (self *WantAuthorizerAdmission) Handles(o Operation) bool { return false } +func (self *WantAuthorizerAdmission) Validate() error { return nil } + +var _ Interface = &WantAuthorizerAdmission{} +var _ WantsAuthorizer = &WantAuthorizerAdmission{} + +// TestWantsAuthorizer ensures that the authorizer is injected when the WantsAuthorizer +// interface is implemented. +func TestWantsAuthorizer(t *testing.T) { + initializer := NewPluginInitializer(nil, &TestAuthorizer{}) + wantAuthorizerAdmission := &WantAuthorizerAdmission{} + initializer.Initialize([]Interface{wantAuthorizerAdmission}) + if wantAuthorizerAdmission.auth == nil { + t.Errorf("expected authorizer to be initialized but found nil") + } +} diff --git a/pkg/admission/types.go b/pkg/admission/types.go index 69609b7e1e..21c943b8d0 100644 --- a/pkg/admission/types.go +++ b/pkg/admission/types.go @@ -17,6 +17,7 @@ limitations under the License. package admission import ( + "k8s.io/kubernetes/pkg/auth/authorizer" "k8s.io/kubernetes/pkg/controller/informers" ) @@ -31,3 +32,9 @@ type WantsInformerFactory interface { SetInformerFactory(informers.SharedInformerFactory) Validator } + +// WantsAuthorizer defines a function which sets Authorizer for admission plugins that need it. +type WantsAuthorizer interface { + SetAuthorizer(authorizer.Authorizer) + Validator +} diff --git a/plugin/pkg/admission/namespace/autoprovision/admission_test.go b/plugin/pkg/admission/namespace/autoprovision/admission_test.go index 7f8ea9dfee..37c502be74 100644 --- a/plugin/pkg/admission/namespace/autoprovision/admission_test.go +++ b/plugin/pkg/admission/namespace/autoprovision/admission_test.go @@ -38,7 +38,7 @@ func newHandlerForTest(c clientset.Interface) (admission.Interface, informers.Sh f := informers.NewSharedInformerFactory(c, 5*time.Minute) handler := NewProvision(c) plugins := []admission.Interface{handler} - pluginInitializer := admission.NewPluginInitializer(f) + pluginInitializer := admission.NewPluginInitializer(f, nil) pluginInitializer.Initialize(plugins) err := admission.Validate(plugins) return handler, f, err diff --git a/plugin/pkg/admission/namespace/exists/admission_test.go b/plugin/pkg/admission/namespace/exists/admission_test.go index cce8d23359..ee2685986b 100644 --- a/plugin/pkg/admission/namespace/exists/admission_test.go +++ b/plugin/pkg/admission/namespace/exists/admission_test.go @@ -37,7 +37,7 @@ func newHandlerForTest(c clientset.Interface) (admission.Interface, informers.Sh f := informers.NewSharedInformerFactory(c, 5*time.Minute) handler := NewExists(c) plugins := []admission.Interface{handler} - pluginInitializer := admission.NewPluginInitializer(f) + pluginInitializer := admission.NewPluginInitializer(f, nil) pluginInitializer.Initialize(plugins) err := admission.Validate(plugins) return handler, f, err diff --git a/plugin/pkg/admission/namespace/lifecycle/admission_test.go b/plugin/pkg/admission/namespace/lifecycle/admission_test.go index 6fd750c1fa..74e7c81c37 100644 --- a/plugin/pkg/admission/namespace/lifecycle/admission_test.go +++ b/plugin/pkg/admission/namespace/lifecycle/admission_test.go @@ -47,7 +47,7 @@ func newHandlerForTestWithClock(c clientset.Interface, cacheClock clock.Clock) ( return nil, f, err } plugins := []admission.Interface{handler} - pluginInitializer := admission.NewPluginInitializer(f) + pluginInitializer := admission.NewPluginInitializer(f, nil) pluginInitializer.Initialize(plugins) err = admission.Validate(plugins) return handler, f, err