diff --git a/pkg/apis/openstackproviderconfig/v1alpha1/types.go b/pkg/apis/openstackproviderconfig/v1alpha1/types.go index 8cb14be922..2c56686e2f 100644 --- a/pkg/apis/openstackproviderconfig/v1alpha1/types.go +++ b/pkg/apis/openstackproviderconfig/v1alpha1/types.go @@ -38,6 +38,9 @@ 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 f9d11c9ae4..9ef7734a8e 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" @@ -166,17 +169,16 @@ 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) + return NewInstanceServiceFromCloud(cloud, []byte(machineSpec.CertBundle)) } 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 @@ -186,16 +188,36 @@ func NewInstanceServiceFromCloud(cloud clientconfig.Cloud) (*InstanceService, er } opts, err := clientconfig.AuthOptions(clientOpts) - if err != nil { return nil, err } 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{