provider/openstack: Openstack Provider Updates (#9725)
* provider/openstack: Adding Identity v3 compatible environment variables * provider/openstack: Adding missing environment variables * provider/openstack: line spacing for provider options * provider/openstack: Making password sensitive * provider/openstack: Adding descriptions to provider options * provider/openstack: Clean up provider documentation * provider/openstack: clean up EndpointType check
This commit is contained in:
parent
9b2b21b583
commit
266b5ab598
|
@ -12,43 +12,53 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
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
|
CACertFile string
|
||||||
ClientCertFile string
|
ClientCertFile string
|
||||||
ClientKeyFile 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
|
osClient *gophercloud.ProviderClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) loadAndValidate() error {
|
func (c *Config) loadAndValidate() error {
|
||||||
|
validEndpoint := false
|
||||||
|
validEndpoints := []string{
|
||||||
|
"internal", "internalURL",
|
||||||
|
"admin", "adminURL",
|
||||||
|
"public", "publicURL",
|
||||||
|
"",
|
||||||
|
}
|
||||||
|
|
||||||
if c.EndpointType != "internal" && c.EndpointType != "internalURL" &&
|
for _, endpoint := range validEndpoints {
|
||||||
c.EndpointType != "admin" && c.EndpointType != "adminURL" &&
|
if c.EndpointType == endpoint {
|
||||||
c.EndpointType != "public" && c.EndpointType != "publicURL" &&
|
validEndpoint = true
|
||||||
c.EndpointType != "" {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !validEndpoint {
|
||||||
return fmt.Errorf("Invalid endpoint type provided")
|
return fmt.Errorf("Invalid endpoint type provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
ao := gophercloud.AuthOptions{
|
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,
|
DomainID: c.DomainID,
|
||||||
DomainName: c.DomainName,
|
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)
|
client, err := openstack.NewClient(ao.IdentityEndpoint)
|
||||||
|
@ -58,7 +68,6 @@ func (c *Config) loadAndValidate() error {
|
||||||
|
|
||||||
config := &tls.Config{}
|
config := &tls.Config{}
|
||||||
if c.CACertFile != "" {
|
if c.CACertFile != "" {
|
||||||
|
|
||||||
caCert, err := ioutil.ReadFile(c.CACertFile)
|
caCert, err := ioutil.ReadFile(c.CACertFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -68,6 +77,7 @@ func (c *Config) loadAndValidate() error {
|
||||||
caCertPool.AppendCertsFromPEM(caCert)
|
caCertPool.AppendCertsFromPEM(caCert)
|
||||||
config.RootCAs = caCertPool
|
config.RootCAs = caCertPool
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Insecure {
|
if c.Insecure {
|
||||||
config.InsecureSkipVerify = true
|
config.InsecureSkipVerify = true
|
||||||
}
|
}
|
||||||
|
@ -81,6 +91,7 @@ func (c *Config) loadAndValidate() error {
|
||||||
config.Certificates = []tls.Certificate{cert}
|
config.Certificates = []tls.Certificate{cert}
|
||||||
config.BuildNameToCertificate()
|
config.BuildNameToCertificate()
|
||||||
}
|
}
|
||||||
|
|
||||||
transport := &http.Transport{Proxy: http.ProxyFromEnvironment, TLSClientConfig: config}
|
transport := &http.Transport{Proxy: http.ProxyFromEnvironment, TLSClientConfig: config}
|
||||||
client.HTTPClient.Transport = transport
|
client.HTTPClient.Transport = transport
|
||||||
|
|
||||||
|
|
|
@ -17,71 +17,113 @@ func Provider() terraform.ResourceProvider {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("OS_AUTH_URL", nil),
|
DefaultFunc: schema.EnvDefaultFunc("OS_AUTH_URL", nil),
|
||||||
|
Description: descriptions["auth_url"],
|
||||||
},
|
},
|
||||||
|
|
||||||
"user_name": &schema.Schema{
|
"user_name": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("OS_USERNAME", ""),
|
DefaultFunc: schema.EnvDefaultFunc("OS_USERNAME", ""),
|
||||||
|
Description: descriptions["user_name"],
|
||||||
},
|
},
|
||||||
|
|
||||||
"user_id": &schema.Schema{
|
"user_id": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Default: "",
|
DefaultFunc: schema.EnvDefaultFunc("OS_USER_ID", ""),
|
||||||
|
Description: descriptions["user_name"],
|
||||||
},
|
},
|
||||||
|
|
||||||
"tenant_id": &schema.Schema{
|
"tenant_id": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Default: "",
|
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
|
||||||
|
"OS_TENANT_ID",
|
||||||
|
"OS_PROJECT_ID",
|
||||||
|
}, ""),
|
||||||
|
Description: descriptions["tenant_id"],
|
||||||
},
|
},
|
||||||
|
|
||||||
"tenant_name": &schema.Schema{
|
"tenant_name": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("OS_TENANT_NAME", nil),
|
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
|
||||||
|
"OS_TENANT_NAME",
|
||||||
|
"OS_PROJECT_NAME",
|
||||||
|
}, ""),
|
||||||
|
Description: descriptions["tenant_name"],
|
||||||
},
|
},
|
||||||
|
|
||||||
"password": &schema.Schema{
|
"password": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
Sensitive: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("OS_PASSWORD", ""),
|
DefaultFunc: schema.EnvDefaultFunc("OS_PASSWORD", ""),
|
||||||
|
Description: descriptions["password"],
|
||||||
},
|
},
|
||||||
|
|
||||||
"token": &schema.Schema{
|
"token": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("OS_AUTH_TOKEN", ""),
|
DefaultFunc: schema.EnvDefaultFunc("OS_AUTH_TOKEN", ""),
|
||||||
|
Description: descriptions["token"],
|
||||||
},
|
},
|
||||||
|
|
||||||
"domain_id": &schema.Schema{
|
"domain_id": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("OS_DOMAIN_ID", ""),
|
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
|
||||||
|
"OS_USER_DOMAIN_ID",
|
||||||
|
"OS_PROJECT_DOMAIN_ID",
|
||||||
|
"OS_DOMAIN_ID",
|
||||||
|
}, ""),
|
||||||
|
Description: descriptions["domain_id"],
|
||||||
},
|
},
|
||||||
|
|
||||||
"domain_name": &schema.Schema{
|
"domain_name": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("OS_DOMAIN_NAME", ""),
|
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{
|
"insecure": &schema.Schema{
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeBool,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Default: false,
|
DefaultFunc: schema.EnvDefaultFunc("OS_INSECURE", ""),
|
||||||
|
Description: descriptions["insecure"],
|
||||||
},
|
},
|
||||||
|
|
||||||
"endpoint_type": &schema.Schema{
|
"endpoint_type": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("OS_ENDPOINT_TYPE", ""),
|
DefaultFunc: schema.EnvDefaultFunc("OS_ENDPOINT_TYPE", ""),
|
||||||
},
|
},
|
||||||
|
|
||||||
"cacert_file": &schema.Schema{
|
"cacert_file": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("OS_CACERT", ""),
|
DefaultFunc: schema.EnvDefaultFunc("OS_CACERT", ""),
|
||||||
|
Description: descriptions["cacert_file"],
|
||||||
},
|
},
|
||||||
|
|
||||||
"cert": &schema.Schema{
|
"cert": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("OS_CERT", ""),
|
DefaultFunc: schema.EnvDefaultFunc("OS_CERT", ""),
|
||||||
|
Description: descriptions["cert"],
|
||||||
},
|
},
|
||||||
|
|
||||||
"key": &schema.Schema{
|
"key": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("OS_KEY", ""),
|
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) {
|
func configureProvider(d *schema.ResourceData) (interface{}, error) {
|
||||||
config := Config{
|
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),
|
IdentityEndpoint: d.Get("auth_url").(string),
|
||||||
Username: d.Get("user_name").(string),
|
Insecure: d.Get("insecure").(bool),
|
||||||
UserID: d.Get("user_id").(string),
|
|
||||||
Password: d.Get("password").(string),
|
Password: d.Get("password").(string),
|
||||||
Token: d.Get("token").(string),
|
Token: d.Get("token").(string),
|
||||||
TenantID: d.Get("tenant_id").(string),
|
TenantID: d.Get("tenant_id").(string),
|
||||||
TenantName: d.Get("tenant_name").(string),
|
TenantName: d.Get("tenant_name").(string),
|
||||||
DomainID: d.Get("domain_id").(string),
|
Username: d.Get("user_name").(string),
|
||||||
DomainName: d.Get("domain_name").(string),
|
UserID: d.Get("user_id").(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),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := config.loadAndValidate(); err != nil {
|
if err := config.loadAndValidate(); err != nil {
|
||||||
|
|
|
@ -35,37 +35,43 @@ resource "openstack_compute_instance_v2" "test-server" {
|
||||||
|
|
||||||
The following arguments are supported:
|
The following arguments are supported:
|
||||||
|
|
||||||
* `auth_url` - (Required) If omitted, the `OS_AUTH_URL` environment
|
* `auth_url` - (Required) The Identity authentication URL. If omitted, the
|
||||||
variable is used.
|
`OS_AUTH_URL` environment variable is used.
|
||||||
|
|
||||||
* `user_name` - (Optional; Required for Identity V2) If omitted, the
|
* `user_name` - (Optional) The Username to login with. If omitted, the
|
||||||
`OS_USERNAME` environment variable is used.
|
`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
|
* `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.
|
`OS_PASSWORD` environment variable is used.
|
||||||
|
|
||||||
* `token` - (Optional; Required if not using `user_name` and `password`)
|
* `token` - (Optional; Required if not using `user_name` and `password`)
|
||||||
A token is an expiring, temporary means of access issued via the
|
A token is an expiring, temporary means of access issued via the Keystone
|
||||||
Keystone service. By specifying a token, you do not have to
|
service. By specifying a token, you do not have to specify a username/password
|
||||||
specify a username/password combination, since the token was
|
combination, since the token was already created by a username/password out of
|
||||||
already created by a username/password out of band of Terraform.
|
band of Terraform. If omitted, the `OS_AUTH_TOKEN` environment variable is used.
|
||||||
If omitted, the `OS_AUTH_TOKEN` environment variable is used.
|
|
||||||
|
|
||||||
* `domain_id` - (Optional) If omitted, the `OS_DOMAIN_ID` environment
|
* `domain_id` - (Optional) The ID of the Domain to scope to (Identity v3). If
|
||||||
variable is used.
|
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`
|
* `domain_name` - (Optional) The Name of the Domain to scope to (Identity v3).
|
||||||
environment variable is used.
|
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)
|
* `insecure` - (Optional) Trust self-signed SSL certificates. If omitted, the
|
||||||
|
`OS_INSECURE` environment variable is used.
|
||||||
* `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`
|
|
||||||
|
|
||||||
* `cacert_file` - (Optional) Specify a custom CA certificate when communicating
|
* `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.
|
||||||
|
|
Loading…
Reference in New Issue