openstack: Add support for token authorization and cloud.yaml

via config options `cloud` and `token` and environment variables
OS_CLOUD and OS_TOKEN.
This commit is contained in:
Matthew Hooker 2017-01-17 14:38:49 -08:00 committed by Rickard von Essen
parent 8f2fa9c8ec
commit 3bdf1f1849
2 changed files with 85 additions and 23 deletions

View File

@ -2,14 +2,14 @@ package openstack
import (
"crypto/tls"
"fmt"
"os"
"crypto/x509"
"fmt"
"io/ioutil"
"os"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack"
"github.com/gophercloud/utils/openstack/clientconfig"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/packer/template/interpolate"
)
@ -30,6 +30,8 @@ type AccessConfig struct {
CACertFile string `mapstructure:"cacert"`
ClientCertFile string `mapstructure:"cert"`
ClientKeyFile string `mapstructure:"key"`
Token string `mapstructure:"token"`
Cloud string `mapstructure:"cloud"`
osClient *gophercloud.ProviderClient
}
@ -42,10 +44,6 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
return []error{fmt.Errorf("Invalid endpoint type provided")}
}
if c.Region == "" {
c.Region = os.Getenv("OS_REGION_NAME")
}
// Legacy RackSpace stuff. We're keeping this around to keep things BC.
if c.Password == "" {
c.Password = os.Getenv("SDK_PASSWORD")
@ -59,6 +57,15 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
if c.Username == "" {
c.Username = os.Getenv("SDK_USERNAME")
}
// End RackSpace
if c.Cloud == "" {
c.Cloud = os.Getenv("OS_CLOUD")
}
if c.Region == "" {
c.Region = os.Getenv("OS_REGION_NAME")
}
if c.CACertFile == "" {
c.CACertFile = os.Getenv("OS_CACERT")
}
@ -69,8 +76,39 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
c.ClientKeyFile = os.Getenv("OS_KEY")
}
// Get as much as possible from the end
ao, _ := openstack.AuthOptionsFromEnv()
clientOpts := new(clientconfig.ClientOpts)
// If a cloud entry was given, base AuthOptions on a clouds.yaml file.
if c.Cloud != "" {
clientOpts.Cloud = c.Cloud
cloud, err := clientconfig.GetCloudFromYAML(clientOpts)
if err != nil {
return []error{err}
}
if c.Region == "" && cloud.RegionName != "" {
c.Region = cloud.RegionName
}
} else {
authInfo := &clientconfig.AuthInfo{
AuthURL: c.IdentityEndpoint,
DomainID: c.DomainID,
DomainName: c.DomainName,
Password: c.Password,
ProjectID: c.TenantID,
ProjectName: c.TenantName,
Token: c.Token,
Username: c.Username,
UserID: c.UserID,
}
clientOpts.AuthInfo = authInfo
}
ao, err := clientconfig.AuthOptions(clientOpts)
if err != nil {
return []error{err}
}
// Make sure we reauth as needed
ao.AllowReauth = true
@ -87,6 +125,7 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
{&c.TenantName, &ao.TenantName},
{&c.DomainID, &ao.DomainID},
{&c.DomainName, &ao.DomainName},
{&c.Token, &ao.TokenID},
}
for _, s := range overrides {
if *s.From != "" {
@ -132,7 +171,7 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
client.HTTPClient.Transport = transport
// Auth
err = openstack.Authenticate(client, ao)
err = openstack.Authenticate(client, *ao)
if err != nil {
return []error{err}
}

View File

@ -25,7 +25,7 @@ created. This simplifies configuration quite a bit.
The builder does *not* manage images. Once it creates an image, it is up to you
to use it or delete it.
~> **Note:** To use OpenStack builder with the OpenStack Newton (Oct 2016)
~> **Note:** To use OpenStack builder with the OpenStack Newton (Oct 2016)
or earlier, we recommend you use Packer v1.1.2 or earlier version.
~> **OpenStack Liberty or later requires OpenSSL!** To use the OpenStack
@ -56,7 +56,7 @@ builder.
- `identity_endpoint` (string) - The URL to the OpenStack Identity service.
If not specified, Packer will use the environment variables `OS_AUTH_URL`,
if set.
if set. This is not required if using `cloud.yaml`.
- `source_image` (string) - The ID or full URL to the base image to use. This
is the image that will be used to launch a new server and provision it.
@ -69,11 +69,14 @@ builder.
- `username` or `user_id` (string) - The username or id used to connect to
the OpenStack service. If not specified, Packer will use the environment
variable `OS_USERNAME` or `OS_USERID`, if set.
variable `OS_USERNAME` or `OS_USERID`, if set. This is not required if
using access token instead of password or if using `cloud.yaml`.
- `password` (string) - The password used to connect to the OpenStack service.
If not specified, Packer will use the environment variables `OS_PASSWORD`,
if set.
if set. This is not required if using access token instead of password or
if using `cloud.yaml`.
### Optional:
@ -82,14 +85,20 @@ builder.
cluster will be used. This may be required for some OpenStack clusters.
- `cacert` (string) - Custom CA certificate file path.
If omitted the OS\_CACERT environment variable can be used.
If omitted the `OS_CACERT` environment variable can be used.
- `cert` (string) - Client certificate file path for SSL client authentication.
If omitted the `OS_CERT` environment variable can be used.
- `cloud` (string) - An entry in a `clouds.yaml` file. See the OpenStack
os-client-config
[documentation](https://docs.openstack.org/os-client-config/latest/user/configuration.html)
for more information about `clouds.yaml` files. If omitted, the `OS_CLOUD`
environment variable is used.
- `config_drive` (boolean) - Whether or not nova should use ConfigDrive for
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
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.
@ -105,7 +114,7 @@ builder.
- `image_members` (array of strings) - List of members to add to the image
after creation. An image member is usually a project (also called the
“tenant”) with whom the image is shared.
"tenant") with whom the image is shared.
- `image_visibility` (string) - One of "public", "private", "shared", or
"community".
@ -114,7 +123,7 @@ builder.
done over an insecure connection. By default this is false.
- `key` (string) - Client private key file path for SSL client authentication.
If omitted the OS\_KEY environment variable can be used.
If omitted the `OS_KEY` environment variable can be used.
- `metadata` (object of key/value strings) - Glance metadata that will be
applied to the image.
@ -181,6 +190,9 @@ builder.
Packer will use the environment variable `OS_TENANT_NAME` or `OS_TENANT_ID`,
if set. Tenant is also called Project in later versions of OpenStack.
- `token` (string) - the token (id) to use with token based authorization.
Packer will use the environment variable `OS_TOKEN`, if set.
- `use_floating_ip` (boolean) - *Deprecated* use `floating_ip` or `floating_ip_pool`
instead.
@ -280,11 +292,12 @@ export OS_PROJECT_DOMAIN_NAME="mydomain"
## Notes on OpenStack Authorization
The simplest way to get all settings for authorization agains OpenStack is to
The simplest way to get all settings for authorization against OpenStack is to
go into the OpenStack Dashboard (Horizon) select your *Project* and navigate
*Project, Access & Security*, select *API Access* and *Download OpenStack RC
File v3*. Source the file, and select your wanted region by setting
environment variable `OS_REGION_NAME` or `OS_REGION_ID` and `export OS_TENANT_NAME=$OS_PROJECT_NAME` or `export OS_TENANT_ID=$OS_PROJECT_ID`.
File v3*. Source the file, and select your wanted region
by setting environment variable `OS_REGION_NAME` or `OS_REGION_ID` and
`export OS_TENANT_NAME=$OS_PROJECT_NAME` or `export OS_TENANT_ID=$OS_PROJECT_ID`.
~> `OS_TENANT_NAME` or `OS_TENANT_ID` must be used even with Identity v3,
`OS_PROJECT_NAME` and `OS_PROJECT_ID` has no effect in Packer.
@ -293,3 +306,13 @@ To troubleshoot authorization issues test you environment variables with the
OpenStack cli. It can be installed with
$ pip install --user python-openstackclient
### Authorize Using Tokens
To authorize with a access token only `identity_endpoint` and `token` is needed,
and possibly `tenant_name` or `tenant_id` depending on your token type. Or use
the following environment variables:
- `OS_AUTH_URL`
- `OS_TOKEN`
- One of `OS_TENANT_NAME` or `OS_TENANT_ID`