github.com/tarrant/terraform@v0.3.8-0.20150402012457-f68c9eee638e/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  	"golang.org/x/oauth2"
    11  	"golang.org/x/oauth2/google"
    12  	"golang.org/x/oauth2/jwt"
    13  	"google.golang.org/api/compute/v1"
    14  )
    15  
    16  // Config is the configuration structure used to instantiate the Google
    17  // provider.
    18  type Config struct {
    19  	AccountFile string
    20  	Project     string
    21  	Region      string
    22  
    23  	clientCompute *compute.Service
    24  }
    25  
    26  func (c *Config) loadAndValidate() error {
    27  	var account accountFile
    28  
    29  	// TODO: validation that it isn't blank
    30  	if c.AccountFile == "" {
    31  		c.AccountFile = os.Getenv("GOOGLE_ACCOUNT_FILE")
    32  	}
    33  	if c.Project == "" {
    34  		c.Project = os.Getenv("GOOGLE_PROJECT")
    35  	}
    36  	if c.Region == "" {
    37  		c.Region = os.Getenv("GOOGLE_REGION")
    38  	}
    39  
    40  	var client *http.Client
    41  
    42  	if c.AccountFile != "" {
    43  		if err := loadJSON(&account, c.AccountFile); err != nil {
    44  			return fmt.Errorf(
    45  				"Error loading account file '%s': %s",
    46  				c.AccountFile,
    47  				err)
    48  		}
    49  
    50  		clientScopes := []string{"https://www.googleapis.com/auth/compute"}
    51  
    52  		// Get the token for use in our requests
    53  		log.Printf("[INFO] Requesting Google token...")
    54  		log.Printf("[INFO]   -- Email: %s", account.ClientEmail)
    55  		log.Printf("[INFO]   -- Scopes: %s", clientScopes)
    56  		log.Printf("[INFO]   -- Private Key Length: %d", len(account.PrivateKey))
    57  
    58  		conf := jwt.Config{
    59  			Email:      account.ClientEmail,
    60  			PrivateKey: []byte(account.PrivateKey),
    61  			Scopes:     clientScopes,
    62  			TokenURL:   "https://accounts.google.com/o/oauth2/token",
    63  		}
    64  
    65  		// Initiate an http.Client. The following GET request will be
    66  		// authorized and authenticated on the behalf of
    67  		// your service account.
    68  		client = conf.Client(oauth2.NoContext)
    69  
    70  	} else {
    71  		log.Printf("[INFO] Requesting Google token via GCE Service Role...")
    72  		client = &http.Client{
    73  			Transport: &oauth2.Transport{
    74  				// Fetch from Google Compute Engine's metadata server to retrieve
    75  				// an access token for the provided account.
    76  				// If no account is specified, "default" is used.
    77  				Source: google.ComputeTokenSource(""),
    78  			},
    79  		}
    80  
    81  	}
    82  
    83  	log.Printf("[INFO] Instantiating GCE client...")
    84  	var err error
    85  	c.clientCompute, err = compute.New(client)
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	return nil
    91  }
    92  
    93  // accountFile represents the structure of the account file JSON file.
    94  type accountFile struct {
    95  	PrivateKeyId string `json:"private_key_id"`
    96  	PrivateKey   string `json:"private_key"`
    97  	ClientEmail  string `json:"client_email"`
    98  	ClientId     string `json:"client_id"`
    99  }
   100  
   101  func loadJSON(result interface{}, path string) error {
   102  	f, err := os.Open(path)
   103  	if err != nil {
   104  		return err
   105  	}
   106  	defer f.Close()
   107  
   108  	dec := json.NewDecoder(f)
   109  	return dec.Decode(result)
   110  }