From 4ce776d252c29b26466b81dfd2de1c062f9e94fa Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Thu, 23 Jul 2015 17:56:32 -0400 Subject: [PATCH] providers/google: Use account_file_contents if provided --- builtin/providers/google/config.go | 33 ++++++++---- builtin/providers/google/config_test.go | 67 +++++++++++++++++++------ builtin/providers/google/provider.go | 7 +-- 3 files changed, 80 insertions(+), 27 deletions(-) diff --git a/builtin/providers/google/config.go b/builtin/providers/google/config.go index 99e693fd4..853b5228a 100644 --- a/builtin/providers/google/config.go +++ b/builtin/providers/google/config.go @@ -3,10 +3,12 @@ package google import ( "encoding/json" "fmt" + "io/ioutil" "log" "net/http" "os" "runtime" + "strings" // TODO(dcunnin): Use version code from version.go @@ -54,10 +56,25 @@ func (c *Config) loadAndValidate() error { var client *http.Client if c.AccountFile != "" { - if err := loadJSON(&account, c.AccountFile); err != nil { + if c.AccountFileContents != "" { return fmt.Errorf( - "Error loading account file '%s': %s", - c.AccountFile, + "Cannot provide both account_file and account_file_contents", + ) + } + + b, err := ioutil.ReadFile(c.AccountFile) + if err != nil { + return err + } + + c.AccountFileContents = string(b) + } + + if c.AccountFileContents != "" { + if err := parseJSON(&account, c.AccountFileContents); err != nil { + return fmt.Errorf( + "Error parsing account file contents '%s': %s", + c.AccountFileContents, err) } @@ -150,13 +167,9 @@ type accountFile struct { ClientId string `json:"client_id"` } -func loadJSON(result interface{}, path string) error { - f, err := os.Open(path) - if err != nil { - return err - } - defer f.Close() +func parseJSON(result interface{}, contents string) error { + r := strings.NewReader(contents) + dec := json.NewDecoder(r) - dec := json.NewDecoder(f) return dec.Decode(result) } diff --git a/builtin/providers/google/config_test.go b/builtin/providers/google/config_test.go index b4ee58520..3ec20376a 100644 --- a/builtin/providers/google/config_test.go +++ b/builtin/providers/google/config_test.go @@ -1,24 +1,63 @@ package google import ( - "reflect" + "io/ioutil" "testing" ) -func TestConfigLoadJSON_account(t *testing.T) { - var actual accountFile - if err := loadJSON(&actual, "./test-fixtures/fake_account.json"); err != nil { - t.Fatalf("err: %s", err) +const testFakeAccountFilePath = "./test-fixtures/fake_account.json" + +func TestConfigLoadAndValidate_accountFile(t *testing.T) { + config := Config{ + AccountFile: testFakeAccountFilePath, + Project: "my-gce-project", + Region: "us-central1", } - expected := accountFile{ - PrivateKeyId: "foo", - PrivateKey: "bar", - ClientEmail: "foo@bar.com", - ClientId: "id@foo.com", - } - - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("bad: %#v", actual) + err := config.loadAndValidate() + if err != nil { + t.Fatalf("error: %v", err) + } +} + +func TestConfigLoadAndValidate_accountFileContents(t *testing.T) { + contents, err := ioutil.ReadFile(testFakeAccountFilePath) + if err != nil { + t.Fatalf("error: %v", err) + } + config := Config{ + AccountFileContents: string(contents), + Project: "my-gce-project", + Region: "us-central1", + } + + err = config.loadAndValidate() + if err != nil { + t.Fatalf("error: %v", err) + } +} + +func TestConfigLoadAndValidate_none(t *testing.T) { + config := Config{ + Project: "my-gce-project", + Region: "us-central1", + } + + err := config.loadAndValidate() + if err != nil { + t.Fatalf("error: %v", err) + } +} + +func TestConfigLoadAndValidate_both(t *testing.T) { + config := Config{ + AccountFile: testFakeAccountFilePath, + AccountFileContents: "{}", + Project: "my-gce-project", + Region: "us-central1", + } + + if config.loadAndValidate() == nil { + t.Fatalf("expected error, but got nil") } } diff --git a/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index c93812d5a..969895d17 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/provider.go @@ -59,9 +59,10 @@ func Provider() terraform.ResourceProvider { func providerConfigure(d *schema.ResourceData) (interface{}, error) { config := Config{ - AccountFile: d.Get("account_file").(string), - Project: d.Get("project").(string), - Region: d.Get("region").(string), + AccountFile: d.Get("account_file").(string), + AccountFileContents: d.Get("account_file_contents").(string), + Project: d.Get("project").(string), + Region: d.Get("region").(string), } if err := config.loadAndValidate(); err != nil {