-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow OpenStack SSL fields to be specified by contents
- OpenStack provider now supports either a path or the file contents for `cacert_file`, `cert`, and `key` - Makes it easier to automate TF by passing in certs as environment variables
- Loading branch information
1 parent
2d894ba
commit 39f06ff
Showing
5 changed files
with
260 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
package openstack | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"strconv" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/pathorcontents" | ||
) | ||
|
||
const testFakeCertPath = "./test-fixtures/fake_cert.pem" | ||
const testFakeKeyPath = "./test-fixtures/fake_key.pem" | ||
|
||
func baseConfig(t *testing.T) Config { | ||
config := Config{ | ||
IdentityEndpoint: os.Getenv("OS_AUTH_URL"), | ||
EndpointType: os.Getenv("OS_ENDPOINT_TYPE"), | ||
CACertFile: os.Getenv("OS_CACERT"), | ||
ClientCertFile: os.Getenv("OS_CERT"), | ||
ClientKeyFile: os.Getenv("OS_KEY"), | ||
Insecure: envBool("OS_INSECURE"), | ||
TenantID: multiEnv("OS_TENANT_ID", "OS_PROJECT_ID"), | ||
TenantName: multiEnv("OS_TENANT_NAME", "OS_PROJECT_NAME"), | ||
DomainID: multiEnv("OS_USER_DOMAIN_ID", "OS_PROJECT_DOMAIN_ID", "OS_DOMAIN_ID"), | ||
DomainName: multiEnv("OS_USER_DOMAIN_NAME", "OS_PROJECT_DOMAIN_NAME", "OS_DOMAIN_NAME", "OS_DEFAULT_DOMAIN"), | ||
Username: os.Getenv("OS_USERNAME"), | ||
UserID: os.Getenv("OS_USER_ID"), | ||
Password: os.Getenv("OS_PASSWORD"), | ||
Token: os.Getenv("OS_AUTH_TOKEN"), | ||
} | ||
|
||
return config | ||
} | ||
|
||
func TestConfigLoadAndValidate_defaultSettings(t *testing.T) { | ||
config := baseConfig(t) | ||
err := config.loadAndValidate() | ||
if err != nil { | ||
t.Fatalf("Unexpected err when validating OpenStack config: %s", err) | ||
} | ||
} | ||
|
||
func TestConfigLoadAndValidate_caCertFile(t *testing.T) { | ||
config := baseConfig(t) | ||
config.CACertFile = testFakeCertPath | ||
|
||
err := config.loadAndValidate() | ||
if err == nil { | ||
t.Fatal("Expected SSL validation error, but got nil") | ||
} | ||
if !strings.Contains(err.Error(), "x509") { | ||
t.Fatalf("Expected error to contain 'x509', but it did not: %s", err) | ||
} | ||
} | ||
|
||
func TestConfigLoadAndValidate_caCertString(t *testing.T) { | ||
fakeCertContents, err := ioutil.ReadFile(testFakeCertPath) | ||
if err != nil { | ||
t.Fatalf("Failed to read cert fixture: %s", err) | ||
} | ||
config := baseConfig(t) | ||
config.CACertFile = string(fakeCertContents) | ||
|
||
err = config.loadAndValidate() | ||
if err == nil { | ||
t.Fatal("Expected SSL validation error, but got nil") | ||
} | ||
if !strings.Contains(err.Error(), "x509") { | ||
t.Fatalf("Expected error to contain 'x509', but it did not: %s", err) | ||
} | ||
} | ||
|
||
func TestConfigLoadAndValidate_clientCert(t *testing.T) { | ||
// Since client SSL validation is enforced server-side and not enabled by default, | ||
// it is difficult to write a failing test here | ||
if os.Getenv("OS_CERT") == "" || os.Getenv("OS_KEY") == "" { | ||
t.Skip("OS_CERT or OS_KEY is not set; skipping OpenStack client SSL auth test.") | ||
} | ||
|
||
certContents, _, err := pathorcontents.Read(os.Getenv("OS_CERT")) | ||
if err != nil { | ||
t.Fatalf("Error reading OS_CERT: %s", err) | ||
} | ||
certFile, err := tempFileWithContents("os-cert", certContents) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.Remove(certFile.Name()) | ||
|
||
keyContents, _, err := pathorcontents.Read(os.Getenv("OS_KEY")) | ||
if err != nil { | ||
t.Fatalf("Error reading OS_KEY: %s", err) | ||
} | ||
keyFile, err := tempFileWithContents("os-key", keyContents) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.Remove(keyFile.Name()) | ||
|
||
// Specify key pair as files | ||
config := baseConfig(t) | ||
config.ClientCertFile = certFile.Name() | ||
config.ClientKeyFile = keyFile.Name() | ||
|
||
err = config.loadAndValidate() | ||
if err != nil { | ||
t.Fatalf("Unexpected err when specifying OpenStack Client keypair by file: %s", err) | ||
} | ||
|
||
// Specify key pair as contents | ||
config = baseConfig(t) | ||
config.ClientCertFile = certContents | ||
config.ClientKeyFile = keyContents | ||
|
||
err = config.loadAndValidate() | ||
if err != nil { | ||
t.Fatalf("Unexpected err when specifying OpenStack Client keypair by contents: %s", err) | ||
} | ||
} | ||
|
||
func envBool(envVar string) bool { | ||
v := os.Getenv(envVar) | ||
if b, err := strconv.ParseBool(v); err == nil { | ||
return b | ||
} | ||
return false | ||
} | ||
|
||
func multiEnv(envVars ...string) string { | ||
for _, v := range envVars { | ||
if os.Getenv(v) != "" { | ||
return os.Getenv(v) | ||
} | ||
} | ||
return "" | ||
} | ||
|
||
func tempFileWithContents(prefix string, contents string) (*os.File, error) { | ||
tmpFile, err := ioutil.TempFile("", prefix) | ||
if err != nil { | ||
return nil, fmt.Errorf("Error creating temp file: %s", err) | ||
} | ||
if _, err := tmpFile.Write([]byte(contents)); err != nil { | ||
_ = os.Remove(tmpFile.Name()) | ||
return nil, fmt.Errorf("Error writing temp file: %s", err) | ||
} | ||
if err := tmpFile.Close(); err != nil { | ||
_ = os.Remove(tmpFile.Name()) | ||
return nil, fmt.Errorf("Error closing temp file: %s", err) | ||
} | ||
return tmpFile, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
-----BEGIN CERTIFICATE----- | ||
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 | ||
-----END CERTIFICATE----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
-----BEGIN RSA PRIVATE KEY----- | ||
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 | ||
-----END RSA PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters