diff --git a/mmv1/third_party/terraform/go.mod b/mmv1/third_party/terraform/go.mod index bb0b2e89a736..e4e0f48fe054 100644 --- a/mmv1/third_party/terraform/go.mod +++ b/mmv1/third_party/terraform/go.mod @@ -97,6 +97,7 @@ require ( go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect + go4.org/netipx v0.0.0-20231129151722-fdeea329fbba golang.org/x/crypto v0.22.0 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/sync v0.7.0 // indirect diff --git a/mmv1/third_party/terraform/go.mod.erb b/mmv1/third_party/terraform/go.mod.erb index a219a8b2da06..253dea2bebb9 100644 --- a/mmv1/third_party/terraform/go.mod.erb +++ b/mmv1/third_party/terraform/go.mod.erb @@ -98,6 +98,7 @@ require ( go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect + go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect golang.org/x/crypto v0.22.0 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/sync v0.7.0 // indirect diff --git a/mmv1/third_party/terraform/go.sum b/mmv1/third_party/terraform/go.sum index 0c641ff41dd8..9a5f52c621b1 100644 --- a/mmv1/third_party/terraform/go.sum +++ b/mmv1/third_party/terraform/go.sum @@ -287,6 +287,8 @@ go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= +go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_netblock_ip_ranges.go b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_netblock_ip_ranges.go index cec7d95cdc86..4a4f9ceebd3d 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_netblock_ip_ranges.go +++ b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_netblock_ip_ranges.go @@ -5,8 +5,11 @@ import ( "fmt" "io/ioutil" "net/http" + "net/netip" + "sort" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "go4.org/netipx" ) type googRanges struct { @@ -20,6 +23,11 @@ type prefixes struct { Ipv6Prefix string `json:"ipv6Prefix"` } +const ( + CLOUD_NETBLOCK_URL = "https://www.gstatic.com/ipranges/cloud.json" + GOOGLE_NETBLOCK_URL = "https://www.gstatic.com/ipranges/goog.json" +) + func DataSourceGoogleNetblockIpRanges() *schema.Resource { return &schema.Resource{ Read: dataSourceGoogleNetblockIpRangesRead, @@ -58,7 +66,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 { @@ -75,12 +82,35 @@ 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 + googleBlocks, err := getCidrBlocksFromUrl(GOOGLE_NETBLOCK_URL) + if err != nil { + return err + } + cloudBlocks, err := getCidrBlocksFromUrl(CLOUD_NETBLOCK_URL) + if err != nil { + return err + } + CidrBlocks, err := getCidrsDifference(googleBlocks, 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) } @@ -199,3 +229,42 @@ func getCidrBlocksFromUrl(url string) (map[string][]string, error) { return cidrBlocks, nil } + +func getCidrsDifference(reference, excluded map[string][]string) (map[string][]string, error) { + result := make(map[string][]string) + + for blockName := range reference { + var ipSetBuilder netipx.IPSetBuilder + for _, cidr := range reference[blockName] { + net, err := netip.ParsePrefix(cidr) + if err != nil { + return result, err + } + ipSetBuilder.AddPrefix(net) + } + + for _, cidr := range excluded[blockName] { + net, err := netip.ParsePrefix(cidr) + if err != nil { + return result, err + } + ipSetBuilder.RemovePrefix(net) + } + + ipSet, err := ipSetBuilder.IPSet() + if err != nil { + return result, err + } + + var ipRangeStrings []string + for _, ipRange := range ipSet.Prefixes() { + ipRangeStrings = append(ipRangeStrings, ipRange.String()) + } + + sort.Strings(ipRangeStrings) + + result[blockName] = ipRangeStrings + } + + return result, nil +} diff --git a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_netblock_ip_ranges_test.go b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_netblock_ip_ranges_test.go index 035f1b071087..8c81f5cedc59 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_netblock_ip_ranges_test.go +++ b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_netblock_ip_ranges_test.go @@ -49,6 +49,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( @@ -141,6 +159,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"