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