Skip to content

Commit

Permalink
Add compute instance group data source (hashicorp#267)
Browse files Browse the repository at this point in the history
  • Loading branch information
aadidenko authored and Dmitry Vlasov committed Aug 15, 2017
1 parent bcfa9e2 commit eb35e5f
Show file tree
Hide file tree
Showing 5 changed files with 389 additions and 0 deletions.
83 changes: 83 additions & 0 deletions google/data_source_google_compute_instance_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package google

import (
"fmt"

"github.com/hashicorp/terraform/helper/schema"
)

func dataSourceGoogleComputeInstanceGroup() *schema.Resource {
return &schema.Resource{
Read: dataSourceComputeInstanceGroupRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},

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

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

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

"instances": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},

"named_port": {
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,
},
},
},
},

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

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

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

func dataSourceComputeInstanceGroupRead(d *schema.ResourceData, meta interface{}) error {
zone := d.Get("zone").(string)
name := d.Get("name").(string)

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

return resourceComputeInstanceGroupRead(d, meta)
}
253 changes: 253 additions & 0 deletions google/data_source_google_compute_instance_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
package google

import (
"errors"
"fmt"
"reflect"
"sort"
"strconv"
"strings"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccDataSourceGoogleComputeInstanceGroup_basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCheckDataSourceGoogleComputeInstanceGroupConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckDataSourceGoogleComputeInstanceGroup("data.google_compute_instance_group.test"),
),
},
},
})
}

func TestAccDataSourceGoogleComputeInstanceGroup_withNamedPort(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCheckDataSourceGoogleComputeInstanceGroupConfigWithNamedPort,
Check: resource.ComposeTestCheckFunc(
testAccCheckDataSourceGoogleComputeInstanceGroup("data.google_compute_instance_group.test"),
),
},
},
})
}

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)
}

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

dsAttrs := ds.Primary.Attributes
rsAttrs := rs.Primary.Attributes

attrsToTest := []string{
"id",
"name",
"zone",
"project",
"description",
"network",
"self_link",
"size",
}

for _, attrToTest := range attrsToTest {
if dsAttrs[attrToTest] != rsAttrs[attrToTest] {
return fmt.Errorf("%s is %s; want %s", attrToTest, dsAttrs[attrToTest], rsAttrs[attrToTest])
}
}

dsNamedPortsCount, ok := dsAttrs["named_port.#"]
if !ok {
return errors.New("can't find 'named_port' attribute in data source")
}

dsNoOfNamedPorts, err := strconv.Atoi(dsNamedPortsCount)
if err != nil {
return errors.New("failed to read number of named ports in data source")
}

rsNamedPortsCount, ok := rsAttrs["named_port.#"]
if !ok {
return errors.New("can't find 'named_port' attribute in resource")
}

rsNoOfNamedPorts, err := strconv.Atoi(rsNamedPortsCount)
if err != nil {
return errors.New("failed to read number of named ports in resource")
}

if dsNoOfNamedPorts != rsNoOfNamedPorts {
return fmt.Errorf(
"expected %d number of named port, received %d, this is most likely a bug",
rsNoOfNamedPorts,
dsNoOfNamedPorts,
)
}

namedPortItemKeys := []string{"name", "value"}
for i := 0; i < dsNoOfNamedPorts; i++ {
for _, key := range namedPortItemKeys {
idx := fmt.Sprintf("named_port.%d.%s", i, key)
if dsAttrs[idx] != rsAttrs[idx] {
return fmt.Errorf("%s is %s; want %s", idx, dsAttrs[idx], rsAttrs[idx])
}
}
}

dsInstancesCount, ok := dsAttrs["instances.#"]
if !ok {
return errors.New("can't find 'instances' attribute in data source")
}

dsNoOfInstances, err := strconv.Atoi(dsInstancesCount)
if err != nil {
return errors.New("failed to read number of named ports in data source")
}

rsInstancesCount, ok := rsAttrs["instances.#"]
if !ok {
return errors.New("can't find 'instances' attribute in resource")
}

rsNoOfInstances, err := strconv.Atoi(rsInstancesCount)
if err != nil {
return errors.New("failed to read number of instances in resource")
}

if dsNoOfInstances != rsNoOfInstances {
return fmt.Errorf(
"expected %d number of instances, received %d, this is most likely a bug",
rsNoOfInstances,
dsNoOfInstances,
)
}

// We don't know the exact keys of the elements, so go through the whole list looking for matching ones
dsInstancesValues := []string{}
for k, v := range dsAttrs {
if strings.HasPrefix(k, "instances") && !strings.HasSuffix(k, "#") {
dsInstancesValues = append(dsInstancesValues, v)
}
}

rsInstancesValues := []string{}
for k, v := range rsAttrs {
if strings.HasPrefix(k, "instances") && !strings.HasSuffix(k, "#") {
rsInstancesValues = append(rsInstancesValues, v)
}
}

sort.Strings(dsInstancesValues)
sort.Strings(rsInstancesValues)

if !reflect.DeepEqual(dsInstancesValues, rsInstancesValues) {
return fmt.Errorf("expected %v list of instances, received %v", rsInstancesValues, dsInstancesValues)
}

return nil
}
}

var testAccCheckDataSourceGoogleComputeInstanceGroupConfig = fmt.Sprintf(`
resource "google_compute_instance" "test" {
name = "tf-test-%s"
machine_type = "n1-standard-1"
zone = "us-central1-a"
boot_disk {
initialize_params {
image = "debian-cloud/debian-8"
}
}
network_interface {
network = "default"
access_config {
// Ephemeral IP
}
}
}
resource "google_compute_instance_group" "test" {
name = "tf-test-%s"
zone = "${google_compute_instance.test.zone}"
instances = [
"${google_compute_instance.test.self_link}",
]
}
data "google_compute_instance_group" "test" {
name = "${google_compute_instance_group.test.name}"
zone = "${google_compute_instance_group.test.zone}"
}
`, acctest.RandString(10), acctest.RandString(10))

var testAccCheckDataSourceGoogleComputeInstanceGroupConfigWithNamedPort = fmt.Sprintf(`
resource "google_compute_instance" "test" {
name = "tf-test-%s"
machine_type = "n1-standard-1"
zone = "us-central1-a"
boot_disk {
initialize_params {
image = "debian-cloud/debian-8"
}
}
network_interface {
network = "default"
access_config {
// Ephemeral IP
}
}
}
resource "google_compute_instance_group" "test" {
name = "tf-test-%s"
zone = "${google_compute_instance.test.zone}"
named_port {
name = "http"
port = "8080"
}
named_port {
name = "https"
port = "8443"
}
instances = [
"${google_compute_instance.test.self_link}",
]
}
data "google_compute_instance_group" "test" {
name = "${google_compute_instance_group.test.name}"
zone = "${google_compute_instance_group.test.zone}"
}
`, acctest.RandString(10), acctest.RandString(10))
1 change: 1 addition & 0 deletions google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func Provider() terraform.ResourceProvider {
"google_compute_network": dataSourceGoogleComputeNetwork(),
"google_compute_subnetwork": dataSourceGoogleComputeSubnetwork(),
"google_compute_zones": dataSourceGoogleComputeZones(),
"google_compute_instance_group": dataSourceGoogleComputeInstanceGroup(),
"google_container_engine_versions": dataSourceGoogleContainerEngineVersions(),
"google_iam_policy": dataSourceGoogleIamPolicy(),
"google_storage_object_signed_url": dataSourceGoogleSignedUrl(),
Expand Down
49 changes: 49 additions & 0 deletions website/docs/d/google_compute_instance_group.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
layout: "google"
page_title: "Google: google_compute_instance_group"
sidebar_current: "docs-google-datasource-compute-instance-group"
description: |-
Get a Compute Instance Group within GCE.
---

# google\_compute\_instance\_group

Get a Compute Instance Group within GCE.
For more information, see [the official documentation](https://cloud.google.com/compute/docs/instance-groups/#unmanaged_instance_groups)
and [API](https://cloud.google.com/compute/docs/reference/latest/instanceGroups)

```
data "google_compute_instance_group" "all" {
name = "instance-group-name"
zone = "us-central1-a"
}
```

## Argument Reference

The following arguments are supported:

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

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

- - -

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

## Attributes Reference

The following arguments are exported:

* `description` - Textual description of the instance group.

* `instances` - List of instances in the group.

* `named_port` - List of named ports in the group.

* `network` - The URL of the network the instance group is in.

* `self_link` - The URI of the resource.

* `size` - The number of instances in the group.
Loading

0 comments on commit eb35e5f

Please sign in to comment.