github.com/wangzhucn/terraform@v0.6.7-0.20151109233120-4eea011b56b3/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 "github.com/hashicorp/terraform/terraform" 14 "golang.org/x/oauth2" 15 "golang.org/x/oauth2/google" 16 "golang.org/x/oauth2/jwt" 17 "google.golang.org/api/compute/v1" 18 "google.golang.org/api/container/v1" 19 "google.golang.org/api/dns/v1" 20 "google.golang.org/api/sqladmin/v1beta4" 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 clientSqlAdmin *sqladmin.Service 36 } 37 38 func (c *Config) loadAndValidate() error { 39 var account accountFile 40 clientScopes := []string{ 41 "https://www.googleapis.com/auth/compute", 42 "https://www.googleapis.com/auth/cloud-platform", 43 "https://www.googleapis.com/auth/ndev.clouddns.readwrite", 44 "https://www.googleapis.com/auth/devstorage.full_control", 45 } 46 47 if c.AccountFile == "" { 48 c.AccountFile = os.Getenv("GOOGLE_ACCOUNT_FILE") 49 } 50 if c.Project == "" { 51 c.Project = os.Getenv("GOOGLE_PROJECT") 52 } 53 if c.Region == "" { 54 c.Region = os.Getenv("GOOGLE_REGION") 55 } 56 57 var client *http.Client 58 59 if c.AccountFile != "" { 60 contents := c.AccountFile 61 62 // Assume account_file is a JSON string 63 if err := parseJSON(&account, contents); err != nil { 64 // If account_file was not JSON, assume it is a file path instead 65 if _, err := os.Stat(c.AccountFile); os.IsNotExist(err) { 66 return fmt.Errorf( 67 "account_file path does not exist: %s", 68 c.AccountFile) 69 } 70 71 b, err := ioutil.ReadFile(c.AccountFile) 72 if err != nil { 73 return fmt.Errorf( 74 "Error reading account_file from path '%s': %s", 75 c.AccountFile, 76 err) 77 } 78 79 contents = string(b) 80 81 if err := parseJSON(&account, contents); err != nil { 82 return fmt.Errorf( 83 "Error parsing account file '%s': %s", 84 contents, 85 err) 86 } 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] Authenticating using DefaultClient") 109 err := error(nil) 110 client, err = google.DefaultClient(oauth2.NoContext, clientScopes...) 111 if err != nil { 112 return err 113 } 114 } 115 116 versionString := terraform.Version 117 prerelease := terraform.VersionPrerelease 118 if len(prerelease) > 0 { 119 versionString = fmt.Sprintf("%s-%s", versionString, prerelease) 120 } 121 userAgent := fmt.Sprintf( 122 "(%s %s) Terraform/%s", runtime.GOOS, runtime.GOARCH, versionString) 123 124 var err error 125 126 log.Printf("[INFO] Instantiating GCE client...") 127 c.clientCompute, err = compute.New(client) 128 if err != nil { 129 return err 130 } 131 c.clientCompute.UserAgent = userAgent 132 133 log.Printf("[INFO] Instantiating GKE client...") 134 c.clientContainer, err = container.New(client) 135 if err != nil { 136 return err 137 } 138 c.clientContainer.UserAgent = userAgent 139 140 log.Printf("[INFO] Instantiating Google Cloud DNS client...") 141 c.clientDns, err = dns.New(client) 142 if err != nil { 143 return err 144 } 145 c.clientDns.UserAgent = userAgent 146 147 log.Printf("[INFO] Instantiating Google Storage Client...") 148 c.clientStorage, err = storage.New(client) 149 if err != nil { 150 return err 151 } 152 c.clientStorage.UserAgent = userAgent 153 154 log.Printf("[INFO] Instantiating Google SqlAdmin Client...") 155 c.clientSqlAdmin, err = sqladmin.New(client) 156 if err != nil { 157 return err 158 } 159 c.clientSqlAdmin.UserAgent = userAgent 160 161 return nil 162 } 163 164 // accountFile represents the structure of the account file JSON file. 165 type accountFile struct { 166 PrivateKeyId string `json:"private_key_id"` 167 PrivateKey string `json:"private_key"` 168 ClientEmail string `json:"client_email"` 169 ClientId string `json:"client_id"` 170 } 171 172 func parseJSON(result interface{}, contents string) error { 173 r := strings.NewReader(contents) 174 dec := json.NewDecoder(r) 175 176 return dec.Decode(result) 177 }