Browse Source

Add support for OS_CACERT in Openstack driver

This enables using docker-machine's openstack driver without having to
resort to using the --insecure flag.

Signed-off-by: Mathias Nyman <mathias.nyman@iki.fi>
Mathias Nyman 2 years ago
parent
commit
bdd3b24cdc
3 changed files with 45 additions and 8 deletions
  1. 2
    0
      docs/drivers/openstack.md
  2. 35
    8
      drivers/openstack/client.go
  3. 8
    0
      drivers/openstack/openstack.go

+ 2
- 0
docs/drivers/openstack.md View File

@@ -25,6 +25,7 @@ Options:
25 25
 
26 26
 -   `--openstack-active-timeout`: The timeout in seconds until the OpenStack instance must be active.
27 27
 -   `--openstack-availability-zone`: The availability zone in which to launch the server.
28
+-   `--openstack-cacert`: The CA certificate bundle to verify against.
28 29
 -   `--openstack-domain-name` or `--openstack-domain-id`: Domain to use for authentication (Keystone v3 only).
29 30
 -   `--openstack-endpoint-type`: Endpoint type can be `internalURL`, `adminURL` on `publicURL`. If is a helper for the driver
30 31
     to choose the right URL in the OpenStack service catalog. If not provided the default id `publicURL`
@@ -52,6 +53,7 @@ Environment variables and default values:
52 53
 | `--openstack-active-timeout`    | `OS_ACTIVE_TIMEOUT`    | `200`       |
53 54
 | `--openstack-auth-url`          | `OS_AUTH_URL`          | -           |
54 55
 | `--openstack-availability-zone` | `OS_AVAILABILITY_ZONE` | -           |
56
+| `--openstack-cacert`            | `OS_CACERT             | -           |
55 57
 | `--openstack-domain-id`         | `OS_DOMAIN_ID`         | -           |
56 58
 | `--openstack-domain-name`       | `OS_DOMAIN_NAME`       | -           |
57 59
 | `--openstack-endpoint-type`     | `OS_ENDPOINT_TYPE`     | `publicURL` |

+ 35
- 8
drivers/openstack/client.go View File

@@ -2,7 +2,9 @@ package openstack
2 2
 
3 3
 import (
4 4
 	"crypto/tls"
5
+	"crypto/x509"
5 6
 	"fmt"
7
+	"io/ioutil"
6 8
 	"net/http"
7 9
 	"time"
8 10
 
@@ -532,6 +534,7 @@ func (c *GenericClient) Authenticate(d *Driver) error {
532 534
 	log.Debug("Authenticating...", map[string]interface{}{
533 535
 		"AuthUrl":    d.AuthUrl,
534 536
 		"Insecure":   d.Insecure,
537
+		"CaCert":     d.CaCert,
535 538
 		"DomainID":   d.DomainID,
536 539
 		"DomainName": d.DomainName,
537 540
 		"Username":   d.Username,
@@ -555,21 +558,45 @@ func (c *GenericClient) Authenticate(d *Driver) error {
555 558
 		return err
556 559
 	}
557 560
 
558
-	provider.UserAgent.Prepend(fmt.Sprintf("docker-machine/v%d", version.APIVersion))
561
+	c.Provider = provider
562
+
563
+	c.Provider.UserAgent.Prepend(fmt.Sprintf("docker-machine/v%d", version.APIVersion))
559 564
 
560
-	if d.Insecure {
561
-		// Configure custom TLS settings.
562
-		config := &tls.Config{InsecureSkipVerify: true}
563
-		transport := &http.Transport{TLSClientConfig: config}
564
-		provider.HTTPClient.Transport = transport
565
+	err = c.SetTLSConfig(d)
566
+	if err != nil {
567
+		return err
565 568
 	}
566 569
 
567
-	err = openstack.Authenticate(provider, opts)
570
+	err = openstack.Authenticate(c.Provider, opts)
568 571
 	if err != nil {
569 572
 		return err
570 573
 	}
571 574
 
572
-	c.Provider = provider
575
+	return nil
576
+}
577
+
578
+func (c *GenericClient) SetTLSConfig(d *Driver) error {
579
+
580
+	config := &tls.Config{}
581
+	config.InsecureSkipVerify = d.Insecure
582
+
583
+	if d.CaCert != "" {
584
+		// Use custom CA certificate(s) for root of trust
585
+		certpool := x509.NewCertPool()
586
+		pem, err := ioutil.ReadFile(d.CaCert)
587
+		if err != nil {
588
+			log.Error("Unable to read specified CA certificate(s)")
589
+			return err
590
+		}
591
+
592
+		ok := certpool.AppendCertsFromPEM(pem)
593
+		if !ok {
594
+			return fmt.Errorf("Ill-formed CA certificate(s) PEM file")
595
+		}
596
+		config.RootCAs = certpool
597
+	}
573 598
 
599
+	transport := &http.Transport{TLSClientConfig: config}
600
+	c.Provider.HTTPClient.Transport = transport
574 601
 	return nil
575 602
 }

+ 8
- 0
drivers/openstack/openstack.go View File

@@ -20,6 +20,7 @@ type Driver struct {
20 20
 	AuthUrl          string
21 21
 	ActiveTimeout    int
22 22
 	Insecure         bool
23
+	CaCert           string
23 24
 	DomainID         string
24 25
 	DomainName       string
25 26
 	Username         string
@@ -66,6 +67,12 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
66 67
 			Name:   "openstack-insecure",
67 68
 			Usage:  "Disable TLS credential checking.",
68 69
 		},
70
+		mcnflag.StringFlag{
71
+			EnvVar: "OS_CACERT",
72
+			Name:   "openstack-cacert",
73
+			Usage:  "CA certificate bundle to verify against",
74
+			Value:  "",
75
+		},
69 76
 		mcnflag.StringFlag{
70 77
 			EnvVar: "OS_DOMAIN_ID",
71 78
 			Name:   "openstack-domain-id",
@@ -252,6 +259,7 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
252 259
 	d.AuthUrl = flags.String("openstack-auth-url")
253 260
 	d.ActiveTimeout = flags.Int("openstack-active-timeout")
254 261
 	d.Insecure = flags.Bool("openstack-insecure")
262
+	d.CaCert = flags.String("openstack-cacert")
255 263
 	d.DomainID = flags.String("openstack-domain-id")
256 264
 	d.DomainName = flags.String("openstack-domain-name")
257 265
 	d.Username = flags.String("openstack-username")

Loading…
Cancel
Save