Skip to content

Commit eb35e5f

Browse files
aadidenkoDmitry Vlasov
authored and
Dmitry Vlasov
committed
Add compute instance group data source (hashicorp#267)
1 parent bcfa9e2 commit eb35e5f

5 files changed

+389
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package google
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/hashicorp/terraform/helper/schema"
7+
)
8+
9+
func dataSourceGoogleComputeInstanceGroup() *schema.Resource {
10+
return &schema.Resource{
11+
Read: dataSourceComputeInstanceGroupRead,
12+
Schema: map[string]*schema.Schema{
13+
"name": {
14+
Type: schema.TypeString,
15+
Required: true,
16+
},
17+
18+
"zone": {
19+
Type: schema.TypeString,
20+
Required: true,
21+
},
22+
23+
"project": {
24+
Type: schema.TypeString,
25+
Optional: true,
26+
},
27+
28+
"description": {
29+
Type: schema.TypeString,
30+
Computed: true,
31+
},
32+
33+
"instances": {
34+
Type: schema.TypeSet,
35+
Computed: true,
36+
Elem: &schema.Schema{Type: schema.TypeString},
37+
Set: schema.HashString,
38+
},
39+
40+
"named_port": {
41+
Type: schema.TypeList,
42+
Computed: true,
43+
Elem: &schema.Resource{
44+
Schema: map[string]*schema.Schema{
45+
"name": {
46+
Type: schema.TypeString,
47+
Required: true,
48+
},
49+
50+
"port": {
51+
Type: schema.TypeInt,
52+
Required: true,
53+
},
54+
},
55+
},
56+
},
57+
58+
"network": {
59+
Type: schema.TypeString,
60+
Computed: true,
61+
},
62+
63+
"self_link": {
64+
Type: schema.TypeString,
65+
Computed: true,
66+
},
67+
68+
"size": {
69+
Type: schema.TypeInt,
70+
Computed: true,
71+
},
72+
},
73+
}
74+
}
75+
76+
func dataSourceComputeInstanceGroupRead(d *schema.ResourceData, meta interface{}) error {
77+
zone := d.Get("zone").(string)
78+
name := d.Get("name").(string)
79+
80+
d.SetId(fmt.Sprintf("%s/%s", zone, name))
81+
82+
return resourceComputeInstanceGroupRead(d, meta)
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
package google
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"reflect"
7+
"sort"
8+
"strconv"
9+
"strings"
10+
"testing"
11+
12+
"github.com/hashicorp/terraform/helper/acctest"
13+
"github.com/hashicorp/terraform/helper/resource"
14+
"github.com/hashicorp/terraform/terraform"
15+
)
16+
17+
func TestAccDataSourceGoogleComputeInstanceGroup_basic(t *testing.T) {
18+
resource.Test(t, resource.TestCase{
19+
PreCheck: func() { testAccPreCheck(t) },
20+
Providers: testAccProviders,
21+
Steps: []resource.TestStep{
22+
{
23+
Config: testAccCheckDataSourceGoogleComputeInstanceGroupConfig,
24+
Check: resource.ComposeTestCheckFunc(
25+
testAccCheckDataSourceGoogleComputeInstanceGroup("data.google_compute_instance_group.test"),
26+
),
27+
},
28+
},
29+
})
30+
}
31+
32+
func TestAccDataSourceGoogleComputeInstanceGroup_withNamedPort(t *testing.T) {
33+
resource.Test(t, resource.TestCase{
34+
PreCheck: func() { testAccPreCheck(t) },
35+
Providers: testAccProviders,
36+
Steps: []resource.TestStep{
37+
{
38+
Config: testAccCheckDataSourceGoogleComputeInstanceGroupConfigWithNamedPort,
39+
Check: resource.ComposeTestCheckFunc(
40+
testAccCheckDataSourceGoogleComputeInstanceGroup("data.google_compute_instance_group.test"),
41+
),
42+
},
43+
},
44+
})
45+
}
46+
47+
func testAccCheckDataSourceGoogleComputeInstanceGroup(dataSourceName string) resource.TestCheckFunc {
48+
return func(s *terraform.State) error {
49+
dsFullName := "data.google_compute_instance_group.test"
50+
rsFullName := "google_compute_instance_group.test"
51+
ds, ok := s.RootModule().Resources[dsFullName]
52+
if !ok {
53+
return fmt.Errorf("cant' find resource called %s in state", dsFullName)
54+
}
55+
56+
rs, ok := s.RootModule().Resources[rsFullName]
57+
if !ok {
58+
return fmt.Errorf("can't find data source called %s in state", rsFullName)
59+
}
60+
61+
dsAttrs := ds.Primary.Attributes
62+
rsAttrs := rs.Primary.Attributes
63+
64+
attrsToTest := []string{
65+
"id",
66+
"name",
67+
"zone",
68+
"project",
69+
"description",
70+
"network",
71+
"self_link",
72+
"size",
73+
}
74+
75+
for _, attrToTest := range attrsToTest {
76+
if dsAttrs[attrToTest] != rsAttrs[attrToTest] {
77+
return fmt.Errorf("%s is %s; want %s", attrToTest, dsAttrs[attrToTest], rsAttrs[attrToTest])
78+
}
79+
}
80+
81+
dsNamedPortsCount, ok := dsAttrs["named_port.#"]
82+
if !ok {
83+
return errors.New("can't find 'named_port' attribute in data source")
84+
}
85+
86+
dsNoOfNamedPorts, err := strconv.Atoi(dsNamedPortsCount)
87+
if err != nil {
88+
return errors.New("failed to read number of named ports in data source")
89+
}
90+
91+
rsNamedPortsCount, ok := rsAttrs["named_port.#"]
92+
if !ok {
93+
return errors.New("can't find 'named_port' attribute in resource")
94+
}
95+
96+
rsNoOfNamedPorts, err := strconv.Atoi(rsNamedPortsCount)
97+
if err != nil {
98+
return errors.New("failed to read number of named ports in resource")
99+
}
100+
101+
if dsNoOfNamedPorts != rsNoOfNamedPorts {
102+
return fmt.Errorf(
103+
"expected %d number of named port, received %d, this is most likely a bug",
104+
rsNoOfNamedPorts,
105+
dsNoOfNamedPorts,
106+
)
107+
}
108+
109+
namedPortItemKeys := []string{"name", "value"}
110+
for i := 0; i < dsNoOfNamedPorts; i++ {
111+
for _, key := range namedPortItemKeys {
112+
idx := fmt.Sprintf("named_port.%d.%s", i, key)
113+
if dsAttrs[idx] != rsAttrs[idx] {
114+
return fmt.Errorf("%s is %s; want %s", idx, dsAttrs[idx], rsAttrs[idx])
115+
}
116+
}
117+
}
118+
119+
dsInstancesCount, ok := dsAttrs["instances.#"]
120+
if !ok {
121+
return errors.New("can't find 'instances' attribute in data source")
122+
}
123+
124+
dsNoOfInstances, err := strconv.Atoi(dsInstancesCount)
125+
if err != nil {
126+
return errors.New("failed to read number of named ports in data source")
127+
}
128+
129+
rsInstancesCount, ok := rsAttrs["instances.#"]
130+
if !ok {
131+
return errors.New("can't find 'instances' attribute in resource")
132+
}
133+
134+
rsNoOfInstances, err := strconv.Atoi(rsInstancesCount)
135+
if err != nil {
136+
return errors.New("failed to read number of instances in resource")
137+
}
138+
139+
if dsNoOfInstances != rsNoOfInstances {
140+
return fmt.Errorf(
141+
"expected %d number of instances, received %d, this is most likely a bug",
142+
rsNoOfInstances,
143+
dsNoOfInstances,
144+
)
145+
}
146+
147+
// We don't know the exact keys of the elements, so go through the whole list looking for matching ones
148+
dsInstancesValues := []string{}
149+
for k, v := range dsAttrs {
150+
if strings.HasPrefix(k, "instances") && !strings.HasSuffix(k, "#") {
151+
dsInstancesValues = append(dsInstancesValues, v)
152+
}
153+
}
154+
155+
rsInstancesValues := []string{}
156+
for k, v := range rsAttrs {
157+
if strings.HasPrefix(k, "instances") && !strings.HasSuffix(k, "#") {
158+
rsInstancesValues = append(rsInstancesValues, v)
159+
}
160+
}
161+
162+
sort.Strings(dsInstancesValues)
163+
sort.Strings(rsInstancesValues)
164+
165+
if !reflect.DeepEqual(dsInstancesValues, rsInstancesValues) {
166+
return fmt.Errorf("expected %v list of instances, received %v", rsInstancesValues, dsInstancesValues)
167+
}
168+
169+
return nil
170+
}
171+
}
172+
173+
var testAccCheckDataSourceGoogleComputeInstanceGroupConfig = fmt.Sprintf(`
174+
resource "google_compute_instance" "test" {
175+
name = "tf-test-%s"
176+
machine_type = "n1-standard-1"
177+
zone = "us-central1-a"
178+
179+
boot_disk {
180+
initialize_params {
181+
image = "debian-cloud/debian-8"
182+
}
183+
}
184+
185+
network_interface {
186+
network = "default"
187+
188+
access_config {
189+
// Ephemeral IP
190+
}
191+
}
192+
}
193+
194+
resource "google_compute_instance_group" "test" {
195+
name = "tf-test-%s"
196+
zone = "${google_compute_instance.test.zone}"
197+
198+
instances = [
199+
"${google_compute_instance.test.self_link}",
200+
]
201+
}
202+
203+
data "google_compute_instance_group" "test" {
204+
name = "${google_compute_instance_group.test.name}"
205+
zone = "${google_compute_instance_group.test.zone}"
206+
}
207+
`, acctest.RandString(10), acctest.RandString(10))
208+
209+
var testAccCheckDataSourceGoogleComputeInstanceGroupConfigWithNamedPort = fmt.Sprintf(`
210+
resource "google_compute_instance" "test" {
211+
name = "tf-test-%s"
212+
machine_type = "n1-standard-1"
213+
zone = "us-central1-a"
214+
215+
boot_disk {
216+
initialize_params {
217+
image = "debian-cloud/debian-8"
218+
}
219+
}
220+
221+
network_interface {
222+
network = "default"
223+
224+
access_config {
225+
// Ephemeral IP
226+
}
227+
}
228+
}
229+
230+
resource "google_compute_instance_group" "test" {
231+
name = "tf-test-%s"
232+
zone = "${google_compute_instance.test.zone}"
233+
234+
named_port {
235+
name = "http"
236+
port = "8080"
237+
}
238+
239+
named_port {
240+
name = "https"
241+
port = "8443"
242+
}
243+
244+
instances = [
245+
"${google_compute_instance.test.self_link}",
246+
]
247+
}
248+
249+
data "google_compute_instance_group" "test" {
250+
name = "${google_compute_instance_group.test.name}"
251+
zone = "${google_compute_instance_group.test.zone}"
252+
}
253+
`, acctest.RandString(10), acctest.RandString(10))

google/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func Provider() terraform.ResourceProvider {
6060
"google_compute_network": dataSourceGoogleComputeNetwork(),
6161
"google_compute_subnetwork": dataSourceGoogleComputeSubnetwork(),
6262
"google_compute_zones": dataSourceGoogleComputeZones(),
63+
"google_compute_instance_group": dataSourceGoogleComputeInstanceGroup(),
6364
"google_container_engine_versions": dataSourceGoogleContainerEngineVersions(),
6465
"google_iam_policy": dataSourceGoogleIamPolicy(),
6566
"google_storage_object_signed_url": dataSourceGoogleSignedUrl(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
layout: "google"
3+
page_title: "Google: google_compute_instance_group"
4+
sidebar_current: "docs-google-datasource-compute-instance-group"
5+
description: |-
6+
Get a Compute Instance Group within GCE.
7+
---
8+
9+
# google\_compute\_instance\_group
10+
11+
Get a Compute Instance Group within GCE.
12+
For more information, see [the official documentation](https://cloud.google.com/compute/docs/instance-groups/#unmanaged_instance_groups)
13+
and [API](https://cloud.google.com/compute/docs/reference/latest/instanceGroups)
14+
15+
```
16+
data "google_compute_instance_group" "all" {
17+
name = "instance-group-name"
18+
zone = "us-central1-a"
19+
}
20+
```
21+
22+
## Argument Reference
23+
24+
The following arguments are supported:
25+
26+
* `name` - (Required) The name of the instance group.
27+
28+
* `zone` - (Required) The zone of the instance group.
29+
30+
- - -
31+
32+
* `project` - (Optional) The project in which the resource belongs. If it
33+
is not provided, the provider project is used.
34+
35+
## Attributes Reference
36+
37+
The following arguments are exported:
38+
39+
* `description` - Textual description of the instance group.
40+
41+
* `instances` - List of instances in the group.
42+
43+
* `named_port` - List of named ports in the group.
44+
45+
* `network` - The URL of the network the instance group is in.
46+
47+
* `self_link` - The URI of the resource.
48+
49+
* `size` - The number of instances in the group.

0 commit comments

Comments
 (0)