diff --git a/google/resource_compute_interconnect_attachment.go b/google/resource_compute_interconnect_attachment.go index 42c94e5b518..10e05580755 100644 --- a/google/resource_compute_interconnect_attachment.go +++ b/google/resource_compute_interconnect_attachment.go @@ -21,10 +21,30 @@ import ( "strconv" "time" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ) +// waitForAttachmentToBeProvisioned waits for an attachment to leave the +// "UNPROVISIONED" state, to indicate that it's either ready or awaiting partner +// activity. +func waitForAttachmentToBeProvisioned(d *schema.ResourceData, config *Config, timeout time.Duration) error { + return resource.Retry(timeout, func() *resource.RetryError { + if err := resourceComputeInterconnectAttachmentRead(d, config); err != nil { + return resource.NonRetryableError(err) + } + + name := d.Get("name").(string) + state := d.Get("state").(string) + if state == "UNPROVISIONED" { + return resource.RetryableError(fmt.Errorf("InterconnectAttachment %q has state %q.", name, state)) + } + log.Printf("InterconnectAttachment %q has state %q.", name, state) + return nil + }) +} + func resourceComputeInterconnectAttachment() *schema.Resource { return &schema.Resource{ Create: resourceComputeInterconnectAttachmentCreate, @@ -36,8 +56,8 @@ func resourceComputeInterconnectAttachment() *schema.Resource { }, Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(4 * time.Minute), - Delete: schema.DefaultTimeout(4 * time.Minute), + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), }, Schema: map[string]*schema.Schema{ @@ -326,6 +346,10 @@ func resourceComputeInterconnectAttachmentCreate(d *schema.ResourceData, meta in log.Printf("[DEBUG] Finished creating InterconnectAttachment %q: %#v", d.Id(), res) + if err := waitForAttachmentToBeProvisioned(d, config, d.Timeout(schema.TimeoutCreate)); err != nil { + return fmt.Errorf("Error waiting for InterconnectAttachment %q to be provisioned: %q", d.Get("name").(string), err) + } + return resourceComputeInterconnectAttachmentRead(d, meta) } @@ -428,6 +452,9 @@ func resourceComputeInterconnectAttachmentDelete(d *schema.ResourceData, meta in } var obj map[string]interface{} + if err := waitForAttachmentToBeProvisioned(d, config, d.Timeout(schema.TimeoutCreate)); err != nil { + return fmt.Errorf("Error waiting for InterconnectAttachment %q to be provisioned: %q", d.Get("name").(string), err) + } log.Printf("[DEBUG] Deleting InterconnectAttachment %q", d.Id()) res, err := sendRequestWithTimeout(config, "DELETE", project, url, obj, d.Timeout(schema.TimeoutDelete)) diff --git a/google/resource_compute_interconnect_attachment_sweeper_test.go b/google/resource_compute_interconnect_attachment_sweeper_test.go deleted file mode 100644 index 9bc2ff21625..00000000000 --- a/google/resource_compute_interconnect_attachment_sweeper_test.go +++ /dev/null @@ -1,119 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** -// -// ---------------------------------------------------------------------------- -// -// This file is automatically generated by Magic Modules and manual -// changes will be clobbered when the file is regenerated. -// -// Please read more about how to change this file in -// .github/CONTRIBUTING.md. -// -// ---------------------------------------------------------------------------- - -package google - -import ( - "context" - "log" - "strings" - - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" -) - -func init() { - resource.AddTestSweepers("ComputeInterconnectAttachment", &resource.Sweeper{ - Name: "ComputeInterconnectAttachment", - F: testSweepComputeInterconnectAttachment, - }) -} - -// At the time of writing, the CI only passes us-central1 as the region -func testSweepComputeInterconnectAttachment(region string) error { - resourceName := "ComputeInterconnectAttachment" - log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) - - config, err := sharedConfigForRegion(region) - if err != nil { - log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) - return err - } - - err = config.LoadAndValidate(context.Background()) - if err != nil { - log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) - return err - } - - // Setup variables to replace in list template - d := &ResourceDataMock{ - FieldsInSchema: map[string]interface{}{ - "project": config.Project, - "region": region, - "location": region, - "zone": "-", - }, - } - - listTemplate := strings.Split("https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/interconnectAttachments", "?")[0] - listUrl, err := replaceVars(d, config, listTemplate) - if err != nil { - log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err) - return nil - } - - res, err := sendRequest(config, "GET", config.Project, listUrl, nil) - if err != nil { - log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) - return nil - } - - resourceList, ok := res["items"] - if !ok { - log.Printf("[INFO][SWEEPER_LOG] Nothing found in response.") - return nil - } - - rl := resourceList.([]interface{}) - - log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName) - // items who don't match the tf-test prefix - nonPrefixCount := 0 - for _, ri := range rl { - obj := ri.(map[string]interface{}) - if obj["name"] == nil { - log.Printf("[INFO][SWEEPER_LOG] %s resource name was nil", resourceName) - return nil - } - - name := GetResourceNameFromSelfLink(obj["name"].(string)) - // Only sweep resources with the test prefix - if !strings.HasPrefix(name, "tf-test") { - nonPrefixCount++ - continue - } - - deleteTemplate := "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/interconnectAttachments/{{name}}" - deleteUrl, err := replaceVars(d, config, deleteTemplate) - if err != nil { - log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err) - return nil - } - deleteUrl = deleteUrl + name - - // Don't wait on operations as we may have a lot to delete - _, err = sendRequest(config, "DELETE", config.Project, deleteUrl, nil) - if err != nil { - log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) - } else { - log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name) - } - } - - if nonPrefixCount > 0 { - log.Printf("[INFO][SWEEPER_LOG] %d items without tf_test prefix remain.", nonPrefixCount) - } - - return nil -} diff --git a/website/docs/r/compute_interconnect_attachment.html.markdown b/website/docs/r/compute_interconnect_attachment.html.markdown index fd38acbeaa9..1b9d7552d46 100644 --- a/website/docs/r/compute_interconnect_attachment.html.markdown +++ b/website/docs/r/compute_interconnect_attachment.html.markdown @@ -178,8 +178,8 @@ The `private_interconnect_info` block contains: This resource provides the following [Timeouts](/docs/configuration/resources.html#timeouts) configuration options: -- `create` - Default is 4 minutes. -- `delete` - Default is 4 minutes. +- `create` - Default is 10 minutes. +- `delete` - Default is 10 minutes. ## Import