From 642d38fd025d1c73ce1d47160095121a107f74c3 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Mon, 21 Oct 2019 15:07:20 -0700 Subject: [PATCH 1/8] Composer environment and compute attached disk id updates --- .../resource_composer_environment.go.erb | 2 +- .../resource_compute_attached_disk.go | 19 +++++++------------ .../resource_compute_attached_disk_test.go | 6 +++--- .../r/compute_attached_disk.html.markdown | 4 ++-- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/third_party/terraform/resources/resource_composer_environment.go.erb b/third_party/terraform/resources/resource_composer_environment.go.erb index 9870db88ec1e..9083e47d2688 100644 --- a/third_party/terraform/resources/resource_composer_environment.go.erb +++ b/third_party/terraform/resources/resource_composer_environment.go.erb @@ -575,7 +575,7 @@ func resourceComposerEnvironmentImport(d *schema.ResourceData, meta interface{}) } // Replace import id for the resource id - id, err := replaceVars(d, config, "{{project}}/{{region}}/{{name}}") + id, err := replaceVars(d, config, "projects/{{project}}/locations/{{region}}/environments/{{name}}") if err != nil { return nil, fmt.Errorf("Error constructing id: %s", err) } diff --git a/third_party/terraform/resources/resource_compute_attached_disk.go b/third_party/terraform/resources/resource_compute_attached_disk.go index bbc45e6e213a..aa80d24f15e1 100644 --- a/third_party/terraform/resources/resource_compute_attached_disk.go +++ b/third_party/terraform/resources/resource_compute_attached_disk.go @@ -100,7 +100,7 @@ func resourceAttachedDiskCreate(d *schema.ResourceData, meta interface{}) error return err } - d.SetId(fmt.Sprintf("%s:%s", zv.Name, diskName)) + d.SetId(fmt.Sprintf("projects/%s/zones/%s/instances/%s/%s", zv.Project, zv.Zone, zv.Name, diskName)) waitErr := computeSharedOperationWaitTime(config.clientCompute, op, zv.Project, int(d.Timeout(schema.TimeoutCreate).Minutes()), "disk to attach") @@ -196,22 +196,17 @@ func resourceAttachedDiskImport(d *schema.ResourceData, meta interface{}) ([]*sc config := meta.(*Config) err := parseImportId( - []string{"projects/(?P[^/]+)/zones/(?P[^/]+)/instances/[^/]+", - "(?P[^/]+)/(?P[^/]+)/[^/]+"}, d, config) + []string{"projects/(?P[^/]+)/zones/(?P[^/]+)/instances/(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)/(?P[^/]+)"}, d, config) if err != nil { return nil, err } - // In all acceptable id formats the actual id will be the last in the path - id := GetResourceNameFromSelfLink(d.Id()) - d.SetId(id) - - IDParts := strings.Split(d.Id(), ":") - if len(IDParts) != 2 { - return nil, fmt.Errorf("unable to determine attached disk id - id should be '{google_compute_instance.name}:{google_compute_disk.name}'") + id, err := replaceVars(d, config, "projects/{{project}}/zones/{{zone}}/instances/{{instance}}/{{disk}}") + if err != nil { + return nil, err } - d.Set("instance", IDParts[0]) - d.Set("disk", IDParts[1]) + d.SetId(id) return []*schema.ResourceData{d}, nil } diff --git a/third_party/terraform/tests/resource_compute_attached_disk_test.go b/third_party/terraform/tests/resource_compute_attached_disk_test.go index e412157a14d2..717d22190a07 100644 --- a/third_party/terraform/tests/resource_compute_attached_disk_test.go +++ b/third_party/terraform/tests/resource_compute_attached_disk_test.go @@ -14,7 +14,7 @@ func TestAccComputeAttachedDisk_basic(t *testing.T) { diskName := acctest.RandomWithPrefix("tf-test-disk") instanceName := acctest.RandomWithPrefix("tf-test-inst") - importID := fmt.Sprintf("%s/us-central1-a/%s:%s", getTestProjectFromEnv(), instanceName, diskName) + importID := fmt.Sprintf("%s/us-central1-a/%s/%s", getTestProjectFromEnv(), instanceName, diskName) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -46,7 +46,7 @@ func TestAccComputeAttachedDisk_full(t *testing.T) { diskName := acctest.RandomWithPrefix("tf-test") instanceName := acctest.RandomWithPrefix("tf-test") - importID := fmt.Sprintf("%s/us-central1-a/%s:%s", getTestProjectFromEnv(), instanceName, diskName) + importID := fmt.Sprintf("%s/us-central1-a/%s/%s", getTestProjectFromEnv(), instanceName, diskName) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -73,7 +73,7 @@ func TestAccComputeAttachedDisk_region(t *testing.T) { diskName := acctest.RandomWithPrefix("tf-test") instanceName := acctest.RandomWithPrefix("tf-test") - importID := fmt.Sprintf("%s/us-central1-a/%s:%s", getTestProjectFromEnv(), instanceName, diskName) + importID := fmt.Sprintf("%s/us-central1-a/%s/%s", getTestProjectFromEnv(), instanceName, diskName) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, diff --git a/third_party/terraform/website/docs/r/compute_attached_disk.html.markdown b/third_party/terraform/website/docs/r/compute_attached_disk.html.markdown index e8ea40375c4a..2da5f78c938b 100644 --- a/third_party/terraform/website/docs/r/compute_attached_disk.html.markdown +++ b/third_party/terraform/website/docs/r/compute_attached_disk.html.markdown @@ -117,6 +117,6 @@ This resource provides the following Attached Disk can be imported the following ways: ``` -$ terraform import google_compute_disk.default projects/{{project}}/zones/{{zone}}/disks/{{instance.name}}:{{disk.name}} -$ terraform import google_compute_disk.default {{project}}/{{zone}}/{{instance.name}}:{{disk.name}} +$ terraform import google_compute_disk.default projects/{{project}}/zones/{{zone}}/instances/{{instance.name}}/{{disk.name}} +$ terraform import google_compute_disk.default {{project}}/{{zone}}/{{instance.name}}/{{disk.name}} ``` From ed51673f18ca0b0c0a8365c537eff5099f92d384 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Mon, 21 Oct 2019 16:21:03 -0700 Subject: [PATCH 2/8] Add compute instance --- .../resources/resource_compute_instance.go | 45 ++++++++++--------- .../tests/resource_compute_instance_test.go | 14 +++--- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/third_party/terraform/resources/resource_compute_instance.go b/third_party/terraform/resources/resource_compute_instance.go index 33cd266bf582..83f14cda5b9d 100644 --- a/third_party/terraform/resources/resource_compute_instance.go +++ b/third_party/terraform/resources/resource_compute_instance.go @@ -548,7 +548,7 @@ func getInstance(config *Config, d *schema.ResourceData) (*computeBeta.Instance, if err != nil { return nil, err } - instance, err := config.clientComputeBeta.Instances.Get(project, zone, d.Id()).Do() + instance, err := config.clientComputeBeta.Instances.Get(project, zone, d.Get("name").(string)).Do() if err != nil { return nil, handleNotFoundError(err, d, fmt.Sprintf("Instance %s", d.Get("name").(string))) } @@ -690,7 +690,7 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err } // Store the ID now - d.SetId(instance.Name) + d.SetId(fmt.Sprintf("projects/%s/zones/%s/instances/%s", project, z, instance.Name)) // Wait for the operation to complete waitErr := computeSharedOperationWaitTime(config.clientCompute, op, project, createTimeout, "instance to create") @@ -866,6 +866,8 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error } } + zone := GetResourceNameFromSelfLink(instance.Zone) + d.Set("service_account", flattenServiceAccounts(instance.ServiceAccounts)) d.Set("attached_disk", ads) d.Set("scratch_disk", scratchDisks) @@ -878,11 +880,11 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error d.Set("self_link", ConvertSelfLinkToV1(instance.SelfLink)) d.Set("instance_id", fmt.Sprintf("%d", instance.Id)) d.Set("project", project) - d.Set("zone", GetResourceNameFromSelfLink(instance.Zone)) + d.Set("zone", zone) d.Set("name", instance.Name) d.Set("description", instance.Description) d.Set("hostname", instance.Hostname) - d.SetId(instance.Name) + d.SetId(fmt.Sprintf("projects/%s/zones/%s/instances/%s", project, zone, instance.Name)) return nil } @@ -902,7 +904,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err // Use beta api directly in order to read network_interface.fingerprint without having to put it in the schema. // Change back to getInstance(config, d) once updating alias ips is GA. - instance, err := config.clientComputeBeta.Instances.Get(project, zone, d.Id()).Do() + instance, err := config.clientComputeBeta.Instances.Get(project, zone, d.Get("name").(string)).Do() if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Instance %s", d.Get("name").(string))) } @@ -926,14 +928,14 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err func() error { // retrieve up-to-date metadata from the API in case several updates hit simultaneously. instances // sometimes but not always share metadata fingerprints. - instance, err := config.clientComputeBeta.Instances.Get(project, zone, d.Id()).Do() + instance, err := config.clientComputeBeta.Instances.Get(project, zone, d.Get("name").(string)).Do() if err != nil { return fmt.Errorf("Error retrieving metadata: %s", err) } metadataV1.Fingerprint = instance.Metadata.Fingerprint - op, err := config.clientCompute.Instances.SetMetadata(project, zone, d.Id(), metadataV1).Do() + op, err := config.clientCompute.Instances.SetMetadata(project, zone, d.Get("name").(string), metadataV1).Do() if err != nil { return fmt.Errorf("Error updating metadata: %s", err) } @@ -961,7 +963,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err return err } op, err := config.clientCompute.Instances.SetTags( - project, zone, d.Id(), tagsV1).Do() + project, zone, d.Get("name").(string), tagsV1).Do() if err != nil { return fmt.Errorf("Error updating tags: %s", err) } @@ -979,7 +981,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err labelFingerprint := d.Get("label_fingerprint").(string) req := compute.InstancesSetLabelsRequest{Labels: labels, LabelFingerprint: labelFingerprint} - op, err := config.clientCompute.Instances.SetLabels(project, zone, d.Id(), &req).Do() + op, err := config.clientCompute.Instances.SetLabels(project, zone, d.Get("name").(string), &req).Do() if err != nil { return fmt.Errorf("Error updating labels: %s", err) } @@ -999,7 +1001,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err } op, err := config.clientComputeBeta.Instances.SetScheduling( - project, zone, d.Id(), scheduling).Do() + project, zone, d.Get("name").(string), scheduling).Do() if err != nil { return fmt.Errorf("Error updating scheduling policy: %s", err) } @@ -1040,7 +1042,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err // Delete any accessConfig that currently exists in instNetworkInterface for _, ac := range instNetworkInterface.AccessConfigs { op, err := config.clientCompute.Instances.DeleteAccessConfig( - project, zone, d.Id(), ac.Name, networkName).Do() + project, zone, d.Get("name").(string), ac.Name, networkName).Do() if err != nil { return fmt.Errorf("Error deleting old access_config: %s", err) } @@ -1065,7 +1067,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err } op, err := config.clientComputeBeta.Instances.AddAccessConfig( - project, zone, d.Id(), networkName, ac).Do() + project, zone, d.Get("name").(string), networkName, ac).Do() if err != nil { return fmt.Errorf("Error adding new access_config: %s", err) } @@ -1085,7 +1087,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err Fingerprint: instNetworkInterface.Fingerprint, ForceSendFields: []string{"AliasIpRanges"}, } - op, err := config.clientComputeBeta.Instances.UpdateNetworkInterface(project, zone, d.Id(), networkName, ni).Do() + op, err := config.clientComputeBeta.Instances.UpdateNetworkInterface(project, zone, d.Get("name").(string), networkName, ni).Do() if err != nil { return errwrap.Wrapf("Error removing alias_ip_range: {{err}}", err) } @@ -1099,7 +1101,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err ranges := d.Get(prefix + ".alias_ip_range").([]interface{}) if len(ranges) > 0 { if rereadFingerprint { - instance, err = config.clientComputeBeta.Instances.Get(project, zone, d.Id()).Do() + instance, err = config.clientComputeBeta.Instances.Get(project, zone, d.Get("name").(string)).Do() if err != nil { return err } @@ -1109,7 +1111,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err AliasIpRanges: expandAliasIpRanges(ranges), Fingerprint: instNetworkInterface.Fingerprint, } - op, err := config.clientComputeBeta.Instances.UpdateNetworkInterface(project, zone, d.Id(), networkName, ni).Do() + op, err := config.clientComputeBeta.Instances.UpdateNetworkInterface(project, zone, d.Get("name").(string), networkName, ni).Do() if err != nil { return errwrap.Wrapf("Error adding alias_ip_range: {{err}}", err) } @@ -1235,7 +1237,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err if d.HasChange("deletion_protection") { nDeletionProtection := d.Get("deletion_protection").(bool) - op, err := config.clientCompute.Instances.SetDeletionProtection(project, zone, d.Id()).DeletionProtection(nDeletionProtection).Do() + op, err := config.clientCompute.Instances.SetDeletionProtection(project, zone, d.Get("name").(string)).DeletionProtection(nDeletionProtection).Do() if err != nil { return fmt.Errorf("Error updating deletion protection flag: %s", err) } @@ -1338,7 +1340,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err if d.HasChange("shielded_instance_config") { shieldedVmConfig := expandShieldedVmConfigs(d) - op, err := config.clientComputeBeta.Instances.UpdateShieldedVmConfig(project, zone, d.Id(), shieldedVmConfig).Do() + op, err := config.clientComputeBeta.Instances.UpdateShieldedVmConfig(project, zone, d.Get("name").(string), shieldedVmConfig).Do() if err != nil { return fmt.Errorf("Error updating shielded vm config: %s", err) } @@ -1492,12 +1494,12 @@ func resourceComputeInstanceDelete(d *schema.ResourceData, meta interface{}) err if err != nil { return err } - log.Printf("[INFO] Requesting instance deletion: %s", d.Id()) + log.Printf("[INFO] Requesting instance deletion: %s", d.Get("name").(string)) if d.Get("deletion_protection").(bool) { - return fmt.Errorf("Cannot delete instance %s: instance Deletion Protection is enabled. Set deletion_protection to false for this resource and run \"terraform apply\" before attempting to delete it.", d.Id()) + return fmt.Errorf("Cannot delete instance %s: instance Deletion Protection is enabled. Set deletion_protection to false for this resource and run \"terraform apply\" before attempting to delete it.", d.Get("name").(string)) } else { - op, err := config.clientCompute.Instances.Delete(project, zone, d.Id()).Do() + op, err := config.clientCompute.Instances.Delete(project, zone, d.Get("name").(string)).Do() if err != nil { return fmt.Errorf("Error deleting instance: %s", err) } @@ -1522,7 +1524,8 @@ func resourceComputeInstanceImportState(d *schema.ResourceData, meta interface{} d.Set("project", parts[0]) d.Set("zone", parts[1]) - d.SetId(parts[2]) + d.Set("name", parts[2]) + d.SetId(fmt.Sprintf("projects/%s/zones/%s/instances/%s", parts[0], parts[1], parts[2])) return []*schema.ResourceData{d}, nil } diff --git a/third_party/terraform/tests/resource_compute_instance_test.go b/third_party/terraform/tests/resource_compute_instance_test.go index f62aa436c9a4..5c4f4a2dc6d5 100644 --- a/third_party/terraform/tests/resource_compute_instance_test.go +++ b/third_party/terraform/tests/resource_compute_instance_test.go @@ -1214,7 +1214,7 @@ func testAccCheckComputeInstanceUpdateMachineType(n string) resource.TestCheckFu config := testAccProvider.Meta().(*Config) - op, err := config.clientCompute.Instances.Stop(config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() + op, err := config.clientCompute.Instances.Stop(config.Project, rs.Primary.Attributes["zone"], rs.Primary.Attributes["name"]).Do() if err != nil { return fmt.Errorf("Could not stop instance: %s", err) } @@ -1228,7 +1228,7 @@ func testAccCheckComputeInstanceUpdateMachineType(n string) resource.TestCheckFu } op, err = config.clientCompute.Instances.SetMachineType( - config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID, &machineType).Do() + config.Project, rs.Primary.Attributes["zone"], rs.Primary.Attributes["name"], &machineType).Do() if err != nil { return fmt.Errorf("Could not change machine type: %s", err) } @@ -1249,7 +1249,7 @@ func testAccCheckComputeInstanceDestroy(s *terraform.State) error { } _, err := config.clientCompute.Instances.Get( - config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() + config.Project, rs.Primary.Attributes["zone"], rs.Primary.Attributes["name"]).Do() if err == nil { return fmt.Errorf("Instance still exists") } @@ -1287,12 +1287,12 @@ func testAccCheckComputeInstanceExistsInProject(n, p string, instance *compute.I config := testAccProvider.Meta().(*Config) found, err := config.clientCompute.Instances.Get( - p, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() + p, rs.Primary.Attributes["zone"], rs.Primary.Attributes["name"]).Do() if err != nil { return err } - if found.Name != rs.Primary.ID { + if found.Name != rs.Primary.Attributes["name"] { return fmt.Errorf("Instance not found") } @@ -1316,12 +1316,12 @@ func testAccCheckComputeBetaInstanceExistsInProject(n, p string, instance *compu config := testAccProvider.Meta().(*Config) found, err := config.clientComputeBeta.Instances.Get( - p, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() + p, rs.Primary.Attributes["zone"], rs.Primary.Attributes["name"]).Do() if err != nil { return err } - if found.Name != rs.Primary.ID { + if found.Name != rs.Primary.Attributes["name"] { return fmt.Errorf("Instance not found") } From 73fbeb314d46552cb6f6b1ca09fcbd1d6a08ebba Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Mon, 21 Oct 2019 16:54:53 -0700 Subject: [PATCH 3/8] Add instance_from_group and instance_group --- ...resource_compute_instance_from_template.go | 2 +- .../resource_compute_instance_group.go | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/third_party/terraform/resources/resource_compute_instance_from_template.go b/third_party/terraform/resources/resource_compute_instance_from_template.go index b7a4019ec589..7926144ffe88 100644 --- a/third_party/terraform/resources/resource_compute_instance_from_template.go +++ b/third_party/terraform/resources/resource_compute_instance_from_template.go @@ -154,7 +154,7 @@ func resourceComputeInstanceFromTemplateCreate(d *schema.ResourceData, meta inte } // Store the ID now - d.SetId(instance.Name) + d.SetId(fmt.Sprintf("projects/%s/zones/%s/instances/%s", project, z, instance.Name)) // Wait for the operation to complete waitErr := computeSharedOperationWaitTime(config.clientCompute, op, project, int(d.Timeout(schema.TimeoutCreate).Minutes()), "instance to create") diff --git a/third_party/terraform/resources/resource_compute_instance_group.go b/third_party/terraform/resources/resource_compute_instance_group.go index d4f9ad3542a9..0b814d8fb8f6 100644 --- a/third_party/terraform/resources/resource_compute_instance_group.go +++ b/third_party/terraform/resources/resource_compute_instance_group.go @@ -155,7 +155,7 @@ func resourceComputeInstanceGroupCreate(d *schema.ResourceData, meta interface{} } // It probably maybe worked, so store the ID now - d.SetId(fmt.Sprintf("%s/%s", zone, name)) + d.SetId(fmt.Sprintf("projects/%s/zones/%s/instanceGroups/%s", project, zone, name)) // Wait for the operation to complete err = computeOperationWait(config.clientCompute, op, project, "Creating InstanceGroup") @@ -378,18 +378,19 @@ func resourceComputeInstanceGroupDelete(d *schema.ResourceData, meta interface{} } func resourceComputeInstanceGroupImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - parts := strings.Split(d.Id(), "/") - if len(parts) == 2 { - d.Set("zone", parts[0]) - d.Set("name", parts[1]) - } else if len(parts) == 3 { - d.Set("project", parts[0]) - d.Set("zone", parts[1]) - d.Set("name", parts[2]) - d.SetId(parts[1] + "/" + parts[2]) - } else { - return nil, fmt.Errorf("Invalid compute instance group specifier. Expecting {zone}/{name} or {project}/{zone}/{name}") + config := meta.(*Config) + if err := parseImportId([]string{ + "projects/(?P[^/]+)/zones/(?P[^/]+)/instanceGroups/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + id, err := replaceVars(d, config, "projects/{{project}}/zones/{{zone}}/instanceGroups/{{name}}") + if err != nil { + return nil, err } + d.SetId(id) return []*schema.ResourceData{d}, nil } From 5122763402f748e1fb4382a8259cc333a46d069f Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Tue, 22 Oct 2019 11:24:03 -0700 Subject: [PATCH 4/8] IGM id --- .../resource_compute_instance_group_manager.go.erb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb b/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb index 1bacafbda09d..f81ecc0ec5ec 100644 --- a/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb +++ b/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb @@ -392,7 +392,7 @@ func resourceComputeInstanceGroupManagerCreate(d *schema.ResourceData, meta inte } // It probably maybe worked, so store the ID now - id, err := replaceVars(d, config, "{{project}}/{{zone}}/{{name}}") + id, err := replaceVars(d, config, "projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{name}}") if err != nil { return err } @@ -1020,12 +1020,12 @@ func flattenUpdatePolicy(updatePolicy *computeBeta.InstanceGroupManagerUpdatePol func resourceInstanceGroupManagerStateImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { d.Set("wait_for_instances", false) config := meta.(*Config) - if err := parseImportId([]string{"(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { + if err := parseImportId([]string{"projects/(?P[^/]+)/zones/(?P[^/]+)/instanceGroupManagers/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { return nil, err } // Replace import id for the resource id - id, err := replaceVars(d, config, "{{project}}/{{zone}}/{{name}}") + id, err := replaceVars(d, config, ""projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{name}}"") if err != nil { return nil, fmt.Errorf("Error constructing id: %s", err) } From 47d5b65d35fe07847dd09c1e3d1f760ab3ad2eb2 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Tue, 22 Oct 2019 14:50:31 -0700 Subject: [PATCH 5/8] Instance template tests passing --- ...urce_compute_instance_group_manager.go.erb | 2 +- .../resource_compute_instance_template.go | 27 ++++++++++++++++--- ...resource_compute_instance_template_test.go | 13 +++++---- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb b/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb index f81ecc0ec5ec..a5cdfe486b61 100644 --- a/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb +++ b/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb @@ -1025,7 +1025,7 @@ func resourceInstanceGroupManagerStateImporter(d *schema.ResourceData, meta inte } // Replace import id for the resource id - id, err := replaceVars(d, config, ""projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{name}}"") + id, err := replaceVars(d, config, "projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{name}}") if err != nil { return nil, fmt.Errorf("Error constructing id: %s", err) } diff --git a/third_party/terraform/resources/resource_compute_instance_template.go b/third_party/terraform/resources/resource_compute_instance_template.go index 0365ac879b22..a81ca555df10 100644 --- a/third_party/terraform/resources/resource_compute_instance_template.go +++ b/third_party/terraform/resources/resource_compute_instance_template.go @@ -3,6 +3,7 @@ package google import ( "fmt" "reflect" + "strings" "github.com/hashicorp/errwrap" "github.com/hashicorp/terraform-plugin-sdk/helper/customdiff" @@ -19,7 +20,7 @@ func resourceComputeInstanceTemplate() *schema.Resource { Read: resourceComputeInstanceTemplateRead, Delete: resourceComputeInstanceTemplateDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: resourceComputeInstanceTemplateImportState, }, SchemaVersion: 1, CustomizeDiff: customdiff.All( @@ -737,7 +738,7 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac } // Store the ID now - d.SetId(instanceTemplate.Name) + d.SetId(fmt.Sprintf("projects/%s/global/instanceTemplates/%s", project, instanceTemplate.Name)) err = computeSharedOperationWait(config.clientCompute, op, project, "Creating Instance Template") if err != nil { @@ -963,7 +964,8 @@ func resourceComputeInstanceTemplateRead(d *schema.ResourceData, meta interface{ return err } - instanceTemplate, err := config.clientComputeBeta.InstanceTemplates.Get(project, d.Id()).Do() + splits := strings.Split(d.Id(), "/") + instanceTemplate, err := config.clientComputeBeta.InstanceTemplates.Get(project, splits[len(splits)-1]).Do() if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Instance Template %q", d.Get("name").(string))) } @@ -1091,8 +1093,9 @@ func resourceComputeInstanceTemplateDelete(d *schema.ResourceData, meta interfac return err } + splits := strings.Split(d.Id(), "/") op, err := config.clientCompute.InstanceTemplates.Delete( - project, d.Id()).Do() + project, splits[len(splits)-1]).Do() if err != nil { return fmt.Errorf("Error deleting instance template: %s", err) } @@ -1129,3 +1132,19 @@ func expandResourceComputeInstanceTemplateScheduling(d *schema.ResourceData, met } return expanded, nil } + +func resourceComputeInstanceTemplateImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{"projects/(?P[^/]+)/global/instanceTemplates/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "projects/{{project}}/global/instanceTemplates/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} diff --git a/third_party/terraform/tests/resource_compute_instance_template_test.go b/third_party/terraform/tests/resource_compute_instance_template_test.go index 127c73c3c88f..ca56d1b37e0a 100644 --- a/third_party/terraform/tests/resource_compute_instance_template_test.go +++ b/third_party/terraform/tests/resource_compute_instance_template_test.go @@ -807,8 +807,9 @@ func testAccCheckComputeInstanceTemplateDestroy(s *terraform.State) error { continue } + splits := strings.Split(rs.Primary.ID, "/") _, err := config.clientCompute.InstanceTemplates.Get( - config.Project, rs.Primary.ID).Do() + config.Project, splits[len(splits)-1]).Do() if err == nil { return fmt.Errorf("Instance template still exists") } @@ -845,13 +846,14 @@ func testAccCheckComputeInstanceTemplateExistsInProject(n, p string, instanceTem config := testAccProvider.Meta().(*Config) + splits := strings.Split(rs.Primary.ID, "/") found, err := config.clientCompute.InstanceTemplates.Get( - p, rs.Primary.ID).Do() + p, splits[len(splits)-1]).Do() if err != nil { return err } - if found.Name != rs.Primary.ID { + if found.Name != splits[len(splits)-1] { return fmt.Errorf("Instance template not found") } @@ -874,13 +876,14 @@ func testAccCheckComputeBetaInstanceTemplateExistsInProject(n, p string, instanc config := testAccProvider.Meta().(*Config) + splits := strings.Split(rs.Primary.ID, "/") found, err := config.clientComputeBeta.InstanceTemplates.Get( - p, rs.Primary.ID).Do() + p, splits[len(splits)-1]).Do() if err != nil { return err } - if found.Name != rs.Primary.ID { + if found.Name != splits[len(splits)-1] { return fmt.Errorf("Instance template not found") } From e7a26d8aa9161983173fee12f754029c5f3855c7 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Tue, 22 Oct 2019 15:26:03 -0700 Subject: [PATCH 6/8] Add new id format to other calls of parseImportId in IGM --- .../resource_compute_instance_group_manager.go.erb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb b/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb index a5cdfe486b61..fd49c5462294 100644 --- a/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb +++ b/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb @@ -451,7 +451,7 @@ func flattenFixedOrPercent(fixedOrPercent *computeBeta.FixedOrPercent) []map[str func getManager(d *schema.ResourceData, meta interface{}) (*computeBeta.InstanceGroupManager, error) { config := meta.(*Config) - if err := parseImportId([]string{"(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { + if err := parseImportId([]string{"projects/(?P[^/]+)/zones/(?P[^/]+)/instanceGroupManagers/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { return nil, err } @@ -595,7 +595,7 @@ func performZoneUpdate(d *schema.ResourceData, config *Config, id string, update func resourceComputeInstanceGroupManagerUpdate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - if err := parseImportId([]string{"(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { + if err := parseImportId([]string{"projects/(?P[^/]+)/zones/(?P[^/]+)/instanceGroupManagers/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { return err } @@ -818,7 +818,7 @@ func resourceComputeInstanceGroupManagerUpdate(d *schema.ResourceData, meta inte func resourceComputeInstanceGroupManagerDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - if err := parseImportId([]string{"(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { + if err := parseImportId([]string{"projects/(?P[^/]+)/zones/(?P[^/]+)/instanceGroupManagers/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { return err } project, err := getProject(d, config) From 271f49a70c8ee8b8579236c07ed68c1fa1e8e90e Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Wed, 23 Oct 2019 09:29:51 -0700 Subject: [PATCH 7/8] Small refactor to memoize var --- .../tests/resource_compute_instance_template_test.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/third_party/terraform/tests/resource_compute_instance_template_test.go b/third_party/terraform/tests/resource_compute_instance_template_test.go index ca56d1b37e0a..fc1722853789 100644 --- a/third_party/terraform/tests/resource_compute_instance_template_test.go +++ b/third_party/terraform/tests/resource_compute_instance_template_test.go @@ -847,13 +847,14 @@ func testAccCheckComputeInstanceTemplateExistsInProject(n, p string, instanceTem config := testAccProvider.Meta().(*Config) splits := strings.Split(rs.Primary.ID, "/") + templateName := splits[len(splits)-1] found, err := config.clientCompute.InstanceTemplates.Get( - p, splits[len(splits)-1]).Do() + p, templateName).Do() if err != nil { return err } - if found.Name != splits[len(splits)-1] { + if found.Name != templateName { return fmt.Errorf("Instance template not found") } @@ -877,13 +878,14 @@ func testAccCheckComputeBetaInstanceTemplateExistsInProject(n, p string, instanc config := testAccProvider.Meta().(*Config) splits := strings.Split(rs.Primary.ID, "/") + templateName := splits[len(splits)-1] found, err := config.clientComputeBeta.InstanceTemplates.Get( - p, splits[len(splits)-1]).Do() + p, templateName).Do() if err != nil { return err } - if found.Name != splits[len(splits)-1] { + if found.Name != templateName { return fmt.Errorf("Instance template not found") } From fdbf4881bb5d7e104f54edc9a9275e8280c55ffa Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Wed, 23 Oct 2019 10:19:13 -0700 Subject: [PATCH 8/8] Refactor, remove parseImportId in IGM --- .../resources/resource_compute_instance.go | 22 +++++++++---------- ...urce_compute_instance_group_manager.go.erb | 10 --------- .../r/compute_instance_group.html.markdown | 1 + ...mpute_instance_group_manager.html.markdown | 1 + .../r/compute_instance_template.html.markdown | 6 +++-- 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/third_party/terraform/resources/resource_compute_instance.go b/third_party/terraform/resources/resource_compute_instance.go index 83f14cda5b9d..6e90ca789ae4 100644 --- a/third_party/terraform/resources/resource_compute_instance.go +++ b/third_party/terraform/resources/resource_compute_instance.go @@ -906,7 +906,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err // Change back to getInstance(config, d) once updating alias ips is GA. instance, err := config.clientComputeBeta.Instances.Get(project, zone, d.Get("name").(string)).Do() if err != nil { - return handleNotFoundError(err, d, fmt.Sprintf("Instance %s", d.Get("name").(string))) + return handleNotFoundError(err, d, fmt.Sprintf("Instance %s", instance.Name)) } // Enable partial mode for the resource since it is possible @@ -928,14 +928,14 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err func() error { // retrieve up-to-date metadata from the API in case several updates hit simultaneously. instances // sometimes but not always share metadata fingerprints. - instance, err := config.clientComputeBeta.Instances.Get(project, zone, d.Get("name").(string)).Do() + instance, err := config.clientComputeBeta.Instances.Get(project, zone, instance.Name).Do() if err != nil { return fmt.Errorf("Error retrieving metadata: %s", err) } metadataV1.Fingerprint = instance.Metadata.Fingerprint - op, err := config.clientCompute.Instances.SetMetadata(project, zone, d.Get("name").(string), metadataV1).Do() + op, err := config.clientCompute.Instances.SetMetadata(project, zone, instance.Name, metadataV1).Do() if err != nil { return fmt.Errorf("Error updating metadata: %s", err) } @@ -981,7 +981,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err labelFingerprint := d.Get("label_fingerprint").(string) req := compute.InstancesSetLabelsRequest{Labels: labels, LabelFingerprint: labelFingerprint} - op, err := config.clientCompute.Instances.SetLabels(project, zone, d.Get("name").(string), &req).Do() + op, err := config.clientCompute.Instances.SetLabels(project, zone, instance.Name, &req).Do() if err != nil { return fmt.Errorf("Error updating labels: %s", err) } @@ -1001,7 +1001,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err } op, err := config.clientComputeBeta.Instances.SetScheduling( - project, zone, d.Get("name").(string), scheduling).Do() + project, zone, instance.Name, scheduling).Do() if err != nil { return fmt.Errorf("Error updating scheduling policy: %s", err) } @@ -1042,7 +1042,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err // Delete any accessConfig that currently exists in instNetworkInterface for _, ac := range instNetworkInterface.AccessConfigs { op, err := config.clientCompute.Instances.DeleteAccessConfig( - project, zone, d.Get("name").(string), ac.Name, networkName).Do() + project, zone, instance.Name, ac.Name, networkName).Do() if err != nil { return fmt.Errorf("Error deleting old access_config: %s", err) } @@ -1067,7 +1067,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err } op, err := config.clientComputeBeta.Instances.AddAccessConfig( - project, zone, d.Get("name").(string), networkName, ac).Do() + project, zone, instance.Name, networkName, ac).Do() if err != nil { return fmt.Errorf("Error adding new access_config: %s", err) } @@ -1087,7 +1087,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err Fingerprint: instNetworkInterface.Fingerprint, ForceSendFields: []string{"AliasIpRanges"}, } - op, err := config.clientComputeBeta.Instances.UpdateNetworkInterface(project, zone, d.Get("name").(string), networkName, ni).Do() + op, err := config.clientComputeBeta.Instances.UpdateNetworkInterface(project, zone, instance.Name, networkName, ni).Do() if err != nil { return errwrap.Wrapf("Error removing alias_ip_range: {{err}}", err) } @@ -1101,7 +1101,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err ranges := d.Get(prefix + ".alias_ip_range").([]interface{}) if len(ranges) > 0 { if rereadFingerprint { - instance, err = config.clientComputeBeta.Instances.Get(project, zone, d.Get("name").(string)).Do() + instance, err = config.clientComputeBeta.Instances.Get(project, zone, instance.Name).Do() if err != nil { return err } @@ -1111,7 +1111,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err AliasIpRanges: expandAliasIpRanges(ranges), Fingerprint: instNetworkInterface.Fingerprint, } - op, err := config.clientComputeBeta.Instances.UpdateNetworkInterface(project, zone, d.Get("name").(string), networkName, ni).Do() + op, err := config.clientComputeBeta.Instances.UpdateNetworkInterface(project, zone, instance.Name, networkName, ni).Do() if err != nil { return errwrap.Wrapf("Error adding alias_ip_range: {{err}}", err) } @@ -1340,7 +1340,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err if d.HasChange("shielded_instance_config") { shieldedVmConfig := expandShieldedVmConfigs(d) - op, err := config.clientComputeBeta.Instances.UpdateShieldedVmConfig(project, zone, d.Get("name").(string), shieldedVmConfig).Do() + op, err := config.clientComputeBeta.Instances.UpdateShieldedVmConfig(project, zone, instance.Name, shieldedVmConfig).Do() if err != nil { return fmt.Errorf("Error updating shielded vm config: %s", err) } diff --git a/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb b/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb index fd49c5462294..75743b5af66a 100644 --- a/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb +++ b/third_party/terraform/resources/resource_compute_instance_group_manager.go.erb @@ -451,9 +451,6 @@ func flattenFixedOrPercent(fixedOrPercent *computeBeta.FixedOrPercent) []map[str func getManager(d *schema.ResourceData, meta interface{}) (*computeBeta.InstanceGroupManager, error) { config := meta.(*Config) - if err := parseImportId([]string{"projects/(?P[^/]+)/zones/(?P[^/]+)/instanceGroupManagers/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { - return nil, err - } project, err := getProject(d, config) if err != nil { @@ -595,10 +592,6 @@ func performZoneUpdate(d *schema.ResourceData, config *Config, id string, update func resourceComputeInstanceGroupManagerUpdate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - if err := parseImportId([]string{"projects/(?P[^/]+)/zones/(?P[^/]+)/instanceGroupManagers/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { - return err - } - project, err := getProject(d, config) if err != nil { return err @@ -818,9 +811,6 @@ func resourceComputeInstanceGroupManagerUpdate(d *schema.ResourceData, meta inte func resourceComputeInstanceGroupManagerDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - if err := parseImportId([]string{"projects/(?P[^/]+)/zones/(?P[^/]+)/instanceGroupManagers/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { - return err - } project, err := getProject(d, config) if err != nil { return err diff --git a/third_party/terraform/website/docs/r/compute_instance_group.html.markdown b/third_party/terraform/website/docs/r/compute_instance_group.html.markdown index 96627ba56df6..401ac57a255c 100644 --- a/third_party/terraform/website/docs/r/compute_instance_group.html.markdown +++ b/third_party/terraform/website/docs/r/compute_instance_group.html.markdown @@ -180,4 +180,5 @@ Instance group can be imported using the `zone` and `name` with an optional `pro ``` $ terraform import google_compute_instance_group.webservers us-central1-a/terraform-webservers $ terraform import google_compute_instance_group.webservers big-project/us-central1-a/terraform-webservers +$ terraform import google_compute_instance_group.webservers projects/big-project/zones/us-central1-a/instanceGroups/terraform-webservers ``` diff --git a/third_party/terraform/website/docs/r/compute_instance_group_manager.html.markdown b/third_party/terraform/website/docs/r/compute_instance_group_manager.html.markdown index 21b2771b528c..dee65b6d8d1d 100644 --- a/third_party/terraform/website/docs/r/compute_instance_group_manager.html.markdown +++ b/third_party/terraform/website/docs/r/compute_instance_group_manager.html.markdown @@ -252,6 +252,7 @@ This resource provides the following Instance group managers can be imported using any of these accepted formats: ``` +$ terraform import google_compute_instance_group_manager.appserver projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{name}} $ terraform import google_compute_instance_group_manager.appserver {{project}}/{{zone}}/{{name}} $ terraform import google_compute_instance_group_manager.appserver {{project}}/{{name}} $ terraform import google_compute_instance_group_manager.appserver {{name}} diff --git a/third_party/terraform/website/docs/r/compute_instance_template.html.markdown b/third_party/terraform/website/docs/r/compute_instance_template.html.markdown index d04cfa16ee05..5e036491ddd5 100644 --- a/third_party/terraform/website/docs/r/compute_instance_template.html.markdown +++ b/third_party/terraform/website/docs/r/compute_instance_template.html.markdown @@ -418,10 +418,12 @@ exported: ## Import -Instance templates can be imported using the `name`, e.g. +Instance templates can be imported using any of these accepted formats: ``` -$ terraform import google_compute_instance_template.default appserver-template +$ terraform import google_compute_instance_template.default projects/{{project}}/global/instanceTemplates/{{name}} +$ terraform import google_compute_instance_template.default {{project}}/{{name}} +$ terraform import google_compute_instance_template.default {{name}} ``` [custom-vm-types]: https://cloud.google.com/dataproc/docs/concepts/compute/custom-machine-types