Skip to content

Commit

Permalink
Add wait_for_instances field to IGM and self_link option to the IG da…
Browse files Browse the repository at this point in the history
…ta source (#1222)

* Add wait_for_instances field to IGM and self_link option to the IG data source

* don't be clever with errors
  • Loading branch information
danawillow authored Mar 20, 2018
1 parent 92d14b7 commit 28efae5
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 42 deletions.
50 changes: 33 additions & 17 deletions google/data_source_google_compute_instance_group.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package google

import (
"errors"
"fmt"

"github.com/hashicorp/terraform/helper/schema"
Expand All @@ -11,14 +12,23 @@ func dataSourceGoogleComputeInstanceGroup() *schema.Resource {
Read: dataSourceComputeInstanceGroupRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"self_link"},
},

"self_link": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ConflictsWith: []string{"name", "zone"},
},

"zone": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Type: schema.TypeString,
Optional: true,
Computed: true,
ConflictsWith: []string{"self_link"},
},

"project": {
Expand Down Expand Up @@ -62,11 +72,6 @@ func dataSourceGoogleComputeInstanceGroup() *schema.Resource {
Computed: true,
},

"self_link": {
Type: schema.TypeString,
Computed: true,
},

"size": {
Type: schema.TypeInt,
Computed: true,
Expand All @@ -76,14 +81,25 @@ func dataSourceGoogleComputeInstanceGroup() *schema.Resource {
}

func dataSourceComputeInstanceGroupRead(d *schema.ResourceData, meta interface{}) error {

zone, err := getZone(d, meta.(*Config))
if err != nil {
return err
config := meta.(*Config)
if name, ok := d.GetOk("name"); ok {
zone, err := getZone(d, config)
if err != nil {
return err
}
d.SetId(fmt.Sprintf("%s/%s", zone, name.(string)))
} else if selfLink, ok := d.GetOk("self_link"); ok {
parsed, err := ParseInstanceGroupFieldValue(selfLink.(string), d, config)
if err != nil {
return err
}
d.Set("name", parsed.Name)
d.Set("zone", parsed.Zone)
d.Set("project", parsed.Project)
d.SetId(fmt.Sprintf("%s/%s", parsed.Zone, parsed.Name))
} else {
return errors.New("Must provide either `self_link` or `zone/name`")
}
name := d.Get("name").(string)

d.SetId(fmt.Sprintf("%s/%s", zone, name))

return resourceComputeInstanceGroupRead(d, meta)
}
54 changes: 52 additions & 2 deletions google/data_source_google_compute_instance_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,35 @@ func TestAccDataSourceGoogleComputeInstanceGroup_withNamedPort(t *testing.T) {
})
}

func TestAccDataSourceGoogleComputeInstanceGroup_fromIGM(t *testing.T) {
t.Parallel()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCheckDataSourceGoogleComputeInstanceGroup_fromIGM(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.google_compute_instance_group.test", "instances.#", "10"),
),
},
},
})
}

func testAccCheckDataSourceGoogleComputeInstanceGroup(dataSourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
dsFullName := "data.google_compute_instance_group.test"
rsFullName := "google_compute_instance_group.test"
ds, ok := s.RootModule().Resources[dsFullName]
if !ok {
return fmt.Errorf("cant' find resource called %s in state", dsFullName)
return fmt.Errorf("cant' find data source called %s in state", dsFullName)
}

rs, ok := s.RootModule().Resources[rsFullName]
if !ok {
return fmt.Errorf("can't find data source called %s in state", rsFullName)
return fmt.Errorf("can't find resource called %s in state", rsFullName)
}

dsAttrs := ds.Primary.Attributes
Expand Down Expand Up @@ -259,3 +276,36 @@ data "google_compute_instance_group" "test" {
}
`, acctest.RandString(10), acctest.RandString(10))
}

func testAccCheckDataSourceGoogleComputeInstanceGroup_fromIGM() string {
return fmt.Sprintf(`
resource "google_compute_instance_template" "igm-basic" {
name = "%s"
machine_type = "n1-standard-1"
disk {
source_image = "debian-cloud/debian-8-jessie-v20160803"
auto_delete = true
boot = true
}
network_interface {
network = "default"
}
}
resource "google_compute_instance_group_manager" "igm" {
name = "%s"
instance_template = "${google_compute_instance_template.igm-basic.self_link}"
base_instance_name = "igm"
zone = "us-central1-a"
target_size = 10
wait_for_instances = true
}
data "google_compute_instance_group" "test" {
self_link = "${google_compute_instance_group_manager.igm.instance_group}"
}
`, acctest.RandomWithPrefix("test-igm"), acctest.RandomWithPrefix("test-igm"))
}
4 changes: 4 additions & 0 deletions google/field_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ func ParseMachineTypesFieldValue(machineType string, d TerraformResourceData, co
return parseZonalFieldValue("machineTypes", machineType, "project", "zone", d, config, false)
}

func ParseInstanceGroupFieldValue(instanceGroup string, d TerraformResourceData, config *Config) (*ZonalFieldValue, error) {
return parseZonalFieldValue("instanceGroups", instanceGroup, "project", "zone", d, config, false)
}

// ------------------------------------------------------------
// Base helpers used to create helpers for specific fields.
// ------------------------------------------------------------
Expand Down
53 changes: 43 additions & 10 deletions google/resource_compute_instance_group_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"
"time"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"

Expand Down Expand Up @@ -197,6 +198,11 @@ func resourceComputeInstanceGroupManager() *schema.Resource {
},
},
},
"wait_for_instances": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: true,
},
},
}
}
Expand Down Expand Up @@ -312,18 +318,18 @@ func flattenNamedPortsBeta(namedPorts []*computeBeta.NamedPort) []map[string]int

}

func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interface{}) error {
func getManager(d *schema.ResourceData, meta interface{}) (*computeBeta.InstanceGroupManager, error) {
computeApiVersion := getComputeApiVersion(d, InstanceGroupManagerBaseApiVersion, InstanceGroupManagerVersionedFeatures)
config := meta.(*Config)

project, err := getProject(d, config)
if err != nil {
return err
return nil, err
}

region, err := getRegion(d, config)
if err != nil {
return err
return nil, err
}

manager := &computeBeta.InstanceGroupManager{}
Expand All @@ -339,7 +345,7 @@ func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interf
v1Manager, e = config.clientCompute.InstanceGroupManagers.Get(project, zone, d.Id()).Do()

if e != nil {
return handleNotFoundError(e, d, fmt.Sprintf("Instance Group Manager %q", d.Get("name").(string)))
return nil, handleNotFoundError(e, d, fmt.Sprintf("Instance Group Manager %q", d.Get("name").(string)))
}
} else {
// If the resource was imported, the only info we have is the ID. Try to find the resource
Expand All @@ -348,7 +354,7 @@ func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interf
resource, e = getZonalResourceFromRegion(getInstanceGroupManager, region, config.clientCompute, project)

if e != nil {
return e
return nil, e
}

v1Manager = resource.(*compute.InstanceGroupManager)
Expand All @@ -359,12 +365,12 @@ func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interf

// The resource doesn't exist anymore
d.SetId("")
return nil
return nil, nil
}

err = Convert(v1Manager, manager)
if err != nil {
return err
return nil, err
}

case v0beta:
Expand All @@ -378,15 +384,15 @@ func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interf
v0betaManager, e = config.clientComputeBeta.InstanceGroupManagers.Get(project, zone, d.Id()).Do()

if e != nil {
return handleNotFoundError(e, d, fmt.Sprintf("Instance Group Manager %q", d.Get("name").(string)))
return nil, handleNotFoundError(e, d, fmt.Sprintf("Instance Group Manager %q", d.Get("name").(string)))
}
} else {
// If the resource was imported, the only info we have is the ID. Try to find the resource
// by searching in the region of the project.
var resource interface{}
resource, e = getZonalBetaResourceFromRegion(getInstanceGroupManager, region, config.clientComputeBeta, project)
if e != nil {
return e
return nil, e
}

v0betaManager = resource.(*computeBeta.InstanceGroupManager)
Expand All @@ -397,11 +403,25 @@ func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interf

// The resource doesn't exist anymore
d.SetId("")
return nil
return nil, nil
}

manager = v0betaManager
}
return manager, nil
}

func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
project, err := getProject(d, config)
if err != nil {
return err
}

manager, err := getManager(d, meta)
if err != nil {
return err
}

d.Set("base_instance_name", manager.BaseInstanceName)
d.Set("instance_template", manager.InstanceTemplate)
Expand All @@ -422,6 +442,19 @@ func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interf
d.Set("update_strategy", update_strategy.(string))
d.Set("auto_healing_policies", flattenAutoHealingPolicies(manager.AutoHealingPolicies))

if d.Get("wait_for_instances").(bool) {
conf := resource.StateChangeConf{
Pending: []string{"creating", "error"},
Target: []string{"created"},
Refresh: waitForInstancesRefreshFunc(getManager, d, meta),
Timeout: d.Timeout(schema.TimeoutCreate),
}
_, err := conf.WaitForState()
if err != nil {
return err
}
}

return nil
}

Expand Down
17 changes: 9 additions & 8 deletions google/resource_compute_region_instance_group_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ func resourceComputeRegionInstanceGroupManagerCreate(d *schema.ResourceData, met

type getInstanceManagerFunc func(*schema.ResourceData, interface{}) (*computeBeta.InstanceGroupManager, error)

func getManager(d *schema.ResourceData, meta interface{}) (*computeBeta.InstanceGroupManager, error) {
func getRegionalManager(d *schema.ResourceData, meta interface{}) (*computeBeta.InstanceGroupManager, error) {
computeApiVersion := getComputeApiVersion(d, RegionInstanceGroupManagerBaseApiVersion, RegionInstanceGroupManagerVersionedFeatures)
config := meta.(*Config)

Expand Down Expand Up @@ -257,17 +257,17 @@ func waitForInstancesRefreshFunc(f getInstanceManagerFunc, d *schema.ResourceDat
log.Printf("[WARNING] Error in fetching manager while waiting for instances to come up: %s\n", err)
return nil, "error", err
}
if creatingCount := m.CurrentActions.Creating + m.CurrentActions.CreatingWithoutRetries; creatingCount > 0 {
return creatingCount, "creating", nil
if done := m.CurrentActions.None; done < m.TargetSize {
return done, "creating", nil
} else {
return creatingCount, "created", nil
return done, "created", nil
}
}
}

func resourceComputeRegionInstanceGroupManagerRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
manager, err := getManager(d, meta)
manager, err := getRegionalManager(d, meta)
if err != nil {
return err
}
Expand Down Expand Up @@ -298,12 +298,13 @@ func resourceComputeRegionInstanceGroupManagerRead(d *schema.ResourceData, meta
conf := resource.StateChangeConf{
Pending: []string{"creating", "error"},
Target: []string{"created"},
Refresh: waitForInstancesRefreshFunc(getManager, d, meta),
Refresh: waitForInstancesRefreshFunc(getRegionalManager, d, meta),
Timeout: d.Timeout(schema.TimeoutCreate),
}
_, err := conf.WaitForState()
// If err is nil, success.
return err
if err != nil {
return err
}
}

return nil
Expand Down
11 changes: 6 additions & 5 deletions website/docs/d/google_compute_instance_group.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ data "google_compute_instance_group" "all" {

The following arguments are supported:

* `name` - (Required) The name of the instance group.

* `zone` - (Required) The zone of the instance group.

- - -
* `name` - (Optional) The name of the instance group. Either `name` or `self_link` must be provided.

* `project` - (Optional) The ID of the project in which the resource belongs. If it
is not provided, the provider project is used.

* `self_link` - (Optional) The self link of the instance group. Either `name` or `self_link` must be provided.

* `zone` - (Optional) The zone of the instance group. If referencing the instance group by name
and `zone` is not provided, the provider zone is used.

## Attributes Reference

The following arguments are exported:
Expand Down
4 changes: 4 additions & 0 deletions website/docs/r/compute_instance_group_manager.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ The following arguments are supported:
instances in the group are added. Updating the target pools attribute does
not affect existing instances.

* `wait_for_instances` - (Optional) Whether to wait for all instances to be created/updated before
returning. Note that if this is set to true and the operation does not succeed, Terraform will
continue trying until it times out.

---

* `auto_healing_policies` - (Optional, [Beta](/docs/providers/google/index.html#beta-features)) The autohealing policies for this managed instance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ The following arguments are supported:
instances in the group are added. Updating the target pools attribute does
not affect existing instances.

* `wait_for_instances` - (Optional) Whether to wait for all instances to be created/updated before
returning. Note that if this is set to true and the operation does not succeed, Terraform will
continue trying until it times out.

---

* `auto_healing_policies` - (Optional, [Beta](/docs/providers/google/index.html#beta-features)) The autohealing policies for this managed instance
Expand Down

0 comments on commit 28efae5

Please sign in to comment.