github.com/anuaimi/terraform@v0.6.4-0.20150904235404-2bf9aec61da8/builtin/providers/google/config.go (about) 1 package google 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "log" 8 "net/http" 9 "os" 10 "runtime" 11 "strings" 12 13 // TODO(dcunnin): Use version code from version.go 14 // "github.com/hashicorp/terraform" 15 "golang.org/x/oauth2" 16 "golang.org/x/oauth2/google" 17 "golang.org/x/oauth2/jwt" 18 "google.golang.org/api/compute/v1" 19 "google.golang.org/api/container/v1" 20 "google.golang.org/api/dns/v1" 21 "google.golang.org/api/storage/v1" 22 ) 23 24 // Config is the configuration structure used to instantiate the Google 25 // provider. 26 type Config struct { 27 AccountFile string 28 Project string 29 Region string 30 31 clientCompute *compute.Service 32 clientContainer *container.Service 33 clientDns *dns.Service 34 clientStorage *storage.Service 35 } 36 37 func (c *Config) loadAndValidate() error { 38 var account accountFile 39 40 if c.AccountFile == "" { 41 c.AccountFile = os.Getenv("GOOGLE_ACCOUNT_FILE") 42 } 43 if c.Project == "" { 44 c.Project = os.Getenv("GOOGLE_PROJECT") 45 } 46 if c.Region == "" { 47 c.Region = os.Getenv("GOOGLE_REGION") 48 } 49 50 var client *http.Client 51 52 if c.AccountFile != "" { 53 contents := c.AccountFile 54 55 // Assume account_file is a JSON string 56 if err := parseJSON(&account, contents); err != nil { 57 // If account_file was not JSON, assume it is a file path instead 58 if _, err := os.Stat(c.AccountFile); os.IsNotExist(err) { 59 return fmt.Errorf( 60 "account_file path does not exist: %s", 61 c.AccountFile) 62 } 63 64 b, err := ioutil.ReadFile(c.AccountFile) 65 if err != nil { 66 return fmt.Errorf( 67 "Error reading account_file from path '%s': %s", 68 c.AccountFile, 69 err) 70 } 71 72 contents = string(b) 73 74 if err := parseJSON(&account, contents); err != nil { 75 return fmt.Errorf( 76 "Error parsing account file '%s': %s", 77 contents, 78 err) 79 } 80 } 81 82 clientScopes := []string{ 83 "https://www.googleapis.com/auth/compute", 84 "https://www.googleapis.com/auth/cloud-platform", 85 "https://www.googleapis.com/auth/ndev.clouddns.readwrite", 86 "https://www.googleapis.com/auth/devstorage.full_control", 87 } 88 89 // Get the token for use in our requests 90 log.Printf("[INFO] Requesting Google token...") 91 log.Printf("[INFO] -- Email: %s", account.ClientEmail) 92 log.Printf("[INFO] -- Scopes: %s", clientScopes) 93 log.Printf("[INFO] -- Private Key Length: %d", len(account.PrivateKey)) 94 95 conf := jwt.Config{ 96 Email: account.ClientEmail, 97 PrivateKey: []byte(account.PrivateKey), 98 Scopes: clientScopes, 99 TokenURL: "https://accounts.google.com/o/oauth2/token", 100 } 101 102 // Initiate an http.Client. The following GET request will be 103 // authorized and authenticated on the behalf of 104 // your service account. 105 client = conf.Client(oauth2.NoContext) 106 107 } else { 108 log.Printf("[INFO] Requesting Google token via GCE Service Role...") 109 client = &http.Client{ 110 Transport: &oauth2.Transport{ 111 // Fetch from Google Compute Engine's metadata server to retrieve 112 // an access token for the provided account. 113 // If no account is specified, "default" is used. 114 Source: google.ComputeTokenSource(""), 115 }, 116 } 117 118 } 119 120 // Build UserAgent 121 versionString := "0.0.0" 122 // TODO(dcunnin): Use Terraform's version code from version.go 123 // versionString := main.Version 124 // if main.VersionPrerelease != "" { 125 // versionString = fmt.Sprintf("%s-%s", versionString, main.VersionPrerelease) 126 // } 127 userAgent := fmt.Sprintf( 128 "(%s %s) Terraform/%s", runtime.GOOS, runtime.GOARCH, versionString) 129 130 var err error 131 132 log.Printf("[INFO] Instantiating GCE client...") 133 c.clientCompute, err = compute.New(client) 134 if err != nil { 135 return err 136 } 137 c.clientCompute.UserAgent = userAgent 138 139 log.Printf("[INFO] Instantiating GKE client...") 140 c.clientContainer, err = container.New(client) 141 if err != nil { 142 return err 143 } 144 c.clientContainer.UserAgent = userAgent 145 146 log.Printf("[INFO] Instantiating Google Cloud DNS client...") 147 c.clientDns, err = dns.New(client) 148 if err != nil { 149 return err 150 } 151 c.clientDns.UserAgent = userAgent 152 153 log.Printf("[INFO] Instantiating Google Storage Client...") 154 c.clientStorage, err = storage.New(client) 155 if err != nil { 156 return err 157 } 158 c.clientStorage.UserAgent = userAgent 159 160 return nil 161 } 162 163 // accountFile represents the structure of the account file JSON file. 164 type accountFile struct { 165 PrivateKeyId string `json:"private_key_id"` 166 PrivateKey string `json:"private_key"` 167 ClientEmail string `json:"client_email"` 168 ClientId string `json:"client_id"` 169 } 170 171 func parseJSON(result interface{}, contents string) error { 172 r := strings.NewReader(contents) 173 dec := json.NewDecoder(r) 174 175 return dec.Decode(result) 176 }