providers/google: Use account_file_contents if provided

This commit is contained in:
Justin Campbell 2015-07-23 17:56:32 -04:00
parent a8d0a70c03
commit 4ce776d252
3 changed files with 80 additions and 27 deletions

View File

@ -3,10 +3,12 @@ package google
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"net/http" "net/http"
"os" "os"
"runtime" "runtime"
"strings"
// TODO(dcunnin): Use version code from version.go // TODO(dcunnin): Use version code from version.go
@ -54,10 +56,25 @@ func (c *Config) loadAndValidate() error {
var client *http.Client var client *http.Client
if c.AccountFile != "" { if c.AccountFile != "" {
if err := loadJSON(&account, c.AccountFile); err != nil { if c.AccountFileContents != "" {
return fmt.Errorf( return fmt.Errorf(
"Error loading account file '%s': %s", "Cannot provide both account_file and account_file_contents",
c.AccountFile, )
}
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) err)
} }
@ -150,13 +167,9 @@ type accountFile struct {
ClientId string `json:"client_id"` ClientId string `json:"client_id"`
} }
func loadJSON(result interface{}, path string) error { func parseJSON(result interface{}, contents string) error {
f, err := os.Open(path) r := strings.NewReader(contents)
if err != nil { dec := json.NewDecoder(r)
return err
}
defer f.Close()
dec := json.NewDecoder(f)
return dec.Decode(result) return dec.Decode(result)
} }

View File

@ -1,24 +1,63 @@
package google package google
import ( import (
"reflect" "io/ioutil"
"testing" "testing"
) )
func TestConfigLoadJSON_account(t *testing.T) { const testFakeAccountFilePath = "./test-fixtures/fake_account.json"
var actual accountFile
if err := loadJSON(&actual, "./test-fixtures/fake_account.json"); err != nil { func TestConfigLoadAndValidate_accountFile(t *testing.T) {
t.Fatalf("err: %s", err) config := Config{
AccountFile: testFakeAccountFilePath,
Project: "my-gce-project",
Region: "us-central1",
} }
expected := accountFile{ err := config.loadAndValidate()
PrivateKeyId: "foo", if err != nil {
PrivateKey: "bar", t.Fatalf("error: %v", err)
ClientEmail: "foo@bar.com", }
ClientId: "id@foo.com", }
}
func TestConfigLoadAndValidate_accountFileContents(t *testing.T) {
if !reflect.DeepEqual(actual, expected) { contents, err := ioutil.ReadFile(testFakeAccountFilePath)
t.Fatalf("bad: %#v", actual) 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")
} }
} }

View File

@ -60,6 +60,7 @@ func Provider() terraform.ResourceProvider {
func providerConfigure(d *schema.ResourceData) (interface{}, error) { func providerConfigure(d *schema.ResourceData) (interface{}, error) {
config := Config{ config := Config{
AccountFile: d.Get("account_file").(string), AccountFile: d.Get("account_file").(string),
AccountFileContents: d.Get("account_file_contents").(string),
Project: d.Get("project").(string), Project: d.Get("project").(string),
Region: d.Get("region").(string), Region: d.Get("region").(string),
} }