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