From ad8ea764a67ad1f3429ceecff76e21246708b462 Mon Sep 17 00:00:00 2001 From: Emilio Garcia Date: Mon, 20 Jan 2020 15:26:05 -0500 Subject: [PATCH 1/2] Revert "allow CA Cert bundles to be trusted" This reverts commit 17be76912a6977bec5363d2c2b0657f357258619. --- .../openstackproviderconfig/v1alpha1/types.go | 3 -- pkg/cloud/openstack/clients/machineservice.go | 36 ++++--------------- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/pkg/apis/openstackproviderconfig/v1alpha1/types.go b/pkg/apis/openstackproviderconfig/v1alpha1/types.go index 2c56686e2f..8cb14be922 100644 --- a/pkg/apis/openstackproviderconfig/v1alpha1/types.go +++ b/pkg/apis/openstackproviderconfig/v1alpha1/types.go @@ -38,9 +38,6 @@ type OpenstackProviderSpec struct { // The name of the cloud to use from the clouds secret CloudName string `json:"cloudName"` - // A plaintext string of PEM(s) - CertBundle string `json:"caCert,omitempty"` - // The flavor reference for the flavor for your server instance. Flavor string `json:"flavor"` diff --git a/pkg/cloud/openstack/clients/machineservice.go b/pkg/cloud/openstack/clients/machineservice.go index 9ef7734a8e..f9d11c9ae4 100644 --- a/pkg/cloud/openstack/clients/machineservice.go +++ b/pkg/cloud/openstack/clients/machineservice.go @@ -17,11 +17,8 @@ limitations under the License. package clients import ( - "crypto/tls" - "crypto/x509" "encoding/base64" "fmt" - "net/http" "time" "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups" @@ -169,16 +166,17 @@ func NewInstanceServiceFromMachine(kubeClient kubernetes.Interface, machine *mac return nil, fmt.Errorf("Failed to get cloud from secret (clients/machienservice.go 150): %v", err) } } - return NewInstanceServiceFromCloud(cloud, []byte(machineSpec.CertBundle)) + return NewInstanceServiceFromCloud(cloud) } func NewInstanceService() (*InstanceService, error) { cloud := clientconfig.Cloud{} - return NewInstanceServiceFromCloud(cloud, nil) + return NewInstanceServiceFromCloud(cloud) } -func NewInstanceServiceFromCloud(cloud clientconfig.Cloud, cert []byte) (*InstanceService, error) { +func NewInstanceServiceFromCloud(cloud clientconfig.Cloud) (*InstanceService, error) { clientOpts := new(clientconfig.ClientOpts) + var opts *gophercloud.AuthOptions if cloud.AuthInfo != nil { clientOpts.AuthInfo = cloud.AuthInfo @@ -188,36 +186,16 @@ func NewInstanceServiceFromCloud(cloud clientconfig.Cloud, cert []byte) (*Instan } opts, err := clientconfig.AuthOptions(clientOpts) + if err != nil { return nil, err } opts.AllowReauth = true - provider, err := openstack.NewClient(opts.IdentityEndpoint) - if err != nil { - return nil, fmt.Errorf("Create new provider client failed: %v", err) - } - - if cert != nil { - certPool, err := x509.SystemCertPool() - if err != nil { - return nil, fmt.Errorf("Create system cert pool failed: %v", err) - } - certPool.AppendCertsFromPEM(cert) - client := http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - RootCAs: certPool, - }, - }, - } - provider.HTTPClient = client - } - - err = openstack.Authenticate(provider, *opts) + provider, err := openstack.AuthenticatedClient(*opts) if err != nil { - return nil, fmt.Errorf("Failed to authenticate provider client: %v", err) + return nil, fmt.Errorf("Create providerClient err: %v", err) } identityClient, err := openstack.NewIdentityV3(provider, gophercloud.EndpointOpts{ From 8f399b28775dffedd5ceead7110a55f046bfa08a Mon Sep 17 00:00:00 2001 From: Emilio Garcia Date: Mon, 20 Jan 2020 16:01:06 -0500 Subject: [PATCH 2/2] get ca cert from cloud-provider-config It's a valid use case, for instance when deploying on an OpenStack cloud that doesn't use SSL. --- pkg/cloud/openstack/clients/machineservice.go | 59 ++++++++++++++++--- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/pkg/cloud/openstack/clients/machineservice.go b/pkg/cloud/openstack/clients/machineservice.go index f9d11c9ae4..b2c2357bb5 100644 --- a/pkg/cloud/openstack/clients/machineservice.go +++ b/pkg/cloud/openstack/clients/machineservice.go @@ -17,8 +17,11 @@ limitations under the License. package clients import ( + "crypto/tls" + "crypto/x509" "encoding/base64" "fmt" + "net/http" "time" "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups" @@ -149,11 +152,25 @@ func GetCloudFromSecret(kubeClient kubernetes.Interface, namespace string, secre return clouds.Clouds[cloudName], nil } +func getCACertFromConfigmap(kubeClient kubernetes.Interface, namespace string, configmapName string, key string) (string, error) { + cloudConfig, err := kubeClient.CoreV1().ConfigMaps(namespace).Get(configmapName, metav1.GetOptions{}) + if err != nil { + return "", fmt.Errorf("failed to get configmap %s/%s/%s from kubernetes api: %v", namespace, configmapName, key, err) + } + + val, ok := cloudConfig.Data[key] + if !ok { + return "", fmt.Errorf("configmap does not contain key, %s", key) + } + + return val, nil +} + // TODO: Eventually we'll have a NewInstanceServiceFromCluster too func NewInstanceServiceFromMachine(kubeClient kubernetes.Interface, machine *machinev1.Machine) (*InstanceService, error) { machineSpec, err := openstackconfigv1.MachineSpecFromProviderSpec(machine.Spec.ProviderSpec) if err != nil { - return nil, fmt.Errorf("Failed to get Machine Spec from Provider Spec (clients/machineservice.go 138): %v", err) + return nil, fmt.Errorf("Failed to get Machine Spec from Provider Spec: %v", err) } cloud := clientconfig.Cloud{} if machineSpec.CloudsSecret != nil && machineSpec.CloudsSecret.Name != "" { @@ -163,20 +180,25 @@ func NewInstanceServiceFromMachine(kubeClient kubernetes.Interface, machine *mac } cloud, err = GetCloudFromSecret(kubeClient, namespace, machineSpec.CloudsSecret.Name, machineSpec.CloudName) if err != nil { - return nil, fmt.Errorf("Failed to get cloud from secret (clients/machienservice.go 150): %v", err) + return nil, fmt.Errorf("Failed to get cloud from secret: %v", err) } } - return NewInstanceServiceFromCloud(cloud) + + cacert, err := getCACertFromConfigmap(kubeClient, "openshift-config", "cloud-provider-config", "ca-bundle.pem") + if err != nil || cacert == "" { + return NewInstanceServiceFromCloud(cloud, nil) + } + + return NewInstanceServiceFromCloud(cloud, []byte(cacert)) } func NewInstanceService() (*InstanceService, error) { cloud := clientconfig.Cloud{} - return NewInstanceServiceFromCloud(cloud) + return NewInstanceServiceFromCloud(cloud, nil) } -func NewInstanceServiceFromCloud(cloud clientconfig.Cloud) (*InstanceService, error) { +func NewInstanceServiceFromCloud(cloud clientconfig.Cloud, cert []byte) (*InstanceService, error) { clientOpts := new(clientconfig.ClientOpts) - var opts *gophercloud.AuthOptions if cloud.AuthInfo != nil { clientOpts.AuthInfo = cloud.AuthInfo @@ -193,9 +215,30 @@ func NewInstanceServiceFromCloud(cloud clientconfig.Cloud) (*InstanceService, er opts.AllowReauth = true - provider, err := openstack.AuthenticatedClient(*opts) + provider, err := openstack.NewClient(opts.IdentityEndpoint) + if err != nil { + return nil, fmt.Errorf("Create new provider client failed: %v", err) + } + + if cert != nil { + certPool, err := x509.SystemCertPool() + if err != nil { + return nil, fmt.Errorf("Create system cert pool failed: %v", err) + } + certPool.AppendCertsFromPEM(cert) + client := http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + RootCAs: certPool, + }, + }, + } + provider.HTTPClient = client + } + + err = openstack.Authenticate(provider, *opts) if err != nil { - return nil, fmt.Errorf("Create providerClient err: %v", err) + return nil, fmt.Errorf("Failed to authenticate provider client: %v", err) } identityClient, err := openstack.NewIdentityV3(provider, gophercloud.EndpointOpts{