Merge pull request #4921 from takaishi/support-client-certificate

OpenStack: Support client certificate
This commit is contained in:
Matthew Hooker 2017-05-24 11:08:24 -07:00 committed by GitHub
commit 21c4d66143
2 changed files with 51 additions and 4 deletions

View File

@ -3,11 +3,14 @@ package openstack
import ( import (
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"net/http"
"os" "os"
"crypto/x509"
"io/ioutil"
"github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack" "github.com/gophercloud/gophercloud/openstack"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/packer/template/interpolate" "github.com/hashicorp/packer/template/interpolate"
) )
@ -24,6 +27,9 @@ type AccessConfig struct {
Insecure bool `mapstructure:"insecure"` Insecure bool `mapstructure:"insecure"`
Region string `mapstructure:"region"` Region string `mapstructure:"region"`
EndpointType string `mapstructure:"endpoint_type"` EndpointType string `mapstructure:"endpoint_type"`
CACertFile string `mapstructure:"cacert"`
ClientCertFile string `mapstructure:"cert"`
ClientKeyFile string `mapstructure:"key"`
osClient *gophercloud.ProviderClient osClient *gophercloud.ProviderClient
} }
@ -53,6 +59,15 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
if c.Username == "" { if c.Username == "" {
c.Username = os.Getenv("SDK_USERNAME") c.Username = os.Getenv("SDK_USERNAME")
} }
if c.CACertFile == "" {
c.CACertFile = os.Getenv("OS_CACERT")
}
if c.ClientCertFile == "" {
c.ClientCertFile = os.Getenv("OS_CERT")
}
if c.ClientKeyFile == "" {
c.ClientKeyFile = os.Getenv("OS_KEY")
}
// Get as much as possible from the end // Get as much as possible from the end
ao, _ := openstack.AuthOptionsFromEnv() ao, _ := openstack.AuthOptionsFromEnv()
@ -85,14 +100,37 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
return []error{err} return []error{err}
} }
tls_config := &tls.Config{}
if c.CACertFile != "" {
caCert, err := ioutil.ReadFile(c.CACertFile)
if err != nil {
return []error{err}
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tls_config.RootCAs = caCertPool
}
// If we have insecure set, then create a custom HTTP client that // If we have insecure set, then create a custom HTTP client that
// ignores SSL errors. // ignores SSL errors.
if c.Insecure { if c.Insecure {
config := &tls.Config{InsecureSkipVerify: true} tls_config.InsecureSkipVerify = true
transport := &http.Transport{TLSClientConfig: config}
client.HTTPClient.Transport = transport
} }
if c.ClientCertFile != "" && c.ClientKeyFile != "" {
cert, err := tls.LoadX509KeyPair(c.ClientCertFile, c.ClientKeyFile)
if err != nil {
return []error{err}
}
tls_config.Certificates = []tls.Certificate{cert}
}
transport := cleanhttp.DefaultTransport()
transport.TLSClientConfig = tls_config
client.HTTPClient.Transport = transport
// Auth // Auth
err = openstack.Authenticate(client, ao) err = openstack.Authenticate(client, ao)
if err != nil { if err != nil {

View File

@ -76,9 +76,15 @@ builder.
server in. If this isn't specified, the default enforced by your OpenStack server in. If this isn't specified, the default enforced by your OpenStack
cluster will be used. This may be required for some OpenStack clusters. cluster will be used. This may be required for some OpenStack clusters.
- `cacert` (string) - Custom CA certificate file path.
If ommited the OS_CACERT environment variable can be used.
- `config_drive` (boolean) - Whether or not nova should use ConfigDrive for - `config_drive` (boolean) - Whether or not nova should use ConfigDrive for
cloud-init metadata. cloud-init metadata.
- `cert` (string) - Client certificate file path for SSL client authentication.
If omitted the OS_CERT environment variable can be used.
- `domain_name` or `domain_id` (string) - The Domain name or ID you are - `domain_name` or `domain_id` (string) - The Domain name or ID you are
authenticating with. OpenStack installations require this if identity v3 is used. authenticating with. OpenStack installations require this if identity v3 is used.
Packer will use the environment variable `OS_DOMAIN_NAME` or `OS_DOMAIN_ID`, if set. Packer will use the environment variable `OS_DOMAIN_NAME` or `OS_DOMAIN_ID`, if set.
@ -102,6 +108,9 @@ builder.
- `insecure` (boolean) - Whether or not the connection to OpenStack can be - `insecure` (boolean) - Whether or not the connection to OpenStack can be
done over an insecure connection. By default this is false. done over an insecure connection. By default this is false.
- `key` (string) - Client private key file path for SSL client authentication.
If ommited the OS_KEY environment variable can be used.
- `metadata` (object of key/value strings) - Glance metadata that will be - `metadata` (object of key/value strings) - Glance metadata that will be
applied to the image. applied to the image.