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