Skip to content

Commit 6864f1f

Browse files
ortamanrosbo
authored andcommitted
Added GCP Netblock Data Source (#1416) (#1580)
* Added GCP Netblock Data Source (#1416) * Added docs for google_netblock_ip_ranges (#1416) * Code review changes (#1416)
1 parent eeafdf8 commit 6864f1f

5 files changed

+209
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package google
2+
3+
import (
4+
"fmt"
5+
"github.com/hashicorp/terraform/helper/schema"
6+
"io/ioutil"
7+
"net/http"
8+
"strings"
9+
)
10+
11+
func dataSourceGoogleNetblockIpRanges() *schema.Resource {
12+
return &schema.Resource{
13+
Read: dataSourceGoogleNetblockIpRangesRead,
14+
15+
Schema: map[string]*schema.Schema{
16+
"cidr_blocks": {
17+
Type: schema.TypeList,
18+
Elem: &schema.Schema{Type: schema.TypeString},
19+
Computed: true,
20+
},
21+
"cidr_blocks_ipv4": {
22+
Type: schema.TypeList,
23+
Elem: &schema.Schema{Type: schema.TypeString},
24+
Computed: true,
25+
},
26+
"cidr_blocks_ipv6": {
27+
Type: schema.TypeList,
28+
Elem: &schema.Schema{Type: schema.TypeString},
29+
Computed: true,
30+
},
31+
},
32+
}
33+
}
34+
35+
func dataSourceGoogleNetblockIpRangesRead(d *schema.ResourceData, meta interface{}) error {
36+
d.SetId("netblock-ip-ranges")
37+
38+
// https://cloud.google.com/compute/docs/faq#where_can_i_find_product_name_short_ip_ranges
39+
CidrBlocks, err := getCidrBlocks()
40+
41+
if err != nil {
42+
return err
43+
}
44+
45+
d.Set("cidr_blocks", CidrBlocks["cidr_blocks"])
46+
d.Set("cidr_blocks_ipv4", CidrBlocks["cidr_blocks_ipv4"])
47+
d.Set("cidr_blocks_ipv6", CidrBlocks["cidr_blocks_ipv6"])
48+
49+
return nil
50+
}
51+
52+
func netblock_request(name string) (string, error) {
53+
const DNS_URL = "https://dns.google.com/resolve?name=%s&type=TXT"
54+
55+
response, err := http.Get(fmt.Sprintf("https://dns.google.com/resolve?name=%s&type=TXT", name))
56+
57+
if err != nil {
58+
return "", fmt.Errorf("Error from _cloud-netblocks: %s", err)
59+
}
60+
61+
defer response.Body.Close()
62+
body, err := ioutil.ReadAll(response.Body)
63+
64+
if err != nil {
65+
return "", fmt.Errorf("Error to retrieve the domains list: %s", err)
66+
}
67+
68+
return string(body), nil
69+
}
70+
71+
func getCidrBlocks() (map[string][]string, error) {
72+
const INITIAL_NETBLOCK_DNS = "_cloud-netblocks.googleusercontent.com"
73+
var dnsNetblockList []string
74+
cidrBlocks := make(map[string][]string)
75+
76+
response, err := netblock_request(INITIAL_NETBLOCK_DNS)
77+
78+
if err != nil {
79+
return nil, err
80+
}
81+
82+
splitedResponse := strings.Split(string(response), " ")
83+
84+
for _, sp := range splitedResponse {
85+
if strings.HasPrefix(sp, "include:") {
86+
dnsNetblock := strings.Replace(sp, "include:", "", 1)
87+
dnsNetblockList = append(dnsNetblockList, dnsNetblock)
88+
}
89+
}
90+
91+
for len(dnsNetblockList) > 0 {
92+
93+
dnsNetblock := dnsNetblockList[0]
94+
95+
dnsNetblockList[0] = ""
96+
dnsNetblockList = dnsNetblockList[1:len(dnsNetblockList)]
97+
98+
response, err = netblock_request(dnsNetblock)
99+
100+
if err != nil {
101+
return nil, err
102+
}
103+
104+
splitedResponse = strings.Split(string(response), " ")
105+
106+
for _, sp := range splitedResponse {
107+
if strings.HasPrefix(sp, "ip") {
108+
109+
cdrBlock := strings.Split(sp, ":")[1]
110+
cidrBlocks["cidr_blocks"] = append(cidrBlocks["cidr_blocks"], cdrBlock)
111+
112+
if strings.HasPrefix(sp, "ip4") {
113+
cdrBlock := strings.Replace(sp, "ip4:", "", 1)
114+
cidrBlocks["cidr_blocks_ipv4"] = append(cidrBlocks["cidr_blocks_ipv4"], cdrBlock)
115+
116+
} else if strings.HasPrefix(sp, "ip6") {
117+
cdrBlock := strings.Replace(sp, "ip6:", "", 1)
118+
cidrBlocks["cidr_blocks_ipv6"] = append(cidrBlocks["cidr_blocks_ipv6"], cdrBlock)
119+
}
120+
} else if strings.HasPrefix(sp, "include:") {
121+
cidr_block := strings.Replace(sp, "include:", "", 1)
122+
dnsNetblockList = append(dnsNetblockList, cidr_block)
123+
}
124+
}
125+
}
126+
127+
return cidrBlocks, nil
128+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package google
2+
3+
import (
4+
"regexp"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform/helper/resource"
8+
)
9+
10+
func TestAccDataSourceGoogleNetblockIpRanges_basic(t *testing.T) {
11+
resource.Test(t, resource.TestCase{
12+
PreCheck: func() { testAccPreCheck(t) },
13+
Providers: testAccProviders,
14+
Steps: []resource.TestStep{
15+
resource.TestStep{
16+
Config: testAccNetblockIpRangesConfig,
17+
Check: resource.ComposeTestCheckFunc(
18+
resource.TestMatchResourceAttr("data.google_netblock_ip_ranges.some",
19+
"cidr_blocks.#", regexp.MustCompile(("^[1-9]+[0-9]*$"))),
20+
resource.TestMatchResourceAttr("data.google_netblock_ip_ranges.some",
21+
"cidr_blocks.0", regexp.MustCompile("^[0-9./:]+$")),
22+
resource.TestMatchResourceAttr("data.google_netblock_ip_ranges.some",
23+
"cidr_blocks_ipv4.#", regexp.MustCompile(("^[1-9]+[0-9]*$"))),
24+
resource.TestMatchResourceAttr("data.google_netblock_ip_ranges.some",
25+
"cidr_blocks_ipv4.0", regexp.MustCompile("^[0-9./]+$")),
26+
resource.TestMatchResourceAttr("data.google_netblock_ip_ranges.some",
27+
"cidr_blocks_ipv6.#", regexp.MustCompile(("^[1-9]+[0-9]*$"))),
28+
resource.TestMatchResourceAttr("data.google_netblock_ip_ranges.some",
29+
"cidr_blocks_ipv6.0", regexp.MustCompile("^[0-9./:]+$")),
30+
),
31+
},
32+
},
33+
})
34+
}
35+
36+
const testAccNetblockIpRangesConfig = `
37+
data "google_netblock_ip_ranges" "some" {}
38+
`

google/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ func Provider() terraform.ResourceProvider {
8787
"google_iam_policy": dataSourceGoogleIamPolicy(),
8888
"google_kms_secret": dataSourceGoogleKmsSecret(),
8989
"google_folder": dataSourceGoogleFolder(),
90+
"google_netblock_ip_ranges": dataSourceGoogleNetblockIpRanges(),
9091
"google_organization": dataSourceGoogleOrganization(),
9192
"google_service_account": dataSourceGoogleServiceAccount(),
9293
"google_service_account_key": dataSourceGoogleServiceAccountKey(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
layout: "google"
3+
page_title: "Google: google_netblock_ip_ranges"
4+
sidebar_current: "docs-google-datasource-netblock-ip-ranges"
5+
description: |-
6+
Use this data source to get the IP ranges from the sender policy framework (SPF) record of \_cloud-netblocks.googleusercontent.com
7+
---
8+
9+
# google_netblock_ip_ranges
10+
11+
Use this data source to get the IP ranges from the sender policy framework (SPF) record of \_cloud-netblocks.googleusercontent
12+
13+
https://cloud.google.com/compute/docs/faq#where_can_i_find_product_name_short_ip_ranges
14+
15+
## Example Usage
16+
17+
```tf
18+
data "google_netblock_ip_ranges" "netblock" {}
19+
20+
output "cidr_blocks" {
21+
value = "${data.google_netblock_ip_ranges.netblock.cidr_blocks}"
22+
}
23+
24+
output "cidr_blocks_ipv4" {
25+
value = "${data.google_netblock_ip_ranges.netblock.cidr_blocks_ipv4}"
26+
}
27+
28+
output "cidr_blocks_ipv6" {
29+
value = "${data.google_netblock_ip_ranges.netblock.cidr_blocks_ipv6}"
30+
}
31+
```
32+
33+
## Attributes Reference
34+
35+
* `cidr_blocks` - Retrieve list of all CIDR blocks.
36+
37+
* `cidr_blocks_ipv4` - Retrieve list of the IP4 CIDR blocks
38+
39+
* `cidr_blocks_ipv6` - Retrieve list of the IP6 CIDR blocks.

website/google.erb

+3
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@
9191
<li<%= sidebar_current("docs-google-kms-secret") %>>
9292
<a href="/docs/providers/google/d/google_kms_secret.html">google_kms_secret</a>
9393
</li>
94+
<li<%= sidebar_current("docs-google-datasource-netblock-ip-ranges") %>>
95+
<a href="/docs/providers/google/d/datasource_google_netblock_ip_ranges.html">google_netblock_ip_ranges</a>
96+
</li>
9497
<li<%= sidebar_current("docs-google-datasource-organization") %>>
9598
<a href="/docs/providers/google/d/google_organization.html">google_organization</a>
9699
</li>

0 commit comments

Comments
 (0)