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 compute instance group data source #267

Merged
merged 2 commits into from
Aug 11, 2017
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
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,
Copy link
Contributor

Choose a reason for hiding this comment

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

Since the parent is Computed, it probably doesn't make a difference but in the context of a data source, this should be Computed: true not 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 @@ -58,6 +58,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