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