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