From 205b2eb3fd831fc52806ba280772ff1ddd3d02e7 Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Fri, 19 Jan 2018 17:41:17 -0500 Subject: [PATCH] Use backup location to load cloud config for OpenStack Since we are transitioning to external cloud provider, we need a way to use the existing cinder volume plugin (from kubelet). With external cloud manager kubelet will be run with --cloud=provider=external and no --cloud-config file will be in the command line. So we need a way to load the openstack config file from somewhere. Taking a cue from kubeadm, which currently is picking up "/etc/kubernetes/cloud-config" https://github.com/kubernetes/kubernetes/blob/master/cmd/kubeadm/app/phases/controlplane/manifests.go#L44 let's support the scenario where we fall back to this static location if there is no cloud provider specified in the command line. This has been tested with local-up-cluster using the following params: EXTERNAL_CLOUD_PROVIDER=true CLOUD_PROVIDER=openstack CLOUD_CONFIG=/etc/kubernetes/cloud-config --- pkg/volume/cinder/attacher.go | 4 ++-- pkg/volume/cinder/cinder.go | 30 ++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/pkg/volume/cinder/attacher.go b/pkg/volume/cinder/attacher.go index 65b24640cbb..ecda5536c5e 100644 --- a/pkg/volume/cinder/attacher.go +++ b/pkg/volume/cinder/attacher.go @@ -57,7 +57,7 @@ const ( ) func (plugin *cinderPlugin) NewAttacher() (volume.Attacher, error) { - cinder, err := getCloudProvider(plugin.host.GetCloudProvider()) + cinder, err := plugin.getCloudProvider() if err != nil { return nil, err } @@ -305,7 +305,7 @@ type cinderDiskDetacher struct { var _ volume.Detacher = &cinderDiskDetacher{} func (plugin *cinderPlugin) NewDetacher() (volume.Detacher, error) { - cinder, err := getCloudProvider(plugin.host.GetCloudProvider()) + cinder, err := plugin.getCloudProvider() if err != nil { return nil, err } diff --git a/pkg/volume/cinder/cinder.go b/pkg/volume/cinder/cinder.go index 07fa459a98d..f0255d5f4f2 100644 --- a/pkg/volume/cinder/cinder.go +++ b/pkg/volume/cinder/cinder.go @@ -37,6 +37,10 @@ import ( "k8s.io/kubernetes/pkg/volume/util/volumehelper" ) +const ( + DefaultCloudConfigPath = "/etc/kubernetes/cloud-config" +) + // This is the primary entrypoint for volume plugins. func ProbeVolumePlugins() []volume.VolumePlugin { return []volume.VolumePlugin{&cinderPlugin{}} @@ -188,25 +192,31 @@ func (plugin *cinderPlugin) newProvisionerInternal(options volume.VolumeOptions, }, nil } -func getCloudProvider(cloudProvider cloudprovider.Interface) (CinderProvider, error) { - if cloud, ok := cloudProvider.(*openstack.OpenStack); ok && cloud != nil { - return cloud, nil - } - return nil, fmt.Errorf("wrong cloud type") -} - func (plugin *cinderPlugin) getCloudProvider() (CinderProvider, error) { cloud := plugin.host.GetCloudProvider() if cloud == nil { - glog.Errorf("Cloud provider not initialized properly") - return nil, errors.New("Cloud provider not initialized properly") + if _, err := os.Stat(DefaultCloudConfigPath); err == nil { + var config *os.File + config, err = os.Open(DefaultCloudConfigPath) + if err != nil { + return nil, errors.New(fmt.Sprintf("unable to load OpenStack configuration from default path : %v", err)) + } else { + defer config.Close() + cloud, err = cloudprovider.GetCloudProvider(openstack.ProviderName, config) + if err != nil { + return nil, errors.New(fmt.Sprintf("unable to create OpenStack cloud provider from default path : %v", err)) + } + } + } else { + return nil, errors.New(fmt.Sprintf("OpenStack cloud provider was not initialized properly : %v", err)) + } } switch cloud := cloud.(type) { case *openstack.OpenStack: return cloud, nil default: - return nil, errors.New("Invalid cloud provider: expected OpenStack.") + return nil, errors.New("invalid cloud provider: expected OpenStack") } }