diff --git a/mmv1/third_party/terraform/services/container/resource_container_cluster.go.tmpl b/mmv1/third_party/terraform/services/container/resource_container_cluster.go.tmpl index f718fa386fb3..4990fb8bd440 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_cluster.go.tmpl +++ b/mmv1/third_party/terraform/services/container/resource_container_cluster.go.tmpl @@ -1874,6 +1874,22 @@ func ResourceContainerCluster() *schema.Resource { }, }, }, + "network_tier_config": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: `Used to determine the default network tier for external IP addresses on cluster resources, such as node pools and load balancers.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "network_tier": { + Type: schema.TypeString, + Required: true, + Description: `Network tier configuration.`, + }, + }, + }, + }, }, }, }, @@ -4359,6 +4375,24 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er log.Printf("[INFO] GKE cluster %s's AutoIpamConfig has been updated", d.Id()) } + if d.HasChange("ip_allocation_policy.0.network_tier_config.0.network_tier") { + req := &container.UpdateClusterRequest{ + Update: &container.ClusterUpdate{ + DesiredNetworkTierConfig: &container.NetworkTierConfig{ + NetworkTier: d.Get("ip_allocation_policy.0.network_tier_config.0.network_tier").(string), + }, + }, + } + + updateF := updateFunc(req, "updating NetworkTierConfig") + // Call update serially. + if err := transport_tpg.LockedCall(lockKey, updateF); err != nil { + return err + } + + log.Printf("[INFO] GKE cluster %s's NetworkTierConfig has been updated", d.Id()) + } + if n, ok := d.GetOk("node_pool.#"); ok { for i := 0; i < n.(int); i++ { nodePoolInfo, err := extractNodePoolInformationFromCluster(d, config, clusterName) @@ -5610,9 +5644,22 @@ func expandIPAllocationPolicy(configured interface{}, d *schema.ResourceData, ne StackType: stackType, PodCidrOverprovisionConfig: expandPodCidrOverprovisionConfig(config["pod_cidr_overprovision_config"]), AutoIpamConfig: expandAutoIpamConfig(config["auto_ipam_config"]), + NetworkTierConfig: expandNetworkTierConfig(config["network_tier_config"]), }, additionalIpRangesConfigs, nil } +func expandNetworkTierConfig(configured interface{}) *container.NetworkTierConfig { + l := configured.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil + } + + config := l[0].(map[string]interface{}) + return &container.NetworkTierConfig{ + NetworkTier: config["network_tier"].(string), + } +} + func expandAutoIpamConfig(configured interface{}) *container.AutoIpamConfig { l, ok := configured.([]interface{}) if !ok || len(l) == 0 || l[0] == nil { @@ -7268,6 +7315,18 @@ func flattenAdditionalIpRangesConfigs(c []*container.AdditionalIPRangesConfig) [ return outRanges } +func flattenNetworkTierConfig(ntc *container.NetworkTierConfig) []map[string]interface{} { + if ntc == nil { + return nil + } + + return []map[string]interface{}{ + { + "network_tier": ntc.NetworkTier, + }, + } +} + func flattenIPAllocationPolicy(c *container.Cluster, d *schema.ResourceData, config *transport_tpg.Config) ([]map[string]interface{}, error) { // If IP aliasing isn't enabled, none of the values in this block can be set. if c == nil || c.IpAllocationPolicy == nil || !c.IpAllocationPolicy.UseIpAliases { @@ -7300,6 +7359,7 @@ func flattenIPAllocationPolicy(c *container.Cluster, d *schema.ResourceData, con "additional_pod_ranges_config": flattenAdditionalPodRangesConfig(c.IpAllocationPolicy), "additional_ip_ranges_config": flattenAdditionalIpRangesConfigs(p.AdditionalIpRangesConfigs), "auto_ipam_config": flattenAutoIpamConfig(p.AutoIpamConfig), + "network_tier_config": flattenNetworkTierConfig(p.NetworkTierConfig), }, }, nil } diff --git a/mmv1/third_party/terraform/services/container/resource_container_cluster_meta.yaml.tmpl b/mmv1/third_party/terraform/services/container/resource_container_cluster_meta.yaml.tmpl index 7ddec0386fd9..e934645679e4 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_cluster_meta.yaml.tmpl +++ b/mmv1/third_party/terraform/services/container/resource_container_cluster_meta.yaml.tmpl @@ -165,6 +165,7 @@ fields: - api_field: 'ipAllocationPolicy.autoIpamConfig.enabled' - api_field: 'ipAllocationPolicy.clusterIpv4CidrBlock' - api_field: 'ipAllocationPolicy.clusterSecondaryRangeName' + - api_field: 'ipAllocationPolicy.networkTierConfig.networkTier' - field: 'ip_allocation_policy.pod_cidr_overprovision_config.disabled' api_field: 'ip_allocation_policy.pod_cidr_overprovision_config.disable' - api_field: 'ipAllocationPolicy.servicesIpv4CidrBlock' diff --git a/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.tmpl b/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.tmpl index 9b3ba6d023e9..5c08888df2df 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.tmpl +++ b/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.tmpl @@ -6868,6 +6868,105 @@ func TestAccContainerCluster_withCpuCfsQuotaPool(t *testing.T) { }) } +func TestAccContainerCluster_network_tier_config(t *testing.T) { + t.Parallel() + + clusterName := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10)) + networkName := acctest.BootstrapSharedTestNetwork(t, "gke-cluster") + subnetworkName := acctest.BootstrapSubnet(t, "gke-cluster", networkName) + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckContainerClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccContainerCluster_network_tier_config_none(clusterName, networkName, subnetworkName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_container_cluster.primary", "ip_allocation_policy.0.network_tier_config.0.network_tier", "NETWORK_TIER_DEFAULT"), + ), + }, + { + ResourceName: "google_container_cluster.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection"}, + }, + { + Config: testAccContainerCluster_network_tier_config(clusterName, networkName, subnetworkName, "NETWORK_TIER_PREMIUM"), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("google_container_cluster.primary", plancheck.ResourceActionUpdate), + }, + }, + }, + { + ResourceName: "google_container_cluster.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection"}, + }, + { + Config: testAccContainerCluster_network_tier_config(clusterName, networkName, subnetworkName, "NETWORK_TIER_STANDARD"), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("google_container_cluster.primary", plancheck.ResourceActionUpdate), + }, + }, + }, + { + ResourceName: "google_container_cluster.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection"}, + }, + }, + }) +} + +func testAccContainerCluster_network_tier_config(clusterName, networkName, subnetworkName, networkTier string) string { + return fmt.Sprintf(` +resource "google_container_cluster" "primary" { + name = "%s" + location = "us-central1-a" + initial_node_count = 2 + dns_config { + cluster_dns = "CLOUD_DNS" + } + + network = "%s" + subnetwork = "%s" + + deletion_protection = false + + ip_allocation_policy { + network_tier_config { + network_tier = "%s" + } + } +}`, clusterName, networkName, subnetworkName, networkTier) +} + +func testAccContainerCluster_network_tier_config_none(clusterName, networkName, subnetworkName string) string { + return fmt.Sprintf(` +resource "google_container_cluster" "primary" { + name = "%s" + location = "us-central1-a" + initial_node_count = 2 + dns_config { + cluster_dns = "CLOUD_DNS" + } + + network = "%s" + subnetwork = "%s" + + deletion_protection = false + + ip_allocation_policy { + } +}`, clusterName, networkName, subnetworkName) +} + func testAccContainerCluster_masterAuthorizedNetworksDisabled(t *testing.T, resource_name string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resource_name] diff --git a/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown b/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown index e1e3f1339df0..7db9f9d474f1 100644 --- a/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown @@ -831,6 +831,8 @@ Structure is [documented below](#nested_additional_ip_ranges_config). * `auto_ipam_config` - (Optional) All the information related to Auto IPAM. Structure is [documented below](#nested_auto_ipam_config) +* `network_tier_config` - (Optional) Contains network tier information. Structure is [documented below](#nested_network_tier_config) + The auto ipam config supports: * `enabled` - (Required) The flag that enables Auto IPAM on this cluster. @@ -847,6 +849,14 @@ Structure is [documented below](#nested_additional_ip_ranges_config). * `pod_ipv4_range_names`- (Required) List of secondary ranges names within this subnetwork that can be used for pod IPs. +The `network_tier_config` block supports: + +* `network_tier` - (Required) Network tier configuration. + Accepted values are: + * `NETWORK_TIER_DEFAULT`: (Default) Use project-level configuration. + * `NETWORK_TIER_PREMIUM`: Premium network tier. + * `NETWORK_TIER_STANDARD`: Standard network tier. + The `master_auth` block supports: