Skip to content

Commit 266b5ab

Browse files
jtopjianstack72
authored andcommitted
provider/openstack: Openstack Provider Updates (hashicorp#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
1 parent 9b2b21b commit 266b5ab

3 files changed

Lines changed: 169 additions & 74 deletions

File tree

builtin/providers/openstack/config.go

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,43 +12,53 @@ import (
1212
)
1313

1414
type Config struct {
15-
Username string
16-
UserID string
17-
Password string
18-
Token string
19-
IdentityEndpoint string
20-
TenantID string
21-
TenantName string
22-
DomainID string
23-
DomainName string
24-
Insecure bool
25-
EndpointType string
2615
CACertFile string
2716
ClientCertFile string
2817
ClientKeyFile string
18+
DomainID string
19+
DomainName string
20+
EndpointType string
21+
IdentityEndpoint string
22+
Insecure bool
23+
Password string
24+
TenantID string
25+
TenantName string
26+
Token string
27+
Username string
28+
UserID string
2929

3030
osClient *gophercloud.ProviderClient
3131
}
3232

3333
func (c *Config) loadAndValidate() error {
34+
validEndpoint := false
35+
validEndpoints := []string{
36+
"internal", "internalURL",
37+
"admin", "adminURL",
38+
"public", "publicURL",
39+
"",
40+
}
41+
42+
for _, endpoint := range validEndpoints {
43+
if c.EndpointType == endpoint {
44+
validEndpoint = true
45+
}
46+
}
3447

35-
if c.EndpointType != "internal" && c.EndpointType != "internalURL" &&
36-
c.EndpointType != "admin" && c.EndpointType != "adminURL" &&
37-
c.EndpointType != "public" && c.EndpointType != "publicURL" &&
38-
c.EndpointType != "" {
48+
if !validEndpoint {
3949
return fmt.Errorf("Invalid endpoint type provided")
4050
}
4151

4252
ao := gophercloud.AuthOptions{
43-
Username: c.Username,
44-
UserID: c.UserID,
45-
Password: c.Password,
46-
TokenID: c.Token,
53+
DomainID: c.DomainID,
54+
DomainName: c.DomainName,
4755
IdentityEndpoint: c.IdentityEndpoint,
56+
Password: c.Password,
4857
TenantID: c.TenantID,
4958
TenantName: c.TenantName,
50-
DomainID: c.DomainID,
51-
DomainName: c.DomainName,
59+
TokenID: c.Token,
60+
Username: c.Username,
61+
UserID: c.UserID,
5262
}
5363

5464
client, err := openstack.NewClient(ao.IdentityEndpoint)
@@ -58,7 +68,6 @@ func (c *Config) loadAndValidate() error {
5868

5969
config := &tls.Config{}
6070
if c.CACertFile != "" {
61-
6271
caCert, err := ioutil.ReadFile(c.CACertFile)
6372
if err != nil {
6473
return err
@@ -68,6 +77,7 @@ func (c *Config) loadAndValidate() error {
6877
caCertPool.AppendCertsFromPEM(caCert)
6978
config.RootCAs = caCertPool
7079
}
80+
7181
if c.Insecure {
7282
config.InsecureSkipVerify = true
7383
}
@@ -81,6 +91,7 @@ func (c *Config) loadAndValidate() error {
8191
config.Certificates = []tls.Certificate{cert}
8292
config.BuildNameToCertificate()
8393
}
94+
8495
transport := &http.Transport{Proxy: http.ProxyFromEnvironment, TLSClientConfig: config}
8596
client.HTTPClient.Transport = transport
8697

builtin/providers/openstack/provider.go

Lines changed: 103 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,71 +17,113 @@ func Provider() terraform.ResourceProvider {
1717
Type: schema.TypeString,
1818
Required: true,
1919
DefaultFunc: schema.EnvDefaultFunc("OS_AUTH_URL", nil),
20+
Description: descriptions["auth_url"],
2021
},
22+
2123
"user_name": &schema.Schema{
2224
Type: schema.TypeString,
2325
Optional: true,
2426
DefaultFunc: schema.EnvDefaultFunc("OS_USERNAME", ""),
27+
Description: descriptions["user_name"],
2528
},
29+
2630
"user_id": &schema.Schema{
27-
Type: schema.TypeString,
28-
Optional: true,
29-
Default: "",
31+
Type: schema.TypeString,
32+
Optional: true,
33+
DefaultFunc: schema.EnvDefaultFunc("OS_USER_ID", ""),
34+
Description: descriptions["user_name"],
3035
},
36+
3137
"tenant_id": &schema.Schema{
3238
Type: schema.TypeString,
3339
Optional: true,
34-
Default: "",
40+
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
41+
"OS_TENANT_ID",
42+
"OS_PROJECT_ID",
43+
}, ""),
44+
Description: descriptions["tenant_id"],
3545
},
46+
3647
"tenant_name": &schema.Schema{
37-
Type: schema.TypeString,
38-
Optional: true,
39-
DefaultFunc: schema.EnvDefaultFunc("OS_TENANT_NAME", nil),
48+
Type: schema.TypeString,
49+
Optional: true,
50+
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
51+
"OS_TENANT_NAME",
52+
"OS_PROJECT_NAME",
53+
}, ""),
54+
Description: descriptions["tenant_name"],
4055
},
56+
4157
"password": &schema.Schema{
4258
Type: schema.TypeString,
4359
Optional: true,
60+
Sensitive: true,
4461
DefaultFunc: schema.EnvDefaultFunc("OS_PASSWORD", ""),
62+
Description: descriptions["password"],
4563
},
64+
4665
"token": &schema.Schema{
4766
Type: schema.TypeString,
4867
Optional: true,
4968
DefaultFunc: schema.EnvDefaultFunc("OS_AUTH_TOKEN", ""),
69+
Description: descriptions["token"],
5070
},
71+
5172
"domain_id": &schema.Schema{
52-
Type: schema.TypeString,
53-
Optional: true,
54-
DefaultFunc: schema.EnvDefaultFunc("OS_DOMAIN_ID", ""),
73+
Type: schema.TypeString,
74+
Optional: true,
75+
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
76+
"OS_USER_DOMAIN_ID",
77+
"OS_PROJECT_DOMAIN_ID",
78+
"OS_DOMAIN_ID",
79+
}, ""),
80+
Description: descriptions["domain_id"],
5581
},
82+
5683
"domain_name": &schema.Schema{
57-
Type: schema.TypeString,
58-
Optional: true,
59-
DefaultFunc: schema.EnvDefaultFunc("OS_DOMAIN_NAME", ""),
84+
Type: schema.TypeString,
85+
Optional: true,
86+
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
87+
"OS_USER_DOMAIN_NAME",
88+
"OS_PROJECT_DOMAIN_NAME",
89+
"OS_DOMAIN_NAME",
90+
"OS_DEFAULT_DOMAIN",
91+
}, ""),
92+
Description: descriptions["domain_name"],
6093
},
94+
6195
"insecure": &schema.Schema{
62-
Type: schema.TypeBool,
63-
Optional: true,
64-
Default: false,
96+
Type: schema.TypeBool,
97+
Optional: true,
98+
DefaultFunc: schema.EnvDefaultFunc("OS_INSECURE", ""),
99+
Description: descriptions["insecure"],
65100
},
101+
66102
"endpoint_type": &schema.Schema{
67103
Type: schema.TypeString,
68104
Optional: true,
69105
DefaultFunc: schema.EnvDefaultFunc("OS_ENDPOINT_TYPE", ""),
70106
},
107+
71108
"cacert_file": &schema.Schema{
72109
Type: schema.TypeString,
73110
Optional: true,
74111
DefaultFunc: schema.EnvDefaultFunc("OS_CACERT", ""),
112+
Description: descriptions["cacert_file"],
75113
},
114+
76115
"cert": &schema.Schema{
77116
Type: schema.TypeString,
78117
Optional: true,
79118
DefaultFunc: schema.EnvDefaultFunc("OS_CERT", ""),
119+
Description: descriptions["cert"],
80120
},
121+
81122
"key": &schema.Schema{
82123
Type: schema.TypeString,
83124
Optional: true,
84125
DefaultFunc: schema.EnvDefaultFunc("OS_KEY", ""),
126+
Description: descriptions["key"],
85127
},
86128
},
87129

@@ -121,22 +163,58 @@ func Provider() terraform.ResourceProvider {
121163
}
122164
}
123165

166+
var descriptions map[string]string
167+
168+
func init() {
169+
descriptions = map[string]string{
170+
"auth_url": "The Identity authentication URL.",
171+
172+
"user_name": "Username to login with.",
173+
174+
"user_id": "User ID to login with.",
175+
176+
"tenant_id": "The ID of the Tenant (Identity v2) or Project (Identity v3)\n" +
177+
"to login with.",
178+
179+
"tenant_name": "The name of the Tenant (Identity v2) or Project (Identity v3)\n" +
180+
"to login with.",
181+
182+
"password": "Password to login with.",
183+
184+
"token": "Authentication token to use as an alternative to username/password.",
185+
186+
"domain_id": "The ID of the Domain to scope to (Identity v3).",
187+
188+
"domain_name": "The name of the Domain to scope to (Identity v3).",
189+
190+
"insecure": "Trust self-signed certificates.",
191+
192+
"cacert_file": "A Custom CA certificate.",
193+
194+
"endpoint_type": "The catalog endpoint type to use.",
195+
196+
"cert": "A client certificate to authenticate with.",
197+
198+
"key": "A client private key to authenticate with.",
199+
}
200+
}
201+
124202
func configureProvider(d *schema.ResourceData) (interface{}, error) {
125203
config := Config{
204+
CACertFile: d.Get("cacert_file").(string),
205+
ClientCertFile: d.Get("cert").(string),
206+
ClientKeyFile: d.Get("key").(string),
207+
DomainID: d.Get("domain_id").(string),
208+
DomainName: d.Get("domain_name").(string),
209+
EndpointType: d.Get("endpoint_type").(string),
126210
IdentityEndpoint: d.Get("auth_url").(string),
127-
Username: d.Get("user_name").(string),
128-
UserID: d.Get("user_id").(string),
211+
Insecure: d.Get("insecure").(bool),
129212
Password: d.Get("password").(string),
130213
Token: d.Get("token").(string),
131214
TenantID: d.Get("tenant_id").(string),
132215
TenantName: d.Get("tenant_name").(string),
133-
DomainID: d.Get("domain_id").(string),
134-
DomainName: d.Get("domain_name").(string),
135-
Insecure: d.Get("insecure").(bool),
136-
EndpointType: d.Get("endpoint_type").(string),
137-
CACertFile: d.Get("cacert_file").(string),
138-
ClientCertFile: d.Get("cert").(string),
139-
ClientKeyFile: d.Get("key").(string),
216+
Username: d.Get("user_name").(string),
217+
UserID: d.Get("user_id").(string),
140218
}
141219

142220
if err := config.loadAndValidate(); err != nil {

website/source/docs/providers/openstack/index.html.markdown

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,50 +35,56 @@ resource "openstack_compute_instance_v2" "test-server" {
3535

3636
The following arguments are supported:
3737

38-
* `auth_url` - (Required) If omitted, the `OS_AUTH_URL` environment
39-
variable is used.
38+
* `auth_url` - (Required) The Identity authentication URL. If omitted, the
39+
`OS_AUTH_URL` environment variable is used.
4040

41-
* `user_name` - (Optional; Required for Identity V2) If omitted, the
42-
`OS_USERNAME` environment variable is used.
41+
* `user_name` - (Optional) The Username to login with. If omitted, the
42+
`OS_USERNAME` environment variable is used.
4343

44-
* `user_id` - (Optional)
44+
* `user_id` - (Optional) The User ID to login with. If omitted, the
45+
`OS_USER_ID` environment variable is used.
4546

46-
* `password` - (Optional; Required if not using `api_key`) If omitted, the
47-
`OS_PASSWORD` environment variable is used.
47+
* `tenant_id` - (Optional) The ID of the Tenant (Identity v2) or Project
48+
(Identity v3) to login with. If omitted, the `OS_TENANT_ID` or
49+
`OS_PROJECT_ID` environment variables are used.
4850

49-
* `token` - (Optional; Required if not using `user_name` and `password`)
50-
A token is an expiring, temporary means of access issued via the
51-
Keystone service. By specifying a token, you do not have to
52-
specify a username/password combination, since the token was
53-
already created by a username/password out of band of Terraform.
54-
If omitted, the `OS_AUTH_TOKEN` environment variable is used.
51+
* `tenant_name` - (Optional) The Name of the Tenant (Identity v2) or Project
52+
(Identity v3) to login with. If omitted, the `OS_TENANT_NAME` or
53+
`OS_PROJECT_NAME` environment variable are used.
5554

56-
* `domain_id` - (Optional) If omitted, the `OS_DOMAIN_ID` environment
57-
variable is used.
55+
* `password` - (Optional) The Password to login with. If omitted, the
56+
`OS_PASSWORD` environment variable is used.
5857

59-
* `domain_name` - (Optional) If omitted, the `OS_DOMAIN_NAME`
60-
environment variable is used.
58+
* `token` - (Optional; Required if not using `user_name` and `password`)
59+
A token is an expiring, temporary means of access issued via the Keystone
60+
service. By specifying a token, you do not have to specify a username/password
61+
combination, since the token was already created by a username/password out of
62+
band of Terraform. If omitted, the `OS_AUTH_TOKEN` environment variable is used.
6163

62-
* `tenant_id` - (Optional)
64+
* `domain_id` - (Optional) The ID of the Domain to scope to (Identity v3). If
65+
If omitted, the following environment variables are checked (in this order):
66+
`OS_USER_DOMAIN_ID`, `OS_PROJECT_DOMAIN_ID`, `OS_DOMAIN_ID`.
6367

64-
* `tenant_name` - (Optional) If omitted, the `OS_TENANT_NAME` environment
65-
variable is used.
68+
* `domain_name` - (Optional) The Name of the Domain to scope to (Identity v3).
69+
If omitted, the following environment variables are checked (in this order):
70+
`OS_USER_DOMAIN_NAME`, `OS_PROJECT_DOMAIN_NAME`, `OS_DOMAIN_NAME`,
71+
`DEFAULT_DOMAIN`.
6672

67-
* `insecure` - (Optional) Explicitly allow the provider to perform
68-
"insecure" SSL requests. If omitted, default value is `false`
73+
* `insecure` - (Optional) Trust self-signed SSL certificates. If omitted, the
74+
`OS_INSECURE` environment variable is used.
6975

7076
* `cacert_file` - (Optional) Specify a custom CA certificate when communicating
71-
over SSL. If omitted, the `OS_CACERT` environment variable is used.
77+
over SSL. If omitted, the `OS_CACERT` environment variable is used.
7278

7379
* `cert` - (Optional) Specify client certificate file for SSL client
74-
authentication. If omitted the `OS_CERT` environment variable is used.
80+
authentication. If omitted the `OS_CERT` environment variable is used.
7581

7682
* `key` - (Optional) Specify client private key file for SSL client
77-
authentication. If omitted the `OS_KEY` environment variable is used.
83+
authentication. If omitted the `OS_KEY` environment variable is used.
7884

7985
* `endpoint_type` - (Optional) Specify which type of endpoint to use from the
80-
service catalog. It can be set using the OS_ENDPOINT_TYPE environment
81-
variable. If not set, public endpoints is used.
86+
service catalog. It can be set using the OS_ENDPOINT_TYPE environment
87+
variable. If not set, public endpoints is used.
8288

8389
## Rackspace Compatibility
8490

0 commit comments

Comments
 (0)