From 14aa30ed1dddf38d2b94d9004966e3273fe27c41 Mon Sep 17 00:00:00 2001 From: Mathieu Velten Date: Fri, 20 Oct 2017 11:46:49 +0200 Subject: [PATCH] Add support for custom CA certificate and insecure mode --- libstorage/drivers/storage/cinder/cinder.go | 8 ++++ .../storage/cinder/storage/cinder_storage.go | 43 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/libstorage/drivers/storage/cinder/cinder.go b/libstorage/drivers/storage/cinder/cinder.go index f87f86d10..7751e7244 100644 --- a/libstorage/drivers/storage/cinder/cinder.go +++ b/libstorage/drivers/storage/cinder/cinder.go @@ -57,6 +57,12 @@ const ( // ConfigSnapshotTimeout is the config key for the snapshot timeout ConfigSnapshotTimeout = Name + ".snapshotTimeout" + + // ConfigCACert is the config key for custom CA certificate (usually for self signed use case) + ConfigCACert = Name + ".CACert" + + // ConfigInsecure is the config ky to disable TLS verification of the server identity + ConfigInsecure = Name + ".insecure" ) func init() { @@ -77,5 +83,7 @@ func init() { r.Key(gofig.String, "", "10m", "", ConfigDeleteTimeout) r.Key(gofig.String, "", "10m", "", ConfigCreateTimeout) r.Key(gofig.String, "", "10m", "", ConfigSnapshotTimeout) + r.Key(gofig.String, "", "", "", ConfigCACert) + r.Key(gofig.Bool, "", false, "", ConfigInsecure) gofigCore.Register(r) } diff --git a/libstorage/drivers/storage/cinder/storage/cinder_storage.go b/libstorage/drivers/storage/cinder/storage/cinder_storage.go index d89d7e536..ccfdba7b1 100644 --- a/libstorage/drivers/storage/cinder/storage/cinder_storage.go +++ b/libstorage/drivers/storage/cinder/storage/cinder_storage.go @@ -1,6 +1,11 @@ package storage import ( + "crypto/tls" + "crypto/x509" + "errors" + "io/ioutil" + "net/http" "time" gofig "github.com/akutz/gofig/types" @@ -114,11 +119,19 @@ func (d *driver) Init(context types.Context, config gofig.Config) error { fields["trustId"] = hiddenText } + fields["caCert"] = d.caCert() + fields["insecure"] = d.insecure() + d.provider, err = openstack.NewClient(authOpts.IdentityEndpoint) if err != nil { return goof.WithFieldsE(fields, "error creating Keystone client", err) } + d.provider.HTTPClient, err = openstackHTTPClient(d.caCert(), d.insecure()) + if err != nil { + return goof.WithFieldsE(fields, "error overriding Gophercloud HTTP client", err) + } + if trustID != "" { authOptionsExt := trusts.AuthOptsExt{ TrustID: trustID, @@ -152,6 +165,28 @@ func (d *driver) Init(context types.Context, config gofig.Config) error { return nil } +func openstackHTTPClient(caCert string, insecure bool) (http.Client, error) { + if caCert == "" { + return http.Client{}, nil + } + + caCertPool := x509.NewCertPool() + caCertContent, err := ioutil.ReadFile(caCert) + if err != nil { + return http.Client{}, errors.New("Can't read certificate file") + } + caCertPool.AppendCertsFromPEM(caCertContent) + + tlsConfig := &tls.Config{ + RootCAs: caCertPool, + InsecureSkipVerify: insecure, + } + tlsConfig.BuildNameToCertificate() + transport := &http.Transport{TLSClientConfig: tlsConfig} + + return http.Client{Transport: transport}, nil +} + // InstanceInspect returns an instance. func (d *driver) InstanceInspect( ctx types.Context, @@ -851,3 +886,11 @@ func (d *driver) snapshotTimeout() time.Duration { } return val } + +func (d *driver) caCert() string { + return d.config.GetString(cinder.ConfigCACert) +} + +func (d *driver) insecure() bool { + return d.config.GetBool(cinder.ConfigInsecure) +}