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>
This commit is contained in:
Mathias Nyman 2016-06-02 16:16:02 +03:00
parent c17f42fab5
commit bdd3b24cdc
3 changed files with 46 additions and 9 deletions

View File

@ -25,6 +25,7 @@ Options:
- `--openstack-active-timeout`: The timeout in seconds until the OpenStack instance must be active.
- `--openstack-availability-zone`: The availability zone in which to launch the server.
- `--openstack-cacert`: The CA certificate bundle to verify against.
- `--openstack-domain-name` or `--openstack-domain-id`: Domain to use for authentication (Keystone v3 only).
- `--openstack-endpoint-type`: Endpoint type can be `internalURL`, `adminURL` on `publicURL`. If is a helper for the driver
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:
| `--openstack-active-timeout` | `OS_ACTIVE_TIMEOUT` | `200` |
| `--openstack-auth-url` | `OS_AUTH_URL` | - |
| `--openstack-availability-zone` | `OS_AVAILABILITY_ZONE` | - |
| `--openstack-cacert` | `OS_CACERT | - |
| `--openstack-domain-id` | `OS_DOMAIN_ID` | - |
| `--openstack-domain-name` | `OS_DOMAIN_NAME` | - |
| `--openstack-endpoint-type` | `OS_ENDPOINT_TYPE` | `publicURL` |

View File

@ -2,7 +2,9 @@ package openstack
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"net/http"
"time"
@ -532,6 +534,7 @@ func (c *GenericClient) Authenticate(d *Driver) error {
log.Debug("Authenticating...", map[string]interface{}{
"AuthUrl": d.AuthUrl,
"Insecure": d.Insecure,
"CaCert": d.CaCert,
"DomainID": d.DomainID,
"DomainName": d.DomainName,
"Username": d.Username,
@ -555,21 +558,45 @@ func (c *GenericClient) Authenticate(d *Driver) error {
return err
}
provider.UserAgent.Prepend(fmt.Sprintf("docker-machine/v%d", version.APIVersion))
c.Provider = provider
if d.Insecure {
// Configure custom TLS settings.
config := &tls.Config{InsecureSkipVerify: true}
transport := &http.Transport{TLSClientConfig: config}
provider.HTTPClient.Transport = transport
}
c.Provider.UserAgent.Prepend(fmt.Sprintf("docker-machine/v%d", version.APIVersion))
err = openstack.Authenticate(provider, opts)
err = c.SetTLSConfig(d)
if err != nil {
return err
}
c.Provider = provider
err = openstack.Authenticate(c.Provider, opts)
if err != nil {
return err
}
return nil
}
func (c *GenericClient) SetTLSConfig(d *Driver) error {
config := &tls.Config{}
config.InsecureSkipVerify = d.Insecure
if d.CaCert != "" {
// Use custom CA certificate(s) for root of trust
certpool := x509.NewCertPool()
pem, err := ioutil.ReadFile(d.CaCert)
if err != nil {
log.Error("Unable to read specified CA certificate(s)")
return err
}
ok := certpool.AppendCertsFromPEM(pem)
if !ok {
return fmt.Errorf("Ill-formed CA certificate(s) PEM file")
}
config.RootCAs = certpool
}
transport := &http.Transport{TLSClientConfig: config}
c.Provider.HTTPClient.Transport = transport
return nil
}

View File

@ -20,6 +20,7 @@ type Driver struct {
AuthUrl string
ActiveTimeout int
Insecure bool
CaCert string
DomainID string
DomainName string
Username string
@ -66,6 +67,12 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
Name: "openstack-insecure",
Usage: "Disable TLS credential checking.",
},
mcnflag.StringFlag{
EnvVar: "OS_CACERT",
Name: "openstack-cacert",
Usage: "CA certificate bundle to verify against",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_DOMAIN_ID",
Name: "openstack-domain-id",
@ -252,6 +259,7 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.AuthUrl = flags.String("openstack-auth-url")
d.ActiveTimeout = flags.Int("openstack-active-timeout")
d.Insecure = flags.Bool("openstack-insecure")
d.CaCert = flags.String("openstack-cacert")
d.DomainID = flags.String("openstack-domain-id")
d.DomainName = flags.String("openstack-domain-name")
d.Username = flags.String("openstack-username")