Skip to content

Commit

Permalink
New data source: compute region instance group (#851)
Browse files Browse the repository at this point in the history
* Add new data source: compute region instance group manager's groups.
* Add documentation for wait_for_instances and for the timeout mechanism in resourceComputeRegionInstanceGroupManagerCreate.
  • Loading branch information
nat-henderson authored Dec 14, 2017
1 parent 086b9e9 commit d2611d4
Show file tree
Hide file tree
Showing 6 changed files with 397 additions and 20 deletions.
160 changes: 160 additions & 0 deletions google/data_source_google_compute_region_instance_group_manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package google

import (
"errors"
"fmt"
"github.com/hashicorp/terraform/helper/schema"
compute "google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
"log"
"net/url"
"strconv"
"strings"
)

func dataSourceGoogleComputeRegionInstanceGroup() *schema.Resource {
return &schema.Resource{
Read: dataSourceComputeRegionInstanceGroupRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},

"instances": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"instance": {
Type: schema.TypeString,
Required: true,
},

"status": {
Type: schema.TypeString,
Required: true,
},

"named_ports": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"port": {
Type: schema.TypeInt,
Required: true,
},
},
},
},
},
},
},

"region": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},

"project": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},

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

"size": {
Type: schema.TypeInt,
Computed: true,
},
},
}
}

func dataSourceComputeRegionInstanceGroupRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
var project, region, name string
if self_link, ok := d.GetOk("self_link"); ok {
parsed, err := url.Parse(self_link.(string))
if err != nil {
return err
}
s := strings.Split(parsed.Path, "/")
project, region, name = s[4], s[6], s[8]
// e.g. https://www.googleapis.com/compute/beta/projects/project_name/regions/region_name/instanceGroups/foobarbaz

} else {
var err error
project, err = getProject(d, config)
if err != nil {
return err
}

region, err = getRegion(d, config)
if err != nil {
return err
}
n, ok := d.GetOk("name")
name = n.(string)
if !ok {
return errors.New("Must provide either `self_link` or `name`.")
}
}

instanceGroup, err := config.clientCompute.RegionInstanceGroups.Get(
project, region, name).Do()
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("Region Instance Group %q", name))
}

members, err := config.clientCompute.RegionInstanceGroups.ListInstances(
project, region, name, &compute.RegionInstanceGroupsListInstancesRequest{
InstanceState: "ALL",
}).Do()
if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
// The resource doesn't have any instances, which is okay.
d.Set("instances", nil)
} else {
return fmt.Errorf("Error reading RegionInstanceGroup Members: %s", err)
}
} else {
d.Set("instances", flattenInstancesWithNamedPorts(members.Items))
}
d.Set("kind", instanceGroup.Kind)
d.SetId(strconv.FormatUint(instanceGroup.Id, 16))
d.Set("self_link", instanceGroup.SelfLink)
d.Set("name", name)
d.Set("project", project)
d.Set("region", region)
return nil
}

func flattenInstancesWithNamedPorts(insts []*compute.InstanceWithNamedPorts) []map[string]interface{} {
result := make([]map[string]interface{}, 0, len(insts))
log.Printf("There were %d instances.\n", len(insts))
for _, inst := range insts {
instMap := make(map[string]interface{})
instMap["instance"] = inst.Instance
instMap["named_ports"] = flattenNamedPorts(inst.NamedPorts)
instMap["status"] = inst.Status
result = append(result, instMap)
}
return result
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package google

import (
"fmt"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"testing"
)

func TestAccDataSourceRegionInstanceGroupManager(t *testing.T) {
t.Parallel()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceRegionInstanceGroupManagerConfig("foobarbaz"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.google_compute_region_instance_group.data_source", "name", "foobarbaz"),
resource.TestCheckResourceAttr("data.google_compute_region_instance_group.data_source", "project", getTestProjectFromEnv()),
resource.TestCheckResourceAttr("data.google_compute_region_instance_group.data_source", "instances.#", "10")),
},
},
})
}

func testAccDataSourceRegionInstanceGroupManagerConfig(instanceManagerName string) string {
return fmt.Sprintf(`
resource "google_compute_health_check" "autohealing" {
name = "%s"
check_interval_sec = 1
timeout_sec = 1
healthy_threshold = 2
unhealthy_threshold = 10
http_health_check {
request_path = "/"
port = "80"
}
}
resource "google_compute_target_pool" "foo" {
name = "%s"
}
data "google_compute_image" "debian" {
project = "debian-cloud"
name = "debian-9-stretch-v20171129"
}
resource "google_compute_instance_template" "foo" {
machine_type = "n1-standard-1"
disk {
source_image = "${data.google_compute_image.debian.self_link}"
}
network_interface {
access_config {
}
network = "default"
}
}
resource "google_compute_region_instance_group_manager" "foo" {
name = "%s"
base_instance_name = "foo"
instance_template = "${google_compute_instance_template.foo.self_link}"
region = "us-central1"
target_pools = ["${google_compute_target_pool.foo.self_link}"]
target_size = 10
named_port {
name = "web"
port = 80
}
wait_for_instances = true
auto_healing_policies {
health_check = "${google_compute_health_check.autohealing.self_link}"
initial_delay_sec = 600
}
}
data "google_compute_region_instance_group" "data_source" {
self_link = "${google_compute_region_instance_group_manager.foo.instance_group}"
}
`, acctest.RandomWithPrefix("test-rigm-"), acctest.RandomWithPrefix("test-rigm-"), instanceManagerName)
}
29 changes: 15 additions & 14 deletions google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,21 @@ func Provider() terraform.ResourceProvider {
},

DataSourcesMap: map[string]*schema.Resource{
"google_dns_managed_zone": dataSourceDnsManagedZone(),
"google_client_config": dataSourceGoogleClientConfig(),
"google_compute_address": dataSourceGoogleComputeAddress(),
"google_compute_image": dataSourceGoogleComputeImage(),
"google_compute_global_address": dataSourceGoogleComputeGlobalAddress(),
"google_compute_lb_ip_ranges": dataSourceGoogleComputeLbIpRanges(),
"google_compute_network": dataSourceGoogleComputeNetwork(),
"google_compute_subnetwork": dataSourceGoogleComputeSubnetwork(),
"google_compute_zones": dataSourceGoogleComputeZones(),
"google_compute_instance_group": dataSourceGoogleComputeInstanceGroup(),
"google_container_engine_versions": dataSourceGoogleContainerEngineVersions(),
"google_active_folder": dataSourceGoogleActiveFolder(),
"google_iam_policy": dataSourceGoogleIamPolicy(),
"google_storage_object_signed_url": dataSourceGoogleSignedUrl(),
"google_dns_managed_zone": dataSourceDnsManagedZone(),
"google_client_config": dataSourceGoogleClientConfig(),
"google_compute_address": dataSourceGoogleComputeAddress(),
"google_compute_image": dataSourceGoogleComputeImage(),
"google_compute_global_address": dataSourceGoogleComputeGlobalAddress(),
"google_compute_lb_ip_ranges": dataSourceGoogleComputeLbIpRanges(),
"google_compute_network": dataSourceGoogleComputeNetwork(),
"google_compute_subnetwork": dataSourceGoogleComputeSubnetwork(),
"google_compute_zones": dataSourceGoogleComputeZones(),
"google_compute_instance_group": dataSourceGoogleComputeInstanceGroup(),
"google_compute_region_instance_group": dataSourceGoogleComputeRegionInstanceGroup(),
"google_container_engine_versions": dataSourceGoogleContainerEngineVersions(),
"google_active_folder": dataSourceGoogleActiveFolder(),
"google_iam_policy": dataSourceGoogleIamPolicy(),
"google_storage_object_signed_url": dataSourceGoogleSignedUrl(),
},

ResourcesMap: map[string]*schema.Resource{
Expand Down
Loading

0 comments on commit d2611d4

Please sign in to comment.