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

New data source: compute region instance group #851

Merged
Merged
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