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 wait_for_instances field to IGM and self_link option to the IG data source #1222

Merged
merged 2 commits into from
Mar 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {
Copy link
Contributor

Choose a reason for hiding this comment

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

slaps forehead

I think I remember writing this code, so thanks for catching my mistake there - obviously the instances shouldn't report ready if they're FAILED.

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