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

provider/google : add a new resource : google_compute_snapshot #12482

Merged
merged 21 commits into from
May 3, 2017

Conversation

tpoindessous
Copy link
Contributor

Hi

here is a WIP for addressing issue #11690

This PR adds a new resource : google_compute_snapshot

For today, I only tested creating and deleting a simple snapshot.

Also, I don't know how the documentation is made.

I will add tests acceptance in next days.

Thanks.

@tpoindessous
Copy link
Contributor Author

Hi,

my test acceptance doesn't work for the moment, terraform doesn't handle very the delete command, so created disks are not deleted yet.

Thanks

@tpoindessous tpoindessous changed the title [WIP] provider/google : add a new resource : google_compute_snapshot provider/google : add a new resource : google_compute_snapshot Mar 13, 2017
@tpoindessous
Copy link
Contributor Author

Hi

I corrected the test acceptance. Everything works now.

Thanks.

@tpoindessous
Copy link
Contributor Author

Hi @paddyforan

I think this PR is ready to be reviewed, I added the documentation. Please tell me if I need to change something.

Thanks !

@paddycarver
Copy link
Contributor

Hey @tpoindessous! Thanks for the PR! I literally have a browser tab open to review it, but unfortunately, it's 2:30 in the morning here, so I need to get some sleep. I'm not sure I'll get to it tomorrow, as I already queued myself a pretty big workload (trying to recover from Next!) but this is on my radar and will get a review ASAP. I just need to set aside some time to do a deep dive and understand it better, along with the problem space. Thanks so much for the patience and PR, however; both are incredibly appreciated.

Copy link
Contributor

@paddycarver paddycarver left a comment

Choose a reason for hiding this comment

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

Hey @tpoindessous! Thanks for the PR, and sorry for the delayed review. This looks super great and follows a lot of our best practices. 👏

The only comments/concerns I have are basically polish:

  • I prefer sourcedisk as source_disk, as it's two words. Open to discussion on that.
  • We're trying to make sure all new resources are implemented with an Exists function, as a best practice.
  • We're trying to make sure everything gets set in state how the API returns it (unless there's a good reason not to).
  • I'd love to see the tests expanded to verify that the fields were actually set on the resource.

Really appreciate the effort you've put into this; I think it's basically ready. If you have any problems with these changes, would like to discuss any of them, or would like someone else to take over this PR and push it past the finish line, we're here to help. :)

Computed: true,
},

"sourcedisk_encryption_key_raw": &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.

sourcedisk => source_disk?

Sensitive: true,
},

"sourcedisk_encryption_key_sha256": &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.

sourcedisk => source_disk?

Computed: true,
},

"sourcedisk_id": &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.

sourcedisk => source_disk?

Computed: true,
},

"sourcedisk": &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.

sourcedisk => source_disk?

d.Set("self_link", snapshot.SelfLink)
if snapshot.SnapshotEncryptionKey != nil && snapshot.SnapshotEncryptionKey.Sha256 != "" {
d.Set("snapshot_encryption_key_sha256", snapshot.SnapshotEncryptionKey.Sha256)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

It may sounds silly, but do you mind setting the other fields here to what the API returns? Especially sourcedisk_encryption_key_sha256, but the others too. I know they're in the config, but setting what the API returns will help Terraform detect if something on the API side gets out of sync with something on the Terraform side. For this resource it isn't as big a deal, but it's better to follow the best practice, unless we can't.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi, just to be sure : I need to duplicate lines 149-151 for each other fields returned by the API ?
Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Forget my question. I just understood that my code was missing setting computed fields.

Thanks

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 not sure the if is necessary for every one, but yeah, ideally, we'd have a Set for every field in the resource that the API returns.

This is because the Set is how data from the API gets into the state, and Terraform diffs the state and the config to find if there's a difference. So the only way Terraform knows if the API and the config don't match is if we Set the data appropriately.

return &schema.Resource{
Create: resourceComputeSnapshotCreate,
Read: resourceComputeSnapshotRead,
Delete: resourceComputeSnapshotDelete,
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd love to see an Exists function, as well!


_, err := config.clientCompute.Snapshots.Get(
config.Project, rs.Primary.ID).Do()
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.

What happens if there's a server error/network error/anything but a 404?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would be it OK to add this test :

if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {

Copy link
Contributor

Choose a reason for hiding this comment

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

That would be perfect!

Copy link
Contributor

Choose a reason for hiding this comment

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

(Assuming, of course, we check for non-404 errors and return that error, as well.)

}
}

func testAccCheckSnapshotEncryptionKey(n string, snapshot *compute.Snapshot) resource.TestCheckFunc {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd love to see checks for the other fields, as well. They could probably be combined into testAccCheckComputeSnapshotExists.


* `zone` - (Required) The zone where the source disk is located.

* `disk` - (Required)
Copy link
Contributor

Choose a reason for hiding this comment

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

A description would be great here.

Copy link
Contributor Author

@tpoindessous tpoindessous left a comment

Choose a reason for hiding this comment

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

Hi

I think I did all that you asked for.

I don't know how to test "Exists" function and I don't know what its purpose. Can you, please, send me to the right doc ? I would like to understand its usage.

Thanks !

Copy link
Contributor

@paddycarver paddycarver left a comment

Choose a reason for hiding this comment

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

Looks super great, thanks @tpoindessous. Couple minor things, mostly doc updates. The only other thing I'm curious about is why we have both disk and source_disk. Couldn't we just make source_disk required and not computed and get rid of disk? Wouldn't that be the same effect, or am I missing something?

As for testing Exists, Exists just adds a layer of code safety to the resource by letting Terraform detect whether it exists or not, so Terraform doesn't need to make API calls to figure out that it's recreating something that already exists, or deleting something that doesn't exist, etc. I'm not sure about testing it--I've never seen dedicated tests. Generally, if the configs work with the Exists function in place, that's exercising that code path, as far as I know.


- - -

* `sourcedisk_encryption_key_raw` - (Optional) A 256-bit [customer-supplied encryption key]
Copy link
Contributor

Choose a reason for hiding this comment

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

Think this needs to be updated to source_disk_encryption_key_raw.

[customer-supplied encryption key](https://cloud.google.com/compute/docs/disks/customer-supplied-encryption)
that protects this resource.

* `sourcedisk_encryption_key_sha256` - The [RFC 4648 base64]
Copy link
Contributor

Choose a reason for hiding this comment

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

Think this needs to be updated to source_disk_encryption_key_sha256.

[customer-supplied encryption key](https://cloud.google.com/compute/docs/disks/customer-supplied-encryption)
that protects the source disk.

* `sourcedisk_id` - The ID value of the source disk used to create this snapshot.
Copy link
Contributor

Choose a reason for hiding this comment

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

Think this needs to be updated to source_disk_id.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, how is this different from source_disk?

This value may be used to determine whether the snapshot was taken from the
current or a previous instance of a given disk name.

* `sourcedisk` - The source disk used to create this snapshot.
Copy link
Contributor

Choose a reason for hiding this comment

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

Think this needs to be updated to source_disk.


* `zone` - (Required) The zone where the source disk is located.

* `disk` - (Required) The disk which will be used as the source of the snapshot
Copy link
Contributor

Choose a reason for hiding this comment

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

How is disk different from source_disk? Won't they always match?

@tpoindessous
Copy link
Contributor Author

Hi @paddyforan

I first tried to replicate Google API to Terraform, but since Terraform keeps the state, some attributes are not needed, as you requested.

I dropped sourcedisk_id and disk attributes.

Thanks.

Copy link
Contributor Author

@tpoindessous tpoindessous left a comment

Choose a reason for hiding this comment

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

HI @paddyforan

Thank for your comments.

I changed code to resolve them.

Thanks.

@tpoindessous
Copy link
Contributor Author

Hi @paddyforan

sorry to bother you ... I take the risk to ping you about this PR :)

Thanks for your time :)

@paddycarver
Copy link
Contributor

Hey @tpoindessous! No risk in pinging--it is my job to review it, after all! You were generous enough to write code to add the feature, the least I can do is look at it. Apologies for the delay on this, I could've sworn I replied to it already. I'll take a look right now and hopefully we can get this in the 0.9.4 release; you've certainly been patient enough about it.

Copy link
Contributor

@paddycarver paddycarver left a comment

Choose a reason for hiding this comment

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

Just a couple of test changes (and a documentation fix, if you're so inclined) and this looks good to me. Feel free to ping me as soon as that's done and you'll jump to the top of my to-do list so we can merge this.

If you've (understandably) moved on to other things because feedback took so long, that's fine, just let me know and I'll push this across the finish line myself. :)

d.Set("source_disk_encryption_key_sha256", snapshot.SourceDiskEncryptionKey.Sha256)
}

d.Set("source_disk", snapshot.SourceDisk)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd love to see

d.Set("name", snapshot.Name)

Here as well, but I'm not willing to hold this any longer over it.

@@ -0,0 +1,64 @@
---
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 going to need to add this resource to the menu as well, but I can always fix that up after.


resource "google_compute_snapshot" "foobar" {
name = "%s"
disk = "${google_compute_disk.foobar.name}"
Copy link
Contributor

Choose a reason for hiding this comment

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

Tests don't run for me, looks like you want source_disk here.

}
resource "google_compute_snapshot" "foobar" {
name = "%s"
disk = "${google_compute_disk.foobar.name}"
Copy link
Contributor

Choose a reason for hiding this comment

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

Tests don't run for me, looks like you want source_disk here.

@tpoindessous
Copy link
Contributor Author

Thanks @paddyforan

Sorry for the failing tests ...

I will do all your points.

I'm stuck with a design error : gcp.sourceDisk is an URL when TF source_disk is a name. So it's not matching. I will look at it in the next days, maybe I will revert change to use "disk" in TF and exposing source_disk only in output (it can be useful). But I need to find the right word in documentation.

I will come back to you only when tests will be OK and all your points are corrected.

Have a nice week-end and a nice Easter.

Copy link
Contributor Author

@tpoindessous tpoindessous left a comment

Choose a reason for hiding this comment

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

Hi !

I just finished all the tasks (I think).

The two tests are OK.

Thanks.

@tpoindessous
Copy link
Contributor Author

Hi

I corrected all the remarks you made. I added the new resource doc in the nav panel.

the two tests are OK :
$ make testacc TEST=./builtin/providers/google TESTARGS='-run=TestAccComputeSnapshot_basic'
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2017/04/20 12:51:32 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/google -v -run=TestAccComputeSnapshot_basic -timeout 120m
=== RUN TestAccComputeSnapshot_basic
--- PASS: TestAccComputeSnapshot_basic (72.11s)
PASS
ok github.com/hashicorp/terraform/builtin/providers/google 72.130s

$ make testacc TEST=./builtin/providers/google TESTARGS='-run=TestAccComputeSnapshot_encryption'
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2017/04/20 12:53:26 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/google -v -run=TestAccComputeSnapshot_encryption -timeout 120m
=== RUN TestAccComputeSnapshot_encryption
--- PASS: TestAccComputeSnapshot_encryption (72.97s)
PASS
ok github.com/hashicorp/terraform/builtin/providers/google 72.986s

Thanks !

@paddycarver
Copy link
Contributor

Hey @tpoindessous!

Sorry for the failing tests ...

No worries! It happens to the best of us. :)

I'm stuck with a design error : gcp.sourceDisk is an URL when TF source_disk is a name. So it's not matching. I will look at it in the next days, maybe I will revert change to use "disk" in TF and exposing source_disk only in output (it can be useful). But I need to find the right word in documentation.

Last question on this:

Is there a reason not to accept the name or URL for the source_disk parameter, and just expand to the URL? That would fix the problem, right?

Thanks so much for your effort and patience on this. If this is getting too drawn-out and your interest wanes, just let me know and I'm happy to do the work to push it over the finish line. :) You've been amazing, but I don't want to assume your generosity and patience are infinite.

(Also, I promise a quick review and reply.)

@nodesocket
Copy link

nodesocket commented May 1, 2017

👍 on this PR. I wonder if it makes sense once this is merged and deployed to take backup snapshots of disks using Terraform? Then the question becomes, how to schedule snapshots with Terraform.

@tpoindessous
Copy link
Contributor Author

Hi @paddycarver

we can't use get method of Disk object with a URL. Maybe we could use this method
https://cloud.google.com/compute/docs/reference/latest/disks/aggregatedList to find the right Disk but I think this may be a lot of work ... I'm not sure I can do it.

Can you please review my last commit ? I added some tests to be sure that the source_disk matches the same disk as source_disk_link.

I have prepared a new PR to add dataSourceGoogleComputeSnapshot, I think I will push it in the next 2 weeks.

Thanks.

Thomas

@paddycarver
Copy link
Contributor

we can't use get method of Disk object with a URL.

I guess I'm confused. The URL contains the Disk name, couldn't we just pull it out of that? I'd like to, if possible, accept either here and just Do The Right Thing. But I also feel like I'm missing context. I'm going to read through all the code again right now and see if I can spot the problem.

Copy link
Contributor

@paddycarver paddycarver left a comment

Choose a reason for hiding this comment

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

After reading through the code, the only wart I could find is source_disk vs. source_disk_link. And while that has a solution, I'm not sure the solution is worth another round of back and forth. I think this offers ample benefit and is in great condition for a merge, and that wart can be fixed without any serious backwards compatibility concerns, so I think it's worthwhile to merge this now and wait for that to actually be a problem before trying to solve it.

Thanks so much for all the dedication, work, and patience on this.

@paddycarver paddycarver merged commit dc63d8c into hashicorp:master May 3, 2017
@tpoindessous tpoindessous deleted the gcp_compute_disk_snapshot branch May 5, 2017 09:47
@ghost
Copy link

ghost commented Apr 13, 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 have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 13, 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.

3 participants