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  }