diff --git a/builtin/providers/openstack/config.go b/builtin/providers/openstack/config.go index e4c6913fa..98d638ce7 100644 --- a/builtin/providers/openstack/config.go +++ b/builtin/providers/openstack/config.go @@ -12,43 +12,53 @@ import ( ) type Config struct { - Username string - UserID string - Password string - Token string - IdentityEndpoint string - TenantID string - TenantName string - DomainID string - DomainName string - Insecure bool - EndpointType string CACertFile string ClientCertFile string ClientKeyFile string + DomainID string + DomainName string + EndpointType string + IdentityEndpoint string + Insecure bool + Password string + TenantID string + TenantName string + Token string + Username string + UserID string osClient *gophercloud.ProviderClient } func (c *Config) loadAndValidate() error { + validEndpoint := false + validEndpoints := []string{ + "internal", "internalURL", + "admin", "adminURL", + "public", "publicURL", + "", + } - if c.EndpointType != "internal" && c.EndpointType != "internalURL" && - c.EndpointType != "admin" && c.EndpointType != "adminURL" && - c.EndpointType != "public" && c.EndpointType != "publicURL" && - c.EndpointType != "" { + for _, endpoint := range validEndpoints { + if c.EndpointType == endpoint { + validEndpoint = true + } + } + + if !validEndpoint { return fmt.Errorf("Invalid endpoint type provided") } ao := gophercloud.AuthOptions{ - Username: c.Username, - UserID: c.UserID, - Password: c.Password, - TokenID: c.Token, - IdentityEndpoint: c.IdentityEndpoint, - TenantID: c.TenantID, - TenantName: c.TenantName, DomainID: c.DomainID, DomainName: c.DomainName, + IdentityEndpoint: c.IdentityEndpoint, + Password: c.Password, + TenantID: c.TenantID, + TenantName: c.TenantName, + TokenID: c.Token, + Username: c.Username, + UserID: c.UserID, } client, err := openstack.NewClient(ao.IdentityEndpoint) @@ -58,7 +68,6 @@ func (c *Config) loadAndValidate() error { config := &tls.Config{} if c.CACertFile != "" { - caCert, err := ioutil.ReadFile(c.CACertFile) if err != nil { return err @@ -68,6 +77,7 @@ func (c *Config) loadAndValidate() error { caCertPool.AppendCertsFromPEM(caCert) config.RootCAs = caCertPool } + if c.Insecure { config.InsecureSkipVerify = true } @@ -81,6 +91,7 @@ func (c *Config) loadAndValidate() error { config.Certificates = []tls.Certificate{cert} config.BuildNameToCertificate() } + transport := &http.Transport{Proxy: http.ProxyFromEnvironment, TLSClientConfig: config} client.HTTPClient.Transport = transport diff --git a/builtin/providers/openstack/provider.go b/builtin/providers/openstack/provider.go index 0211d4756..e6ef6e32f 100644 --- a/builtin/providers/openstack/provider.go +++ b/builtin/providers/openstack/provider.go @@ -17,71 +17,113 @@ func Provider() terraform.ResourceProvider { Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("OS_AUTH_URL", nil), + Description: descriptions["auth_url"], }, + "user_name": &schema.Schema{ Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("OS_USERNAME", ""), + Description: descriptions["user_name"], }, + "user_id": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Default: "", + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("OS_USER_ID", ""), + Description: descriptions["user_name"], }, + "tenant_id": &schema.Schema{ Type: schema.TypeString, Optional: true, - Default: "", + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "OS_TENANT_ID", + "OS_PROJECT_ID", + }, ""), + Description: descriptions["tenant_id"], }, + "tenant_name": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - DefaultFunc: schema.EnvDefaultFunc("OS_TENANT_NAME", nil), + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "OS_TENANT_NAME", + "OS_PROJECT_NAME", + }, ""), + Description: descriptions["tenant_name"], }, + "password": &schema.Schema{ Type: schema.TypeString, Optional: true, + Sensitive: true, DefaultFunc: schema.EnvDefaultFunc("OS_PASSWORD", ""), + Description: descriptions["password"], }, + "token": &schema.Schema{ Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("OS_AUTH_TOKEN", ""), + Description: descriptions["token"], }, + "domain_id": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - DefaultFunc: schema.EnvDefaultFunc("OS_DOMAIN_ID", ""), - }, - "domain_name": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - DefaultFunc: schema.EnvDefaultFunc("OS_DOMAIN_NAME", ""), - }, - "insecure": &schema.Schema{ - Type: schema.TypeBool, + Type: schema.TypeString, Optional: true, - Default: false, + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "OS_USER_DOMAIN_ID", + "OS_PROJECT_DOMAIN_ID", + "OS_DOMAIN_ID", + }, ""), + Description: descriptions["domain_id"], }, + + "domain_name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "OS_USER_DOMAIN_NAME", + "OS_PROJECT_DOMAIN_NAME", + "OS_DOMAIN_NAME", + "OS_DEFAULT_DOMAIN", + }, ""), + Description: descriptions["domain_name"], + }, + + "insecure": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("OS_INSECURE", ""), + Description: descriptions["insecure"], + }, + "endpoint_type": &schema.Schema{ Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("OS_ENDPOINT_TYPE", ""), }, + "cacert_file": &schema.Schema{ Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("OS_CACERT", ""), + Description: descriptions["cacert_file"], }, + "cert": &schema.Schema{ Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("OS_CERT", ""), + Description: descriptions["cert"], }, + "key": &schema.Schema{ Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("OS_KEY", ""), + Description: descriptions["key"], }, }, @@ -121,22 +163,58 @@ func Provider() terraform.ResourceProvider { } } +var descriptions map[string]string + +func init() { + descriptions = map[string]string{ + "auth_url": "The Identity authentication URL.", + + "user_name": "Username to login with.", + + "user_id": "User ID to login with.", + + "tenant_id": "The ID of the Tenant (Identity v2) or Project (Identity v3)\n" + + "to login with.", + + "tenant_name": "The name of the Tenant (Identity v2) or Project (Identity v3)\n" + + "to login with.", + + "password": "Password to login with.", + + "token": "Authentication token to use as an alternative to username/password.", + + "domain_id": "The ID of the Domain to scope to (Identity v3).", + + "domain_name": "The name of the Domain to scope to (Identity v3).", + + "insecure": "Trust self-signed certificates.", + + "cacert_file": "A Custom CA certificate.", + + "endpoint_type": "The catalog endpoint type to use.", + + "cert": "A client certificate to authenticate with.", + + "key": "A client private key to authenticate with.", + } +} + func configureProvider(d *schema.ResourceData) (interface{}, error) { config := Config{ + CACertFile: d.Get("cacert_file").(string), + ClientCertFile: d.Get("cert").(string), + ClientKeyFile: d.Get("key").(string), + DomainID: d.Get("domain_id").(string), + DomainName: d.Get("domain_name").(string), + EndpointType: d.Get("endpoint_type").(string), IdentityEndpoint: d.Get("auth_url").(string), - Username: d.Get("user_name").(string), - UserID: d.Get("user_id").(string), + Insecure: d.Get("insecure").(bool), Password: d.Get("password").(string), Token: d.Get("token").(string), TenantID: d.Get("tenant_id").(string), TenantName: d.Get("tenant_name").(string), - DomainID: d.Get("domain_id").(string), - DomainName: d.Get("domain_name").(string), - Insecure: d.Get("insecure").(bool), - EndpointType: d.Get("endpoint_type").(string), - CACertFile: d.Get("cacert_file").(string), - ClientCertFile: d.Get("cert").(string), - ClientKeyFile: d.Get("key").(string), + Username: d.Get("user_name").(string), + UserID: d.Get("user_id").(string), } if err := config.loadAndValidate(); err != nil { diff --git a/website/source/docs/providers/openstack/index.html.markdown b/website/source/docs/providers/openstack/index.html.markdown index 22db5a5f1..9711cfbb2 100644 --- a/website/source/docs/providers/openstack/index.html.markdown +++ b/website/source/docs/providers/openstack/index.html.markdown @@ -35,50 +35,56 @@ resource "openstack_compute_instance_v2" "test-server" { The following arguments are supported: -* `auth_url` - (Required) If omitted, the `OS_AUTH_URL` environment - variable is used. +* `auth_url` - (Required) The Identity authentication URL. If omitted, the + `OS_AUTH_URL` environment variable is used. -* `user_name` - (Optional; Required for Identity V2) If omitted, the - `OS_USERNAME` environment variable is used. +* `user_name` - (Optional) The Username to login with. If omitted, the + `OS_USERNAME` environment variable is used. -* `user_id` - (Optional) +* `user_id` - (Optional) The User ID to login with. If omitted, the + `OS_USER_ID` environment variable is used. -* `password` - (Optional; Required if not using `api_key`) If omitted, the - `OS_PASSWORD` environment variable is used. +* `tenant_id` - (Optional) The ID of the Tenant (Identity v2) or Project + (Identity v3) to login with. If omitted, the `OS_TENANT_ID` or + `OS_PROJECT_ID` environment variables are used. + +* `tenant_name` - (Optional) The Name of the Tenant (Identity v2) or Project + (Identity v3) to login with. If omitted, the `OS_TENANT_NAME` or + `OS_PROJECT_NAME` environment variable are used. + +* `password` - (Optional) The Password to login with. If omitted, the + `OS_PASSWORD` environment variable is used. * `token` - (Optional; Required if not using `user_name` and `password`) - A token is an expiring, temporary means of access issued via the - Keystone service. By specifying a token, you do not have to - specify a username/password combination, since the token was - already created by a username/password out of band of Terraform. - If omitted, the `OS_AUTH_TOKEN` environment variable is used. + A token is an expiring, temporary means of access issued via the Keystone + service. By specifying a token, you do not have to specify a username/password + combination, since the token was already created by a username/password out of + band of Terraform. If omitted, the `OS_AUTH_TOKEN` environment variable is used. -* `domain_id` - (Optional) If omitted, the `OS_DOMAIN_ID` environment - variable is used. +* `domain_id` - (Optional) The ID of the Domain to scope to (Identity v3). If + If omitted, the following environment variables are checked (in this order): + `OS_USER_DOMAIN_ID`, `OS_PROJECT_DOMAIN_ID`, `OS_DOMAIN_ID`. -* `domain_name` - (Optional) If omitted, the `OS_DOMAIN_NAME` - environment variable is used. +* `domain_name` - (Optional) The Name of the Domain to scope to (Identity v3). + If omitted, the following environment variables are checked (in this order): + `OS_USER_DOMAIN_NAME`, `OS_PROJECT_DOMAIN_NAME`, `OS_DOMAIN_NAME`, + `DEFAULT_DOMAIN`. -* `tenant_id` - (Optional) - -* `tenant_name` - (Optional) If omitted, the `OS_TENANT_NAME` environment - variable is used. - -* `insecure` - (Optional) Explicitly allow the provider to perform - "insecure" SSL requests. If omitted, default value is `false` +* `insecure` - (Optional) Trust self-signed SSL certificates. If omitted, the + `OS_INSECURE` environment variable is used. * `cacert_file` - (Optional) Specify a custom CA certificate when communicating - over SSL. If omitted, the `OS_CACERT` environment variable is used. + over SSL. If omitted, the `OS_CACERT` environment variable is used. * `cert` - (Optional) Specify client certificate file for SSL client - authentication. If omitted the `OS_CERT` environment variable is used. + authentication. If omitted the `OS_CERT` environment variable is used. * `key` - (Optional) Specify client private key file for SSL client - authentication. If omitted the `OS_KEY` environment variable is used. + authentication. If omitted the `OS_KEY` environment variable is used. * `endpoint_type` - (Optional) Specify which type of endpoint to use from the - service catalog. It can be set using the OS_ENDPOINT_TYPE environment - variable. If not set, public endpoints is used. + service catalog. It can be set using the OS_ENDPOINT_TYPE environment + variable. If not set, public endpoints is used. ## Rackspace Compatibility