Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for google_service_account_key #472

Merged
merged 11 commits into from
Oct 25, 2017
Merged

Conversation

sebglon
Copy link
Contributor

@sebglon sebglon commented Sep 27, 2017

to correct PR #204

Copy link
Contributor

@danawillow danawillow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm, this change adds about 70 new vendored files. Is that intentional?

Also, before this is checked in it'll need documentation in the website/ folder.

}

d.SetId(sak.Name)
d.Set("name", sak.Name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of setting these values on create, we usually call the read function at the end of the create function. Is it possible for you to do that here? Alternatively, if your goal was to avoid an extra API call you could add a helper function that could take the ServiceAccountKey object and do the d.Set calls

Required: true,
ForceNew: true,
},
"name": &schema.Schema{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're trying to get to a more clear way of ordering fields in the schema, by doing Requireds, then Optionals, then Computeds. Mind doing that here too?

}

func testAccGoogleServiceAccountKey(account, name string) string {
t := `resource "google_service_account" "acceptance" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency with other resources, can you just start this with the fmt.Sprintf instead of making it a variable?

}

resource "google_service_account_key" "acceptance" {
service_account_id = "${google_service_account.acceptance.id}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you also want to test some of the other fields? There's some logic regarding pgp keys in your create function so at a minimum I'd like to see that tested, but ideally the other fields as well

resource.TestStep{
Config: testAccGoogleServiceAccountKey(accountId, displayName),
Check: resource.ComposeTestCheckFunc(
testAccCheckGoogleServiceAccountKeyExists("google_service_account_key.acceptance"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can check values with fields with resource.TestCheckResourceAttr to ensure they have the values you want instead of just that the resource exists

return fmt.Errorf("Error creating service account key: %s", err)
}

if v, ok := d.GetOk("pgp_key"); ok {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused about this part, since it's just reading a value from the config, encrypting it, and then storing it back in state. I'm not totally against it, but it does make me cautious since it's not necessarily matching the API. What's the use case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use case is to get GPG_key on output for using it with another tools. If it is possible to have them on outpup without storing it, i'm interesting.

@sebglon
Copy link
Contributor Author

sebglon commented Oct 3, 2017

@danawillow I have modified all comment except Adding test on all fields.
Is it possible to have field output without storing them? If it's possible, i can remove all added vendor.

@sebglon
Copy link
Contributor Author

sebglon commented Oct 13, 2017

I have open on issue on Google googleapis/google-api-go-client#234
Because create finish in 200 but if you make get just after we have 404 with the generated key name.
If i wait 10 sec or more under create and get, i have get 200.
And if i refresh google console i can see the key but i can't download public key on it to validate.

@danawillow can you see help us on google to have the good people?

@sebglon
Copy link
Contributor Author

sebglon commented Oct 16, 2017

I have added a workaroud for waiting public Key.
Is ti possible to Validate doc?


r := &iam.CreateServiceAccountKeyRequest{}

if v, ok := d.GetOk("key_algorithm"); ok {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this has a default value, ok will always be true, and this and the above can be simplified to:

r := &iam.CreateServiceAccountKeyRequest {
  KeyAlgorithm: d.Get("key_algorithm").(string),
}

}

if pubKey == "" {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extra newline

pubKey = pubkeyInterface.(string)
}

if pubKey == "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this variable never gets used, it might make sense to just not set it at all and instead do an if statement like:

if _, ok := d.GetOk("public_key"); !ok {
// stuff
}


sak, err := config.clientIAM.Projects.ServiceAccounts.Keys.Create(serviceAccount, r).Do()
if err != nil || sak == nil {
return fmt.Errorf("Error creating service account key: %s", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be nice to differentiate in the message the case where it returned an error vs returning nothing

Required: true,
ForceNew: true,
},
"public_key_type": &schema.Schema{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this value has a reasonable default: https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts.keys/get. Any reason why it's Required vs private_key_type and key_algorithm being Optional?

Optional: true,
ForceNew: true,
},
"private_key": &schema.Schema{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be down in the Computed section


## Import

Lightsail Key Pairs cannot be imported, because the private and public key are
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's lightsail?

}
```

## Argument Reference
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing docs for public_key_type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes


## Attributes Reference

The following attributes are exported in addition to the arguments listed above:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also valid_after and valid_before

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

* `public_key` - the public key, base64 encoded
* `private_key` - the private key, base64 encoded. This is only populated
when creating a new key, and when no `pgp_key` is provided
* `encrypted_private_key` – the private key material, base 64 encoded and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the schema these are called private_key_encrypted and private_key_fingerprint


r.PrivateKeyType = d.Get("private_key_type").(string)

sak, err := config.clientIAM.Projects.ServiceAccounts.Keys.Create(serviceAccount, r).Do()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused, why do we only call the create function if public_key is unset?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes of course.

@aeneasr
Copy link

aeneasr commented Oct 22, 2017

Anything I can do to help speed up this PR? :) Creating service account keys is indispensable to configuring Google Cloud SQL on GKE containers as the Cloud SQL Proxy requires those credentials - otherwise it's not possible to connect from containers within GKE to Google Cloud SQL which in turn makes it impossible to automate the process with terraform at the moment.

Copy link
Contributor

@danawillow danawillow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost there!

KeyAlgorithm: d.Get("key_algorithm").(string),
}

var err error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have to declare this here since you initialize it just a few lines down with the :=


var err error

r.PrivateKeyType = d.Get("private_key_type").(string)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also add this into the struct on line 94ish like you did with key_algorithm

}

err = serviceAccountKeyWaitTime(config.clientIAM.Projects.ServiceAccounts.Keys, d.Id(), d.Get("public_key_type").(string), "Creating Service account key", 4)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's an error creating it, we probably want to d.SetId("") so it doesn't end up in state.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actualiy a bug on GCE IAM, the key is is well created but not downloadable just after creation. it is necessary to wait a few second or minut to download it.

The setId is good because key well exist

## Argument Reference

The following arguments are supported:
* `name` - The name used for this key pair (not used on create)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since name is computed, it probably belongs in the Attributes Reference section (and then you can get rid of the parenthetical)


The following attributes are exported in addition to the arguments listed above:

* `fingerprint` - The MD5 public key fingerprint as specified in section 4 of RFC 4716.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can you make sure there's a new line between each bullet point?

)

// Test that a service account key can be created and destroyed
func TestAccGoogleServiceAccountKey_basic(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add t.Parallel() (and then a new line) to the beginning of each of these tests?

public_key_type = "TYPE_X509_PEM_FILE"
pgp_key = <<EOF
%s
EOF
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have an extra space after the EOF which is causing the test to fail. If you remove the extra space it passes.

@danawillow
Copy link
Contributor

Oh also you'll want to add an entry into website/google.erb so the documentation shows up on the sidebar

@sebglon
Copy link
Contributor Author

sebglon commented Oct 24, 2017

All change are made.

if err != nil {
return err
}
resourceGoogleServiceAccountKeyRead(d, meta)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can just be return resourceGoogleServiceAccountKeyRead(d, meta) and then you can get rid of the rest of the function

"public_key": {
Type: schema.TypeString,
Computed: true,
Optional: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this Optional line should be removed, and this whole field should move into the Computed section

* `public_key` - The public key, base64 encoded

* `private_key` - The private key, base64 encoded. This is only populated

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the newline should be after the next line, not before it.


// Test that a service account key can be created and destroyed
func TestAccGoogleServiceAccountKey_basic(t *testing.T) {
t.Parallel()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: empty line after all t.Parallel()s

@@ -0,0 +1,85 @@
---
layout: "google"
page_title: "Google: google_service_accout_key"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: account

@@ -92,6 +92,10 @@
<li<%= sidebar_current("docs-google-service-account") %>>
<a href="/docs/providers/google/r/google_service_account.html">google_service_account</a>
</li>
<li<%= sidebar_current("docs-google-service-account") %>>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be docs-google-service-account-key

@sebglon
Copy link
Contributor Author

sebglon commented Oct 25, 2017

@danawillow All are good

@danawillow
Copy link
Contributor

Thanks @sebglon!

$ make testacc TEST=./google TESTARGS='-run=TestAccGoogleServiceAccountKey'
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go test ./google -v -run=TestAccGoogleServiceAccountKey -timeout 120m
=== RUN   TestAccGoogleServiceAccountKey_basic
=== RUN   TestAccGoogleServiceAccountKey_pgp
--- PASS: TestAccGoogleServiceAccountKey_pgp (59.03s)
--- PASS: TestAccGoogleServiceAccountKey_basic (60.13s)
PASS
ok  	github.com/terraform-providers/terraform-provider-google/google	60.324s

@danawillow danawillow merged commit 94e0b74 into hashicorp:master Oct 25, 2017
@aeneasr
Copy link

aeneasr commented Oct 25, 2017

Awesome, thank you both for your work on this! Is there a way to check the ETA of unreleased versions (specifically 1.1.2 :) )?

@danawillow
Copy link
Contributor

Our goal is to release every two weeks or so, but we don't give exact dates because sometimes we need the flexibility to release sooner or later.

@aeneasr
Copy link

aeneasr commented Oct 25, 2017

Thank you for the swift response, I'm looking forward to having this released!

@sebglon sebglon deleted the PR-204 branch October 25, 2017 20:27
@aeneasr
Copy link

aeneasr commented Nov 1, 2017

Hope this doesn't come by as annoying, but this issue has actually blocked my team and me since it came up. It would be extremely awesome if it was possible to release some time this week, especially because i have no idea how to add custom built plugins to terraform (installed from binaries).

chrisst pushed a commit to chrisst/terraform-provider-google that referenced this pull request Nov 9, 2018
* Initial support for google service account keys

* Add vendor for vault and encryption

* Add change for PR comment

* Add doc and improvement fo public key management

* adding waiter for compatibility with issue googleapis/google-api-go-client#234

* improvement

* Add test with pgp_key

* Perform doc anf format

* remove test if public_key exists

* Add link on doc

* correct pr
luis-silva pushed a commit to luis-silva/terraform-provider-google that referenced this pull request May 21, 2019
@ghost
Copy link

ghost commented Mar 30, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 hashibot-feedback@hashicorp.com. Thanks!

@ghost ghost locked and limited conversation to collaborators Mar 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants