Merge pull request #884 from hashicorp/452-google-secrets-file
[REPACK] #452 providers/google: remove deprecated client secrets file
This commit is contained in:
commit
24c3718ac6
|
@ -17,17 +17,26 @@ const clientScopes string = "https://www.googleapis.com/auth/compute"
|
|||
// Config is the configuration structure used to instantiate the Google
|
||||
// provider.
|
||||
type Config struct {
|
||||
AccountFile string
|
||||
ClientSecretsFile string
|
||||
Project string
|
||||
Region string
|
||||
AccountFile string
|
||||
Project string
|
||||
Region string
|
||||
|
||||
clientCompute *compute.Service
|
||||
}
|
||||
|
||||
func (c *Config) loadAndValidate() error {
|
||||
var account accountFile
|
||||
var secrets clientSecretsFile
|
||||
|
||||
// TODO: validation that it isn't blank
|
||||
if c.AccountFile == "" {
|
||||
c.AccountFile = os.Getenv("GOOGLE_ACCOUNT_FILE")
|
||||
}
|
||||
if c.Project == "" {
|
||||
c.Project = os.Getenv("GOOGLE_PROJECT")
|
||||
}
|
||||
if c.Region == "" {
|
||||
c.Region = os.Getenv("GOOGLE_REGION")
|
||||
}
|
||||
|
||||
if err := loadJSON(&account, c.AccountFile); err != nil {
|
||||
return fmt.Errorf(
|
||||
|
@ -36,24 +45,15 @@ func (c *Config) loadAndValidate() error {
|
|||
err)
|
||||
}
|
||||
|
||||
if err := loadJSON(&secrets, c.ClientSecretsFile); err != nil {
|
||||
return fmt.Errorf(
|
||||
"Error loading client secrets file '%s': %s",
|
||||
c.ClientSecretsFile,
|
||||
err)
|
||||
}
|
||||
|
||||
// Get the token for use in our requests
|
||||
log.Printf("[INFO] Requesting Google token...")
|
||||
log.Printf("[INFO] -- Email: %s", account.ClientEmail)
|
||||
log.Printf("[INFO] -- Scopes: %s", clientScopes)
|
||||
log.Printf("[INFO] -- Private Key Length: %d", len(account.PrivateKey))
|
||||
log.Printf("[INFO] -- Token URL: %s", secrets.Web.TokenURI)
|
||||
jwtTok := jwt.NewToken(
|
||||
account.ClientEmail,
|
||||
clientScopes,
|
||||
[]byte(account.PrivateKey))
|
||||
jwtTok.ClaimSet.Aud = secrets.Web.TokenURI
|
||||
token, err := jwtTok.Assert(new(http.Client))
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error retrieving auth token: %s", err)
|
||||
|
@ -64,8 +64,6 @@ func (c *Config) loadAndValidate() error {
|
|||
Config: &oauth.Config{
|
||||
ClientId: account.ClientId,
|
||||
Scope: clientScopes,
|
||||
TokenURL: secrets.Web.TokenURI,
|
||||
AuthURL: secrets.Web.AuthURI,
|
||||
},
|
||||
Token: token,
|
||||
}
|
||||
|
@ -87,16 +85,6 @@ type accountFile struct {
|
|||
ClientId string `json:"client_id"`
|
||||
}
|
||||
|
||||
// clientSecretsFile represents the structure of the client secrets JSON file.
|
||||
type clientSecretsFile struct {
|
||||
Web struct {
|
||||
AuthURI string `json:"auth_uri"`
|
||||
ClientEmail string `json:"client_email"`
|
||||
ClientId string `json:"client_id"`
|
||||
TokenURI string `json:"token_uri"`
|
||||
}
|
||||
}
|
||||
|
||||
func loadJSON(result interface{}, path string) error {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
|
|
|
@ -22,20 +22,3 @@ func TestConfigLoadJSON_account(t *testing.T) {
|
|||
t.Fatalf("bad: %#v", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigLoadJSON_client(t *testing.T) {
|
||||
var actual clientSecretsFile
|
||||
if err := loadJSON(&actual, "./test-fixtures/fake_client.json"); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
var expected clientSecretsFile
|
||||
expected.Web.AuthURI = "https://accounts.google.com/o/oauth2/auth"
|
||||
expected.Web.ClientEmail = "foo@developer.gserviceaccount.com"
|
||||
expected.Web.ClientId = "foo.apps.googleusercontent.com"
|
||||
expected.Web.TokenURI = "https://accounts.google.com/o/oauth2/token"
|
||||
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Fatalf("bad: %#v", actual)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,12 +15,6 @@ func Provider() terraform.ResourceProvider {
|
|||
DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE", nil),
|
||||
},
|
||||
|
||||
"client_secrets_file": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("GOOGLE_CLIENT_FILE", nil),
|
||||
},
|
||||
|
||||
"project": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
|
@ -49,10 +43,9 @@ func Provider() terraform.ResourceProvider {
|
|||
|
||||
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
||||
config := Config{
|
||||
AccountFile: d.Get("account_file").(string),
|
||||
ClientSecretsFile: d.Get("client_secrets_file").(string),
|
||||
Project: d.Get("project").(string),
|
||||
Region: d.Get("region").(string),
|
||||
AccountFile: d.Get("account_file").(string),
|
||||
Project: d.Get("project").(string),
|
||||
Region: d.Get("region").(string),
|
||||
}
|
||||
|
||||
if err := config.loadAndValidate(); err != nil {
|
||||
|
|
|
@ -33,10 +33,6 @@ func testAccPreCheck(t *testing.T) {
|
|||
t.Fatal("GOOGLE_ACCOUNT_FILE must be set for acceptance tests")
|
||||
}
|
||||
|
||||
if v := os.Getenv("GOOGLE_CLIENT_FILE"); v == "" {
|
||||
t.Fatal("GOOGLE_CLIENT_FILE must be set for acceptance tests")
|
||||
}
|
||||
|
||||
if v := os.Getenv("GOOGLE_PROJECT"); v == "" {
|
||||
t.Fatal("GOOGLE_PROJECT must be set for acceptance tests")
|
||||
}
|
||||
|
|
|
@ -137,11 +137,11 @@ func resourceComputeInstance() *schema.Resource {
|
|||
},
|
||||
|
||||
"scopes": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
StateFunc: func(v interface{}) string {
|
||||
return canonicalizeServiceScope(v.(string))
|
||||
},
|
||||
|
@ -294,11 +294,11 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err
|
|||
scopesCount := d.Get(prefix + ".scopes.#").(int)
|
||||
scopes := make([]string, 0, scopesCount)
|
||||
for j := 0; j < scopesCount; j++ {
|
||||
scope := d.Get(fmt.Sprintf(prefix + ".scopes.%d", j)).(string)
|
||||
scope := d.Get(fmt.Sprintf(prefix+".scopes.%d", j)).(string)
|
||||
scopes = append(scopes, canonicalizeServiceScope(scope))
|
||||
}
|
||||
|
||||
serviceAccount := &compute.ServiceAccount {
|
||||
serviceAccount := &compute.ServiceAccount{
|
||||
Email: "default",
|
||||
Scopes: scopes,
|
||||
}
|
||||
|
@ -378,8 +378,8 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error
|
|||
// Set the service accounts
|
||||
for i, serviceAccount := range instance.ServiceAccounts {
|
||||
prefix := fmt.Sprintf("service_account.%d", i)
|
||||
d.Set(prefix + ".email", serviceAccount.Email)
|
||||
d.Set(prefix + ".scopes.#", len(serviceAccount.Scopes))
|
||||
d.Set(prefix+".email", serviceAccount.Email)
|
||||
d.Set(prefix+".scopes.#", len(serviceAccount.Scopes))
|
||||
for j, scope := range serviceAccount.Scopes {
|
||||
d.Set(fmt.Sprintf("%s.scopes.%d", prefix, j), scope)
|
||||
}
|
||||
|
@ -534,14 +534,19 @@ func resourceComputeInstanceDelete(d *schema.ResourceData, meta interface{}) err
|
|||
|
||||
func resourceInstanceMetadata(d *schema.ResourceData) *compute.Metadata {
|
||||
var metadata *compute.Metadata
|
||||
if v := d.Get("metadata").([]interface{}); len(v) > 0 {
|
||||
if metadataList := d.Get("metadata").([]interface{}); len(metadataList) > 0 {
|
||||
m := new(compute.Metadata)
|
||||
m.Items = make([]*compute.MetadataItems, 0, len(v))
|
||||
for _, v := range v {
|
||||
for k, v := range v.(map[string]interface{}) {
|
||||
m.Items = make([]*compute.MetadataItems, 0, len(metadataList))
|
||||
for _, metadataMap := range metadataList {
|
||||
for key, val := range metadataMap.(map[string]interface{}) {
|
||||
// TODO: fix https://github.com/hashicorp/terraform/issues/883
|
||||
// and remove this workaround <3 phinze
|
||||
if key == "#" {
|
||||
continue
|
||||
}
|
||||
m.Items = append(m.Items, &compute.MetadataItems{
|
||||
Key: k,
|
||||
Value: v.(string),
|
||||
Key: key,
|
||||
Value: val.(string),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ Use the navigation to the left to read about the available resources.
|
|||
# Configure the Google Cloud provider
|
||||
provider "google" {
|
||||
account_file = "account.json"
|
||||
client_secrets_file = "client_secrets.json"
|
||||
project = "my-gce-project"
|
||||
region = "us-central1"
|
||||
}
|
||||
|
@ -39,33 +38,23 @@ The following keys can be used to configure the provider.
|
|||
your account credentials, downloaded from Google Cloud Console. More
|
||||
details on retrieving this file are below.
|
||||
|
||||
* `client_secrets_file` - (Required) Path to the JSON file containing
|
||||
the secrets for your account, downloaded from Google Cloud Console.
|
||||
More details on retrieving this file are below.
|
||||
|
||||
* `project` - (Required) The name of the project to apply any resources to.
|
||||
|
||||
* `region` - (Required) The region to operate under.
|
||||
|
||||
## Authentication JSON Files
|
||||
## Authentication JSON File
|
||||
|
||||
Authenticating with Google Cloud services requires two separate JSON
|
||||
files: one which we call the _account file_ and the _client secrets file_.
|
||||
Authenticating with Google Cloud services requires a JSON
|
||||
file which we call the _account file_.
|
||||
|
||||
Both of these files are downloaded directly from the
|
||||
This file is downloaded directly from the
|
||||
[Google Developers Console](https://console.developers.google.com). To make
|
||||
the process more straightforwarded, it is documented here.
|
||||
the process more straightforwarded, it is documented here:
|
||||
|
||||
1. Log into the [Google Developers Console](https://console.developers.google.com)
|
||||
and select a project.
|
||||
|
||||
2. Under the "APIs & Auth" section, click "Credentials."
|
||||
|
||||
3. Create a new OAuth client ID and select "Installed application" as the
|
||||
type of account. Once created, click the "Download JSON" button underneath
|
||||
the account. The file should start with "client\_secret". This is your _client
|
||||
secrets file_.
|
||||
|
||||
4. Create a new OAuth client ID and select "Service account" as the type
|
||||
of account. Once created, a JSON file should be downloaded. This is your
|
||||
_account file_.
|
||||
3. Create a new OAuth client ID and select "Service account" as the type
|
||||
of account. Once created, and after a P12 key is downloaded, a JSON file should be downloaded. This is your _account file_.
|
||||
|
|
Loading…
Reference in New Issue