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

provider/google: Add google_compute_zones data source #11954

Merged
merged 1 commit into from
Feb 15, 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
80 changes: 80 additions & 0 deletions builtin/providers/google/data_source_google_compute_zones.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package google

import (
"fmt"
"log"
"sort"
"time"

"github.com/hashicorp/terraform/helper/schema"
compute "google.golang.org/api/compute/v1"
)

func dataSourceGoogleComputeZones() *schema.Resource {
return &schema.Resource{
Read: dataSourceGoogleComputeZonesRead,
Schema: map[string]*schema.Schema{
"region": {
Type: schema.TypeString,
Optional: true,
},
"names": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"status": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: func(v interface{}, k string) (ws []string, es []error) {
value := v.(string)
if value != "UP" && value != "DOWN" {
es = append(es, fmt.Errorf("%q can only be 'UP' or 'DOWN' (%q given)", k, value))
}
return
},
},
},
}
}

func dataSourceGoogleComputeZonesRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

region := config.Region
if r, ok := d.GetOk("region"); ok {
region = r.(string)
}

regionUrl := fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/regions/%s",
config.Project, region)
filter := fmt.Sprintf("(region eq %s)", regionUrl)

if s, ok := d.GetOk("status"); ok {
filter += fmt.Sprintf(" (status eq %s)", s)
}

call := config.clientCompute.Zones.List(config.Project).Filter(filter)

resp, err := call.Do()
if err != nil {
return err
}

zones := flattenZones(resp.Items)
log.Printf("[DEBUG] Received Google Compute Zones: %q", zones)

d.Set("names", zones)
d.SetId(time.Now().UTC().String())

return nil
}

func flattenZones(zones []*compute.Zone) []string {
result := make([]string, len(zones), len(zones))
for i, zone := range zones {
result[i] = zone.Name
}
sort.Strings(result)
return result
}
70 changes: 70 additions & 0 deletions builtin/providers/google/data_source_google_compute_zones_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package google

import (
"errors"
"fmt"
"strconv"
"testing"

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

func TestAccGoogleComputeZones_basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCheckGoogleComputeZonesConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckGoogleComputeZonesMeta("data.google_compute_zones.available"),
),
},
},
})
}

func testAccCheckGoogleComputeZonesMeta(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Can't find zones data source: %s", n)
}

if rs.Primary.ID == "" {
return errors.New("zones data source ID not set.")
}

count, ok := rs.Primary.Attributes["names.#"]
if !ok {
return errors.New("can't find 'names' attribute")
}

noOfNames, err := strconv.Atoi(count)
if err != nil {
return errors.New("failed to read number of zones")
}
if noOfNames < 2 {
return fmt.Errorf("expected at least 2 zones, received %d, this is most likely a bug",
noOfNames)
}

for i := 0; i < noOfNames; i++ {
idx := "names." + strconv.Itoa(i)
v, ok := rs.Primary.Attributes[idx]
if !ok {
return fmt.Errorf("zone list is corrupt (%q not found), this is definitely a bug", idx)
}
if len(v) < 1 {
return fmt.Errorf("Empty zone name (%q), this is definitely a bug", idx)
}
}

return nil
}
}

var testAccCheckGoogleComputeZonesConfig = `
data "google_compute_zones" "available" {}
`
3 changes: 2 additions & 1 deletion builtin/providers/google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ func Provider() terraform.ResourceProvider {
},

DataSourcesMap: map[string]*schema.Resource{
"google_iam_policy": dataSourceGoogleIamPolicy(),
"google_iam_policy": dataSourceGoogleIamPolicy(),
"google_compute_zones": dataSourceGoogleComputeZones(),
},

ResourcesMap: map[string]*schema.Resource{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
layout: "google"
page_title: "Google: google_compute_zones"
sidebar_current: "docs-google-datasource-compute-zones"
description: |-
Provides a list of available Google Compute zones
---

# google\_compute\_zones

Provides access to available Google Compute zones in a region for a given project.
See more about [regions and zones](https://cloud.google.com/compute/docs/regions-zones/regions-zones) in the upstream docs.

```
data "google_compute_zones" "available" {}
resource "google_compute_instance_group_manager" "foo" {
count = "${length(data.google_compute_zones.available.names)}"
name = "terraform-test-${count.index}"
instance_template = "${google_compute_instance_template.foobar.self_link}"
base_instance_name = "foobar-${count.index}"
zone = "${data.google_compute_zones.available.names[count.index]}"
target_size = 1
}
```

## Argument Reference

The following arguments are supported:

* `region` (Optional) - Region from which to list available zones. Defaults to region declared in the provider.
* `status` (Optional) - Allows to filter list of zones based on their current status. Status can be either `UP` or `DOWN`.
Defaults to no filtering (all available zones - both `UP` and `DOWN`).

## Attributes Reference

The following attribute is exported:

* `names` - A list of zones available in the given region
3 changes: 3 additions & 0 deletions website/source/layouts/google.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
<li<%= sidebar_current(/^docs-google-datasource/) %>>
<a href="#">Google Cloud Platform Data Sources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-google-datasource-compute-zones") %>>
<a href="/docs/providers/google/d/google_compute_zones.html">google_compute_zones</a>
</li>
<li<%= sidebar_current("docs-google-datasource-iam-policy") %>>
<a href="/docs/providers/google/d/google_iam_policy.html">google_iam_policy</a>
</li>
Expand Down