github.com/alexissmirnov/terraform@v0.4.3-0.20150423153700-1ef9731a2f14/builtin/providers/google/config.go (about) 1 package google 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "log" 7 "net/http" 8 "os" 9 "runtime" 10 11 // TODO(dcunnin): Use version code from version.go 12 // "github.com/hashicorp/terraform" 13 "golang.org/x/oauth2" 14 "golang.org/x/oauth2/google" 15 "golang.org/x/oauth2/jwt" 16 "google.golang.org/api/compute/v1" 17 ) 18 19 // Config is the configuration structure used to instantiate the Google 20 // provider. 21 type Config struct { 22 AccountFile string 23 Project string 24 Region string 25 26 clientCompute *compute.Service 27 } 28 29 func (c *Config) loadAndValidate() error { 30 var account accountFile 31 32 // TODO: validation that it isn't blank 33 if c.AccountFile == "" { 34 c.AccountFile = os.Getenv("GOOGLE_ACCOUNT_FILE") 35 } 36 if c.Project == "" { 37 c.Project = os.Getenv("GOOGLE_PROJECT") 38 } 39 if c.Region == "" { 40 c.Region = os.Getenv("GOOGLE_REGION") 41 } 42 43 var client *http.Client 44 45 if c.AccountFile != "" { 46 if err := loadJSON(&account, c.AccountFile); err != nil { 47 return fmt.Errorf( 48 "Error loading account file '%s': %s", 49 c.AccountFile, 50 err) 51 } 52 53 clientScopes := []string{"https://www.googleapis.com/auth/compute"} 54 55 // Get the token for use in our requests 56 log.Printf("[INFO] Requesting Google token...") 57 log.Printf("[INFO] -- Email: %s", account.ClientEmail) 58 log.Printf("[INFO] -- Scopes: %s", clientScopes) 59 log.Printf("[INFO] -- Private Key Length: %d", len(account.PrivateKey)) 60 61 conf := jwt.Config{ 62 Email: account.ClientEmail, 63 PrivateKey: []byte(account.PrivateKey), 64 Scopes: clientScopes, 65 TokenURL: "https://accounts.google.com/o/oauth2/token", 66 } 67 68 // Initiate an http.Client. The following GET request will be 69 // authorized and authenticated on the behalf of 70 // your service account. 71 client = conf.Client(oauth2.NoContext) 72 73 } else { 74 log.Printf("[INFO] Requesting Google token via GCE Service Role...") 75 client = &http.Client{ 76 Transport: &oauth2.Transport{ 77 // Fetch from Google Compute Engine's metadata server to retrieve 78 // an access token for the provided account. 79 // If no account is specified, "default" is used. 80 Source: google.ComputeTokenSource(""), 81 }, 82 } 83 84 } 85 86 log.Printf("[INFO] Instantiating GCE client...") 87 var err error 88 c.clientCompute, err = compute.New(client) 89 90 // Set UserAgent 91 versionString := "0.0.0" 92 // TODO(dcunnin): Use Terraform's version code from version.go 93 // versionString := main.Version 94 // if main.VersionPrerelease != "" { 95 // versionString = fmt.Sprintf("%s-%s", versionString, main.VersionPrerelease) 96 // } 97 c.clientCompute.UserAgent = fmt.Sprintf( 98 "(%s %s) Terraform/%s", runtime.GOOS, runtime.GOARCH, versionString) 99 100 if err != nil { 101 return err 102 } 103 104 return nil 105 } 106 107 // accountFile represents the structure of the account file JSON file. 108 type accountFile struct { 109 PrivateKeyId string `json:"private_key_id"` 110 PrivateKey string `json:"private_key"` 111 ClientEmail string `json:"client_email"` 112 ClientId string `json:"client_id"` 113 } 114 115 func loadJSON(result interface{}, path string) error { 116 f, err := os.Open(path) 117 if err != nil { 118 return err 119 } 120 defer f.Close() 121 122 dec := json.NewDecoder(f) 123 return dec.Decode(result) 124 }