Skip to content

Commit

Permalink
Exposes filtered CIDRs ranges for default domains
Browse files Browse the repository at this point in the history
Per https://cloud.google.com/vpc/docs/configure-private-google-access#ip-addr-defaults :

> The IP addresses used by the default domains for Google APIs and services fit within
> the list of ranges computed by taking away all ranges in cloud.json from those in
> goog.json. The following example shows you how to get this range using Python.

`terraform-provider-google` was offering access to both `goog.json`
(`google-netblocks`) and `cloud.json` (`cloud-netblocks`) but not to
that useful subset of addresses in goog.json but not in cloud.json,
which is hard to process otherwise (using only terraform native transforms).

This mirrors the above doc's python script's behavior.
  • Loading branch information
bpineau committed Jun 11, 2021
1 parent ef1c106 commit ccf95c9
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 2 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ require (
google.golang.org/api v0.46.0
google.golang.org/genproto v0.0.0-20210503173045-b96a97608f20 // indirect
google.golang.org/grpc v1.38.0
gopkg.in/netaddr.v1 v1.5.1
)

go 1.16
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,7 @@ github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
Expand Down Expand Up @@ -1329,6 +1330,8 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/netaddr.v1 v1.5.1 h1:lnD7O5z5JnrRu6mWBOd59NVgLVWM1+StKRu2uFJInDM=
gopkg.in/netaddr.v1 v1.5.1/go.mod h1:wwHEDCASVBPRL/Fw3064+E4o4GXyQkQ66WWchZTX/3g=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
Expand Down
71 changes: 69 additions & 2 deletions google/data_source_google_netblock_ip_ranges.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@ import (
"fmt"
"io/ioutil"
"net/http"
"sort"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"gopkg.in/netaddr.v1"
)

const (
CLOUD_NETBLOCK_URL = "https://www.gstatic.com/ipranges/cloud.json"
GOOGLE_NETBLOCK_URL = "https://www.gstatic.com/ipranges/goog.json"
)

type googRanges struct {
Expand Down Expand Up @@ -58,7 +65,6 @@ func dataSourceGoogleNetblockIpRangesRead(d *schema.ResourceData, meta interface
// Dynamic ranges
case "cloud-netblocks":
// https://cloud.google.com/compute/docs/faq#find_ip_range
const CLOUD_NETBLOCK_URL = "https://www.gstatic.com/ipranges/cloud.json"
CidrBlocks, err := getCidrBlocksFromUrl(CLOUD_NETBLOCK_URL)

if err != nil {
Expand All @@ -75,12 +81,36 @@ func dataSourceGoogleNetblockIpRangesRead(d *schema.ResourceData, meta interface
}
case "google-netblocks":
// https://cloud.google.com/vpc/docs/configure-private-google-access?hl=en#ip-addr-defaults
const GOOGLE_NETBLOCK_URL = "https://www.gstatic.com/ipranges/goog.json"
CidrBlocks, err := getCidrBlocksFromUrl(GOOGLE_NETBLOCK_URL)

if err != nil {
return err
}

if err := d.Set("cidr_blocks", CidrBlocks["cidr_blocks"]); err != nil {
return fmt.Errorf("Error setting cidr_blocks: %s", err)
}
if err := d.Set("cidr_blocks_ipv4", CidrBlocks["cidr_blocks_ipv4"]); err != nil {
return fmt.Errorf("Error setting cidr_blocks_ipv4: %s", err)
}
if err := d.Set("cidr_blocks_ipv6", CidrBlocks["cidr_blocks_ipv6"]); err != nil {
return fmt.Errorf("Error setting cidr_blocks_ipv6: %s", err)
}
case "default-domains-netblocks":
// https://cloud.google.com/vpc/docs/configure-private-google-access#ip-addr-defaults
googBlocks, err := getCidrBlocksFromUrl(GOOGLE_NETBLOCK_URL)
if err != nil {
return err
}
cloudBlocks, err := getCidrBlocksFromUrl(CLOUD_NETBLOCK_URL)
if err != nil {
return err
}
CidrBlocks, err := getCidrsDifference(googBlocks, cloudBlocks)
if err != nil {
return err
}

if err := d.Set("cidr_blocks", CidrBlocks["cidr_blocks"]); err != nil {
return fmt.Errorf("Error setting cidr_blocks: %s", err)
}
Expand Down Expand Up @@ -199,3 +229,40 @@ func getCidrBlocksFromUrl(url string) (map[string][]string, error) {

return cidrBlocks, nil
}

// select or split CIDRs ranges from "reference" set, so the result has no overlap with ranges in "excluded"
func getCidrsDifference(reference, excluded map[string][]string) (map[string][]string, error) {
result := make(map[string][]string)

for blockName := range reference {
referenceSet := netaddr.IPSet{}
for _, cidr := range reference[blockName] {
net, err := netaddr.ParseNet(cidr)
if err != nil {
return result, err
}
referenceSet.InsertNet(net)
}

excludedSet := netaddr.IPSet{}
for _, cidr := range excluded[blockName] {
net, err := netaddr.ParseNet(cidr)
if err != nil {
return result, err
}
excludedSet.InsertNet(net)
}

delta := referenceSet.Difference(&excludedSet)

var difference []string
for _, cidr := range delta.GetNetworks() {
difference = append(difference, cidr.String())
}
sort.Strings(difference)

result[blockName] = difference
}

return result, nil
}
24 changes: 24 additions & 0 deletions google/data_source_google_netblock_ip_ranges_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,24 @@ func TestAccDataSourceGoogleNetblockIpRanges_basic(t *testing.T) {
"cidr_blocks_ipv6.0", regexp.MustCompile("^(?:[0-9a-fA-F]{1,4}:){1,2}.*/[0-9]{1,3}$")),
),
},
{
Config: testAccNetblockIpRangesConfig_defaultdomains,
Check: resource.ComposeTestCheckFunc(
// Default domains netblocks
resource.TestMatchResourceAttr("data.google_netblock_ip_ranges.defaultdomains",
"cidr_blocks.#", regexp.MustCompile(("^[1-9]+[0-9]*$"))),
resource.TestMatchResourceAttr("data.google_netblock_ip_ranges.defaultdomains",
"cidr_blocks.0", regexp.MustCompile("^(?:[0-9a-fA-F./:]{1,4}){1,2}.*/[0-9]{1,3}$")),
resource.TestMatchResourceAttr("data.google_netblock_ip_ranges.defaultdomains",
"cidr_blocks_ipv4.#", regexp.MustCompile(("^[1-9]+[0-9]*$"))),
resource.TestMatchResourceAttr("data.google_netblock_ip_ranges.defaultdomains",
"cidr_blocks_ipv4.0", regexp.MustCompile("^(?:[0-9]{1,3}.){3}[0-9]{1,3}/[0-9]{1,2}$")),
resource.TestMatchResourceAttr("data.google_netblock_ip_ranges.defaultdomains",
"cidr_blocks_ipv6.#", regexp.MustCompile(("^[1-9]+[0-9]*$"))),
resource.TestMatchResourceAttr("data.google_netblock_ip_ranges.defaultdomains",
"cidr_blocks_ipv6.0", regexp.MustCompile("^(?:[0-9a-fA-F]{1,4}:){1,2}.*/[0-9]{1,3}$")),
),
},
{
Config: testAccNetblockIpRangesConfig_restricted,
Check: resource.ComposeTestCheckFunc(
Expand Down Expand Up @@ -140,6 +158,12 @@ data "google_netblock_ip_ranges" "google" {
}
`

const testAccNetblockIpRangesConfig_defaultdomains = `
data "google_netblock_ip_ranges" "defaultdomains" {
range_type = "default-domains-netblocks"
}
`

const testAccNetblockIpRangesConfig_restricted = `
data "google_netblock_ip_ranges" "restricted" {
range_type = "restricted-googleapis"
Expand Down
2 changes: 2 additions & 0 deletions website/docs/d/netblock_ip_ranges.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ The following arguments are supported:

* `google-netblocks` - Corresponds to IP addresses used for Google services. [More details.](https://cloud.google.com/compute/docs/faq#where_can_i_find_product_name_short_ip_ranges)

* `default-domains-netblocks` - Correspond to the IP addresses used by the default domains for Google APIs and services. Those are IPs addresses in `google-netblocks` but not in `cloud-netblocks`. [More details.](https://cloud.google.com/vpc/docs/configure-private-google-access#ip-addr-defaults)

* `restricted-googleapis` - Corresponds to the IP addresses used for Private Google Access only for services that support VPC Service Controls API access. [More details.](https://cloud.google.com/vpc/docs/private-access-options#domain-vips)

* `private-googleapis` - Corresponds to the IP addresses used for Private Google Access for services that do not support VPC Service Controls. [More details.](https://cloud.google.com/vpc/docs/private-access-options#domain-vips)
Expand Down

0 comments on commit ccf95c9

Please sign in to comment.