Skip to content

Commit

Permalink
Add data source for retrieving multiple GCE subnetworks (#10669) (#18159
Browse files Browse the repository at this point in the history
)

[upstream:cb86587cb58db43ff4fa99c6369c1996543c7278]

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician committed May 16, 2024
1 parent fb9ce6a commit 7f3f4f8
Show file tree
Hide file tree
Showing 4 changed files with 330 additions and 0 deletions.
1 change: 1 addition & 0 deletions google/provider/provider_mmv1_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ var handwrittenDatasources = map[string]*schema.Resource{
"google_compute_ssl_certificate": compute.DataSourceGoogleComputeSslCertificate(),
"google_compute_ssl_policy": compute.DataSourceGoogleComputeSslPolicy(),
"google_compute_subnetwork": compute.DataSourceGoogleComputeSubnetwork(),
"google_compute_subnetworks": compute.DataSourceGoogleComputeSubnetworks(),
"google_compute_vpn_gateway": compute.DataSourceGoogleComputeVpnGateway(),
"google_compute_zones": compute.DataSourceGoogleComputeZones(),
"google_container_azure_versions": containerazure.DataSourceGoogleContainerAzureVersions(),
Expand Down
122 changes: 122 additions & 0 deletions google/services/compute/data_source_google_compute_subnetworks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package compute

import (
"fmt"
"path/filepath"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
)

func DataSourceGoogleComputeSubnetworks() *schema.Resource {
return &schema.Resource{
Read: dataSourceGoogleComputeSubnetworksRead,

Schema: map[string]*schema.Schema{
"filter": {
Type: schema.TypeString,
Optional: true,
},
"project": {
Type: schema.TypeString,
Optional: true,
},
"region": {
Type: schema.TypeString,
Optional: true,
},
"subnetworks": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"description": {
Type: schema.TypeString,
Computed: true,
},
"ip_cidr_range": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"network": {
Type: schema.TypeString,
Computed: true,
},
"network_self_link": {
Type: schema.TypeString,
Computed: true,
},
"private_ip_google_access": {
Type: schema.TypeBool,
Computed: true,
},
"self_link": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
}
}

func dataSourceGoogleComputeSubnetworksRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}

project, err := tpgresource.GetProject(d, config)
if err != nil {
return fmt.Errorf("Error fetching project for subnetwork: %s", err)
}

region, err := tpgresource.GetRegion(d, config)
if err != nil {
return fmt.Errorf("Error fetching region for subnetwork: %s", err)
}

filter := d.Get("filter").(string)

subnetworks := make([]map[string]interface{}, 0)

subnetworkList, err := config.NewComputeClient(userAgent).Subnetworks.List(project, region).Filter(filter).Do()
if err != nil {
return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Subnetworks : %s %s", project, region))
}

for _, subnet := range subnetworkList.Items {
subnetworks = append(subnetworks, map[string]interface{}{
"description": subnet.Description,
"ip_cidr_range": subnet.IpCidrRange,
"name": subnet.Name,
"network_self_link": filepath.Base(subnet.Network),
"network": subnet.Network,
"private_ip_google_access": subnet.PrivateIpGoogleAccess,
"self_link": subnet.SelfLink,
})
}

if err := d.Set("subnetworks", subnetworks); err != nil {
return fmt.Errorf("Error retrieving subnetworks: %s", err)
}

d.SetId(fmt.Sprintf(
"projects/%s/regions/%s/subnetworks",
project,
region,
))

return nil
}
160 changes: 160 additions & 0 deletions google/services/compute/data_source_google_compute_subnetworks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package compute_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-provider-google/google/acctest"
"github.com/hashicorp/terraform-provider-google/google/envvar"
)

func TestAccDataSourceGoogleSubnetworks_basic(t *testing.T) {
t.Parallel()

// Common resource configuration
static_prefix := "tf-test"
random_suffix := acctest.RandString(t, 10)
project := envvar.GetTestProjectFromEnv()
region := envvar.GetTestRegionFromEnv()

// Resource identifier used for content testing
id := fmt.Sprintf(
"projects/%s/regions/%s/subnetworks",
project,
region,
)

// Configuration of network resources
network := static_prefix + "-network-" + random_suffix
subnet_1 := static_prefix + "-subnet-1-" + random_suffix
subnet_2 := static_prefix + "-subnet-2-" + random_suffix
cidr_1 := "192.168.31.0/24"
cidr_2 := "192.168.32.0/24"

// Configuration map used in test deployment
context := map[string]interface{}{
"cidr_1": cidr_1,
"cidr_2": cidr_2,
"network": network,
"project": project,
"region": region,
"subnet_1": subnet_1,
"subnet_2": subnet_2,
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccCheckGoogleSubnetworksConfig(context),
Check: resource.ComposeTestCheckFunc(
// Test schema
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.0.description"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.0.ip_cidr_range"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.0.name"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.0.network"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.0.network_self_link"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.0.private_ip_google_access"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.0.self_link"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.1.description"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.1.ip_cidr_range"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.1.name"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.1.network"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.1.network_self_link"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.1.private_ip_google_access"),
resource.TestCheckResourceAttrSet("data.google_compute_subnetworks.all", "subnetworks.1.self_link"),
// Test content
resource.TestCheckResourceAttr("data.google_compute_subnetworks.all", "id", id),
resource.TestCheckResourceAttr("data.google_compute_subnetworks.one", "subnetworks.0.ip_cidr_range", cidr_1),
resource.TestCheckResourceAttr("data.google_compute_subnetworks.one", "subnetworks.0.name", subnet_1),
resource.TestCheckResourceAttr("data.google_compute_subnetworks.one", "subnetworks.0.private_ip_google_access", "true"),
resource.TestCheckResourceAttr("data.google_compute_subnetworks.two", "subnetworks.0.ip_cidr_range", cidr_2),
resource.TestCheckResourceAttr("data.google_compute_subnetworks.two", "subnetworks.0.name", subnet_2),
resource.TestCheckResourceAttr("data.google_compute_subnetworks.two", "subnetworks.0.private_ip_google_access", "false"),
),
},
},
})
}

func testAccCheckGoogleSubnetworksConfig(context map[string]interface{}) string {
return fmt.Sprintf(`
locals {
cidr_one = "%s"
cidr_two = "%s"
network = "%s"
project_id = "%s"
region = "%s"
subnet_one = "%s"
subnet_two = "%s"
}
resource "google_compute_network" "this" {
auto_create_subnetworks = false
mtu = 1460
name = local.network
project = local.project_id
}
resource "google_compute_subnetwork" "subnet_one" {
description = "Test subnet one"
ip_cidr_range = local.cidr_one
name = local.subnet_one
network = google_compute_network.this.id
private_ip_google_access = true
project = local.project_id
region = local.region
}
resource "google_compute_subnetwork" "subnet_two" {
description = "Test subnet two"
ip_cidr_range = local.cidr_two
name = local.subnet_two
network = google_compute_network.this.id
private_ip_google_access = false
project = local.project_id
region = local.region
}
data "google_compute_subnetworks" "all" {
filter = "network eq .*${google_compute_network.this.name}"
depends_on = [
google_compute_subnetwork.subnet_one,
google_compute_subnetwork.subnet_two,
]
}
data "google_compute_subnetworks" "one" {
filter = "name: ${google_compute_subnetwork.subnet_one.name}"
region = local.region
}
data "google_compute_subnetworks" "two" {
filter = "ipCidrRange eq ${google_compute_subnetwork.subnet_two.ip_cidr_range}"
project = local.project_id
region = local.region
}
data "google_compute_subnetworks" "no_attr" {
depends_on = [
google_compute_network.this,
google_compute_subnetwork.subnet_one,
google_compute_subnetwork.subnet_two,
]
}`,
context["cidr_1"].(string),
context["cidr_2"].(string),
context["network"].(string),
context["project"].(string),
context["region"].(string),
context["subnet_1"].(string),
context["subnet_2"].(string),
)
}
47 changes: 47 additions & 0 deletions website/docs/d/compute_subnetworks.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
subcategory: "Compute Engine"
description: |-
Get subnetworks within GCE.
---

# google\_compute\_subnetworks

Get subnetworks within GCE.
See [the official documentation](https://cloud.google.com/vpc/docs/subnets)
and [API](https://cloud.google.com/compute/docs/reference/rest/v1/subnetworks/list).

## Example Usage

```hcl
data "google_compute_subnetworks" "my-subnetworks" {
filter = "ipCidrRange eq 192.168.178.0/24"
project = "my-project"
region = "us-east1"
}
```

## Argument Reference

The following arguments are supported:

* `filter` - (Optional) - A string filter as defined in the [REST API](https://cloud.google.com/compute/docs/reference/rest/v1/subnetworks/list#query-parameters).

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

* `region` - (Optional) The region this subnetwork has been created in. If
unspecified, this defaults to the region configured in the provider.

## Attributes Reference

* `subnetworks` - A list of all retrieved GCE subnetworks. Structure is [defined below](#nested_subnetworks).

<a name="nested_subnetworks"></a>The `subnetworks` block supports:

* `description` - Description of the subnetwork.
* `ip_cidr_range` - The IP address range represented as a CIDR block.
* `name` - The name of the subnetwork.
* `network` - The self link of the parent network.
* `network_name` - The name of the parent network computed from `network` attribute.
* `private_ip_google_access` - Whether the VMs in the subnet can access Google services without assigned external IP addresses.
* `self_link` - The self link of the subnetwork.

0 comments on commit 7f3f4f8

Please sign in to comment.