github.com/adamar/terraform@v0.2.2-0.20141016210445-2e703afdad0e/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 10 "code.google.com/p/goauth2/oauth" 11 "code.google.com/p/goauth2/oauth/jwt" 12 "code.google.com/p/google-api-go-client/compute/v1" 13 ) 14 15 const clientScopes string = "https://www.googleapis.com/auth/compute" 16 17 // Config is the configuration structure used to instantiate the Google 18 // provider. 19 type Config struct { 20 AccountFile string 21 ClientSecretsFile string 22 Project string 23 Region string 24 25 clientCompute *compute.Service 26 } 27 28 func (c *Config) loadAndValidate() error { 29 var account accountFile 30 var secrets clientSecretsFile 31 32 // TODO: validation that it isn't blank 33 if c.AccountFile == "" { 34 c.AccountFile = os.Getenv("GOOGLE_ACCOUNT_FILE") 35 } 36 if c.ClientSecretsFile == "" { 37 c.ClientSecretsFile = os.Getenv("GOOGLE_CLIENT_FILE") 38 } 39 if c.Project == "" { 40 c.Project = os.Getenv("GOOGLE_PROJECT") 41 } 42 if c.Region == "" { 43 c.Region = os.Getenv("GOOGLE_REGION") 44 } 45 46 if err := loadJSON(&account, c.AccountFile); err != nil { 47 return fmt.Errorf( 48 "Error loading account file '%s': %s", 49 c.AccountFile, 50 err) 51 } 52 53 if err := loadJSON(&secrets, c.ClientSecretsFile); err != nil { 54 return fmt.Errorf( 55 "Error loading client secrets file '%s': %s", 56 c.ClientSecretsFile, 57 err) 58 } 59 60 // Get the token for use in our requests 61 log.Printf("[INFO] Requesting Google token...") 62 log.Printf("[INFO] -- Email: %s", account.ClientEmail) 63 log.Printf("[INFO] -- Scopes: %s", clientScopes) 64 log.Printf("[INFO] -- Private Key Length: %d", len(account.PrivateKey)) 65 log.Printf("[INFO] -- Token URL: %s", secrets.Web.TokenURI) 66 jwtTok := jwt.NewToken( 67 account.ClientEmail, 68 clientScopes, 69 []byte(account.PrivateKey)) 70 jwtTok.ClaimSet.Aud = secrets.Web.TokenURI 71 token, err := jwtTok.Assert(new(http.Client)) 72 if err != nil { 73 return fmt.Errorf("Error retrieving auth token: %s", err) 74 } 75 76 // Instantiate the transport to communicate to Google 77 transport := &oauth.Transport{ 78 Config: &oauth.Config{ 79 ClientId: account.ClientId, 80 Scope: clientScopes, 81 TokenURL: secrets.Web.TokenURI, 82 AuthURL: secrets.Web.AuthURI, 83 }, 84 Token: token, 85 } 86 87 log.Printf("[INFO] Instantiating GCE client...") 88 c.clientCompute, err = compute.New(transport.Client()) 89 if err != nil { 90 return err 91 } 92 93 return nil 94 } 95 96 // accountFile represents the structure of the account file JSON file. 97 type accountFile struct { 98 PrivateKeyId string `json:"private_key_id"` 99 PrivateKey string `json:"private_key"` 100 ClientEmail string `json:"client_email"` 101 ClientId string `json:"client_id"` 102 } 103 104 // clientSecretsFile represents the structure of the client secrets JSON file. 105 type clientSecretsFile struct { 106 Web struct { 107 AuthURI string `json:"auth_uri"` 108 ClientEmail string `json:"client_email"` 109 ClientId string `json:"client_id"` 110 TokenURI string `json:"token_uri"` 111 } 112 } 113 114 func loadJSON(result interface{}, path string) error { 115 f, err := os.Open(path) 116 if err != nil { 117 return err 118 } 119 defer f.Close() 120 121 dec := json.NewDecoder(f) 122 return dec.Decode(result) 123 }