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