Rev 15: Implement getting credentials from environment variables. in http://bazaar.launchpad.net/+branch/goose
John Arbash Meinel
john at arbash-meinel.com
Sun Nov 18 14:36:57 UTC 2012
At http://bazaar.launchpad.net/+branch/goose
------------------------------------------------------------
revno: 15 [merge]
revision-id: john at arbash-meinel.com-20121118143652-zgbcfem2v1m6q700
parent: martin.packman at canonical.com-20121116164138-zga70lp9hi554pi6
parent: john at arbash-meinel.com-20121118143308-p6qb95i4qy2vi1aj
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: goose
timestamp: Sun 2012-11-18 14:36:52 +0000
message:
Implement getting credentials from environment variables.
added:
identity/identity_test.go identity_test.go-20121118124826-592e00m0s78hzsav-1
testing/envsuite/ testingenvsuite-20121118124846-ncfmwn337i5sqpbt-1
testing/envsuite/envsuite.go envsuite.go-20121118130715-1o6604wecyn3166e-1
testing/envsuite/envsuite_test.go envsuite_test.go-20121118130715-1o6604wecyn3166e-2
modified:
identity/identity.go identity.go-20121101104736-kra8p5238cfvt680-1
-------------- next part --------------
=== modified file 'identity/identity.go'
--- a/identity/identity.go 2012-11-01 11:03:25 +0000
+++ b/identity/identity.go 2012-11-18 14:33:08 +0000
@@ -1,16 +1,43 @@
package identity
+import (
+ "os"
+)
+
type AuthDetails struct {
Token string
ServiceURLs map[string]string
}
type Credentials struct {
- URL string // The URL to authenticate against
- User string // The username to authenticate as
- Secrets string // The secrets to pass
+ URL string // The URL to authenticate against
+ User string // The username to authenticate as
+ Secrets string // The secrets to pass
+ Region string // Region to send requests to
+ TenantName string // The tenant information for this connection
}
type Authenticator interface {
Auth(creds Credentials) (*AuthDetails, error)
}
+
+func getConfig(envVars ...string) (value string) {
+ value = ""
+ for _, v := range envVars {
+ value = os.Getenv(v)
+ if value != "" {
+ break
+ }
+ }
+ return
+}
+
+func CredentialsFromEnv() *Credentials {
+ return &Credentials{
+ URL: getConfig("OS_AUTH_URL"),
+ User: getConfig("OS_USERNAME", "NOVA_USERNAME"),
+ Secrets: getConfig("OS_PASSWORD", "NOVA_PASSWORD"),
+ Region: getConfig("OS_REGION_NAME", "NOVA_REGION"),
+ TenantName: getConfig("OS_TENANT_NAME", "NOVA_PROJECT_ID"),
+ }
+}
=== added file 'identity/identity_test.go'
--- a/identity/identity_test.go 1970-01-01 00:00:00 +0000
+++ b/identity/identity_test.go 2012-11-18 14:33:08 +0000
@@ -0,0 +1,67 @@
+package identity
+
+import (
+ . "launchpad.net/gocheck"
+ "launchpad.net/goose/testing/envsuite"
+ "os"
+)
+
+type CredentialsTestSuite struct {
+ // Isolate all of these tests from the real Environ.
+ envsuite.EnvSuite
+}
+
+var _ = Suite(&CredentialsTestSuite{})
+
+func (s *CredentialsTestSuite) TestCredentialsFromEnv(c *C) {
+ var scenarios = []struct {
+ summary string
+ env map[string]string
+ username string
+ password string
+ tenant string
+ region string
+ authURL string
+ }{
+ {summary: "Old 'NOVA' style creds",
+ env: map[string]string{
+ "NOVA_USERNAME": "test-user",
+ "NOVA_PASSWORD": "test-pass",
+ // TODO: JAM 20121118 There exists a 'tenant
+ // name' and a 'tenant id'. Does
+ // NOVA_PROJECT_ID map to the 'tenant id' or to
+ // the tenant name? ~/.canonistack/novarc says
+ // tenant_name.
+ "NOVA_PROJECT_ID": "tenant-name",
+ "NOVA_REGION": "region",
+ },
+ username: "test-user",
+ password: "test-pass",
+ tenant: "tenant-name",
+ region: "region",
+ },
+ {summary: "New 'OS' style environment",
+ env: map[string]string{
+ "OS_USERNAME": "test-user",
+ "OS_PASSWORD": "test-pass",
+ "OS_TENANT_NAME": "tenant-name",
+ "OS_REGION_NAME": "region",
+ },
+ username: "test-user",
+ password: "test-pass",
+ tenant: "tenant-name",
+ region: "region",
+ },
+ }
+ for _, scenario := range scenarios {
+ for key, value := range scenario.env {
+ os.Setenv(key, value)
+ }
+ creds := CredentialsFromEnv()
+ c.Check(creds.URL, Equals, scenario.authURL)
+ c.Check(creds.User, Equals, scenario.username)
+ c.Check(creds.Secrets, Equals, scenario.password)
+ c.Check(creds.Region, Equals, scenario.region)
+ c.Check(creds.TenantName, Equals, scenario.tenant)
+ }
+}
=== added directory 'testing/envsuite'
=== added file 'testing/envsuite/envsuite.go'
--- a/testing/envsuite/envsuite.go 1970-01-01 00:00:00 +0000
+++ b/testing/envsuite/envsuite.go 2012-11-18 13:07:38 +0000
@@ -0,0 +1,33 @@
+package envsuite
+
+// Provides an EnvSuite type which makes sure this test suite gets an isolated
+// environment settings. Settings will be saved on start and then cleared, and
+// reset on tear down.
+
+import (
+ . "launchpad.net/gocheck"
+ "os"
+ "strings"
+)
+
+type EnvSuite struct {
+ environ []string
+}
+
+func (s *EnvSuite) SetUpSuite(c *C) {
+ s.environ = os.Environ()
+}
+
+func (s *EnvSuite) SetUpTest(c *C) {
+ os.Clearenv()
+}
+
+func (s *EnvSuite) TearDownTest(c *C) {
+ for _, envstring := range s.environ {
+ kv := strings.SplitN(envstring, "=", 2)
+ os.Setenv(kv[0], kv[1])
+ }
+}
+
+func (s *EnvSuite) TearDownSuite(c *C) {
+}
=== added file 'testing/envsuite/envsuite_test.go'
--- a/testing/envsuite/envsuite_test.go 1970-01-01 00:00:00 +0000
+++ b/testing/envsuite/envsuite_test.go 2012-11-18 13:07:38 +0000
@@ -0,0 +1,48 @@
+package envsuite
+
+import (
+ . "launchpad.net/gocheck"
+ "os"
+ "testing"
+)
+
+type EnvTestSuite struct {
+ EnvSuite
+}
+
+func Test(t *testing.T) {
+ TestingT(t)
+}
+
+var _ = Suite(&EnvTestSuite{})
+
+func (s *EnvTestSuite) TestGrabsCurrentEnvironment(c *C) {
+ envsuite := &EnvSuite{}
+ // EnvTestSuite is an EnvSuite, so we should have already isolated
+ // ourselves from the world. So we set a single env value, and we
+ // assert that SetUpSuite is able to see that.
+ os.Setenv("TEST_KEY", "test-value")
+ envsuite.SetUpSuite(c)
+ c.Assert(envsuite.environ, DeepEquals, []string{"TEST_KEY=test-value"})
+}
+
+func (s *EnvTestSuite) TestClearsEnvironment(c *C) {
+ envsuite := &EnvSuite{}
+ os.Setenv("TEST_KEY", "test-value")
+ envsuite.SetUpSuite(c)
+ // SetUpTest should reset the current environment back to being
+ // completely empty.
+ envsuite.SetUpTest(c)
+ c.Assert(os.Getenv("TEST_KEY"), Equals, "")
+ c.Assert(os.Environ(), DeepEquals, []string{})
+}
+
+func (s *EnvTestSuite) TestRestoresEnvironment(c *C) {
+ envsuite := &EnvSuite{}
+ os.Setenv("TEST_KEY", "test-value")
+ envsuite.SetUpSuite(c)
+ envsuite.SetUpTest(c)
+ envsuite.TearDownTest(c)
+ c.Assert(os.Getenv("TEST_KEY"), Equals, "test-value")
+ c.Assert(os.Environ(), DeepEquals, []string{"TEST_KEY=test-value"})
+}
More information about the bazaar-commits
mailing list