diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index d71908e11e4..15926581840 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -332,7 +332,15 @@ func BuildMasterConfig(s *options.ServerRunOptions) (*master.Config, informers.S } admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",") - pluginInitializer := kubeadmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer) + var cloudConfig []byte + + if s.CloudProvider.CloudConfigFile != "" { + cloudConfig, err = ioutil.ReadFile(s.CloudProvider.CloudConfigFile) + if err != nil { + glog.Fatalf("Error reading from cloud configuration file %s: %#v", s.CloudProvider.CloudConfigFile, err) + } + } + pluginInitializer := kubeadmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer, cloudConfig) admissionConfigProvider, err := admission.ReadAdmissionConfiguration(admissionControlPluginNames, s.GenericServerRunOptions.AdmissionControlConfigFile) if err != nil { return nil, nil, fmt.Errorf("failed to read plugin config: %v", err) diff --git a/federation/cmd/federation-apiserver/app/server.go b/federation/cmd/federation-apiserver/app/server.go index 25276dd0d33..a9202a8897b 100644 --- a/federation/cmd/federation-apiserver/app/server.go +++ b/federation/cmd/federation-apiserver/app/server.go @@ -21,6 +21,7 @@ package app import ( "fmt" + "io/ioutil" "strings" "time" @@ -168,7 +169,15 @@ func Run(s *options.ServerRunOptions) error { } admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",") - pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer) + var cloudConfig []byte + + if s.CloudProvider.CloudConfigFile != "" { + cloudConfig, err = ioutil.ReadFile(s.CloudProvider.CloudConfigFile) + if err != nil { + glog.Fatalf("Error reading from cloud configuration file %s: %#v", s.CloudProvider.CloudConfigFile, err) + } + } + pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer, cloudConfig) admissionConfigProvider, err := admission.ReadAdmissionConfiguration(admissionControlPluginNames, s.GenericServerRunOptions.AdmissionControlConfigFile) if err != nil { return fmt.Errorf("failed to read plugin config: %v", err) diff --git a/pkg/kubeapiserver/admission/init_test.go b/pkg/kubeapiserver/admission/init_test.go index 6df687d8cf8..fd584385c03 100644 --- a/pkg/kubeapiserver/admission/init_test.go +++ b/pkg/kubeapiserver/admission/init_test.go @@ -51,10 +51,33 @@ var _ WantsAuthorizer = &WantAuthorizerAdmission{} // TestWantsAuthorizer ensures that the authorizer is injected when the WantsAuthorizer // interface is implemented. func TestWantsAuthorizer(t *testing.T) { - initializer := NewPluginInitializer(nil, nil, &TestAuthorizer{}) + initializer := NewPluginInitializer(nil, nil, &TestAuthorizer{}, nil) wantAuthorizerAdmission := &WantAuthorizerAdmission{} initializer.Initialize(wantAuthorizerAdmission) if wantAuthorizerAdmission.auth == nil { t.Errorf("expected authorizer to be initialized but found nil") } } + +type WantsCloudConfigAdmissionPlugin struct { + cloudConfig []byte +} + +func (self *WantsCloudConfigAdmissionPlugin) SetCloudConfig(cloudConfig []byte) { + self.cloudConfig = cloudConfig +} + +func (self *WantsCloudConfigAdmissionPlugin) Admit(a admission.Attributes) error { return nil } +func (self *WantsCloudConfigAdmissionPlugin) Handles(o admission.Operation) bool { return false } +func (self *WantsCloudConfigAdmissionPlugin) Validate() error { return nil } + +func TestCloudConfigAdmissionPlugin(t *testing.T) { + cloudConfig := []byte("cloud-configuration") + initializer := NewPluginInitializer(nil, nil, &TestAuthorizer{}, cloudConfig) + wantsCloudConfigAdmission := &WantsCloudConfigAdmissionPlugin{} + initializer.Initialize(wantsCloudConfigAdmission) + + if wantsCloudConfigAdmission.cloudConfig == nil { + t.Errorf("Expected cloud config to be initialized but found nil") + } +} diff --git a/pkg/kubeapiserver/admission/initializer.go b/pkg/kubeapiserver/admission/initializer.go index fe0a3710af4..5bcba733cc3 100644 --- a/pkg/kubeapiserver/admission/initializer.go +++ b/pkg/kubeapiserver/admission/initializer.go @@ -43,20 +43,27 @@ type WantsAuthorizer interface { admission.Validator } +// WantsCloudConfig defines a function which sets CloudConfig for admission plugins that need it. +type WantsCloudConfig interface { + SetCloudConfig([]byte) +} + type pluginInitializer struct { internalClient internalclientset.Interface informers informers.SharedInformerFactory authorizer authorizer.Authorizer + cloudConfig []byte } var _ admission.PluginInitializer = pluginInitializer{} // NewPluginInitializer constructs new instance of PluginInitializer -func NewPluginInitializer(internalClient internalclientset.Interface, sharedInformers informers.SharedInformerFactory, authz authorizer.Authorizer) admission.PluginInitializer { +func NewPluginInitializer(internalClient internalclientset.Interface, sharedInformers informers.SharedInformerFactory, authz authorizer.Authorizer, cloudConfig []byte) admission.PluginInitializer { return pluginInitializer{ internalClient: internalClient, informers: sharedInformers, authorizer: authz, + cloudConfig: cloudConfig, } } @@ -74,4 +81,8 @@ func (i pluginInitializer) Initialize(plugin admission.Interface) { if wants, ok := plugin.(WantsAuthorizer); ok { wants.SetAuthorizer(i.authorizer) } + + if wants, ok := plugin.(WantsCloudConfig); ok { + wants.SetCloudConfig(i.cloudConfig) + } } diff --git a/plugin/pkg/admission/limitranger/admission_test.go b/plugin/pkg/admission/limitranger/admission_test.go index e4482dd1b44..a651a2d502f 100644 --- a/plugin/pkg/admission/limitranger/admission_test.go +++ b/plugin/pkg/admission/limitranger/admission_test.go @@ -595,7 +595,7 @@ func newHandlerForTest(c clientset.Interface) (admission.Interface, informers.Sh if err != nil { return nil, f, err } - pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil) + pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil) pluginInitializer.Initialize(handler) err = admission.Validate(handler) return handler, f, err diff --git a/plugin/pkg/admission/namespace/autoprovision/admission_test.go b/plugin/pkg/admission/namespace/autoprovision/admission_test.go index c03f36cb7b9..40001e366b6 100644 --- a/plugin/pkg/admission/namespace/autoprovision/admission_test.go +++ b/plugin/pkg/admission/namespace/autoprovision/admission_test.go @@ -38,7 +38,7 @@ import ( func newHandlerForTest(c clientset.Interface) (admission.Interface, informers.SharedInformerFactory, error) { f := informers.NewSharedInformerFactory(c, 5*time.Minute) handler := NewProvision() - pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil) + pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil) pluginInitializer.Initialize(handler) err := admission.Validate(handler) 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 389a0240a1d..6e211e1e66e 100644 --- a/plugin/pkg/admission/namespace/exists/admission_test.go +++ b/plugin/pkg/admission/namespace/exists/admission_test.go @@ -37,7 +37,7 @@ import ( func newHandlerForTest(c clientset.Interface) (admission.Interface, informers.SharedInformerFactory, error) { f := informers.NewSharedInformerFactory(c, 5*time.Minute) handler := NewExists() - pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil) + pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil) pluginInitializer.Initialize(handler) err := admission.Validate(handler) 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 20e78111d16..026328ebb1d 100644 --- a/plugin/pkg/admission/namespace/lifecycle/admission_test.go +++ b/plugin/pkg/admission/namespace/lifecycle/admission_test.go @@ -48,7 +48,7 @@ func newHandlerForTestWithClock(c clientset.Interface, cacheClock clock.Clock) ( if err != nil { return nil, f, err } - pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil) + pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil) pluginInitializer.Initialize(handler) err = admission.Validate(handler) return handler, f, err diff --git a/plugin/pkg/admission/persistentvolume/label/BUILD b/plugin/pkg/admission/persistentvolume/label/BUILD index f8c6ef86db3..eb848c37ed2 100644 --- a/plugin/pkg/admission/persistentvolume/label/BUILD +++ b/plugin/pkg/admission/persistentvolume/label/BUILD @@ -20,6 +20,7 @@ go_library( "//pkg/cloudprovider:go_default_library", "//pkg/cloudprovider/providers/aws:go_default_library", "//pkg/cloudprovider/providers/gce:go_default_library", + "//pkg/kubeapiserver/admission:go_default_library", "//pkg/volume:go_default_library", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apiserver/pkg/admission", diff --git a/plugin/pkg/admission/persistentvolume/label/admission.go b/plugin/pkg/admission/persistentvolume/label/admission.go index 11fdec74031..312dab6731a 100644 --- a/plugin/pkg/admission/persistentvolume/label/admission.go +++ b/plugin/pkg/admission/persistentvolume/label/admission.go @@ -17,6 +17,7 @@ limitations under the License. package label import ( + "bytes" "fmt" "io" "sync" @@ -27,6 +28,7 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider/providers/aws" "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" + kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" vol "k8s.io/kubernetes/pkg/volume" ) @@ -44,9 +46,12 @@ type persistentVolumeLabel struct { mutex sync.Mutex ebsVolumes aws.Volumes + cloudConfig []byte gceCloudProvider *gce.GCECloud } +var _ kubeapiserveradmission.WantsCloudConfig = &persistentVolumeLabel{} + // NewPersistentVolumeLabel returns an admission.Interface implementation which adds labels to PersistentVolume CREATE requests, // based on the labels provided by the underlying cloud provider. // @@ -57,6 +62,10 @@ func NewPersistentVolumeLabel() *persistentVolumeLabel { } } +func (l *persistentVolumeLabel) SetCloudConfig(cloudConfig []byte) { + l.cloudConfig = cloudConfig +} + func (l *persistentVolumeLabel) Admit(a admission.Attributes) (err error) { if a.GetResource().GroupResource() != api.Resource("persistentvolumes") { return nil @@ -131,7 +140,11 @@ func (l *persistentVolumeLabel) getEBSVolumes() (aws.Volumes, error) { defer l.mutex.Unlock() if l.ebsVolumes == nil { - cloudProvider, err := cloudprovider.GetCloudProvider("aws", nil) + var cloudConfigReader io.Reader + if len(l.cloudConfig) > 0 { + cloudConfigReader = bytes.NewReader(l.cloudConfig) + } + cloudProvider, err := cloudprovider.GetCloudProvider("aws", cloudConfigReader) if err != nil || cloudProvider == nil { return nil, err } @@ -176,7 +189,11 @@ func (l *persistentVolumeLabel) getGCECloudProvider() (*gce.GCECloud, error) { defer l.mutex.Unlock() if l.gceCloudProvider == nil { - cloudProvider, err := cloudprovider.GetCloudProvider("gce", nil) + var cloudConfigReader io.Reader + if len(l.cloudConfig) > 0 { + cloudConfigReader = bytes.NewReader(l.cloudConfig) + } + cloudProvider, err := cloudprovider.GetCloudProvider("gce", cloudConfigReader) if err != nil || cloudProvider == nil { return nil, err } diff --git a/plugin/pkg/admission/podnodeselector/admission_test.go b/plugin/pkg/admission/podnodeselector/admission_test.go index 4e6d874e799..acdf65d6356 100644 --- a/plugin/pkg/admission/podnodeselector/admission_test.go +++ b/plugin/pkg/admission/podnodeselector/admission_test.go @@ -183,7 +183,7 @@ func TestHandles(t *testing.T) { func newHandlerForTest(c clientset.Interface) (*podNodeSelector, informers.SharedInformerFactory, error) { f := informers.NewSharedInformerFactory(c, 5*time.Minute) handler := NewPodNodeSelector(nil) - pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil) + pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil) pluginInitializer.Initialize(handler) err := admission.Validate(handler) return handler, f, err