From 1b25078f436182cdfc8e88ff9b068d87f8a041d4 Mon Sep 17 00:00:00 2001 From: Modular Magician Date: Wed, 9 Nov 2022 16:11:24 +0000 Subject: [PATCH] Promote container cluster enable_l4_ilb_subsetting from beta to ga (#6767) Signed-off-by: Modular Magician --- .changelog/6767.txt | 3 + google/resource_container_cluster.go | 62 +++++++++++++++++ google/resource_container_cluster_test.go | 83 +++++++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 .changelog/6767.txt diff --git a/.changelog/6767.txt b/.changelog/6767.txt new file mode 100644 index 0000000000..5130a2e61b --- /dev/null +++ b/.changelog/6767.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +container: Added `enable_l4_ilb_subsetting` to GA `google_container_cluster` +``` diff --git a/google/resource_container_cluster.go b/google/resource_container_cluster.go index 14fe5a0f88..febe0a96ce 100644 --- a/google/resource_container_cluster.go +++ b/google/resource_container_cluster.go @@ -96,6 +96,20 @@ func rfc5545RecurrenceDiffSuppress(k, o, n string, d *schema.ResourceData) bool return false } +// Has enable_l4_ilb_subsetting been enabled before? +func isBeenEnabled(_ context.Context, old, new, _ interface{}) bool { + if old == nil || new == nil { + return false + } + + // if subsetting is enabled, but is not now + if old.(bool) && !new.(bool) { + return true + } + + return false +} + func resourceContainerCluster() *schema.Resource { return &schema.Resource{ UseJSONNumber: true, @@ -106,6 +120,7 @@ func resourceContainerCluster() *schema.Resource { CustomizeDiff: customdiff.All( resourceNodeConfigEmptyGuestAccelerator, + customdiff.ForceNewIfChange("enable_l4_ilb_subsetting", isBeenEnabled), containerClusterAutopilotCustomizeDiff, containerClusterNodeVersionRemoveDefaultCustomizeDiff, containerClusterNetworkPolicyEmptyCustomizeDiff, @@ -1384,6 +1399,12 @@ func resourceContainerCluster() *schema.Resource { Description: `Whether Intra-node visibility is enabled for this cluster. This makes same node pod to pod traffic visible for VPC network.`, ConflictsWith: []string{"enable_autopilot"}, }, + "enable_l4_ilb_subsetting": { + Type: schema.TypeBool, + Optional: true, + Description: `Whether L4ILB Subsetting is enabled for this cluster.`, + Default: false, + }, "private_ipv6_google_access": { Type: schema.TypeString, Optional: true, @@ -1591,6 +1612,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er DefaultSnatStatus: expandDefaultSnatStatus(d.Get("default_snat_status")), DatapathProvider: d.Get("datapath_provider").(string), PrivateIpv6GoogleAccess: d.Get("private_ipv6_google_access").(string), + EnableL4ilbSubsetting: d.Get("enable_l4_ilb_subsetting").(bool), DnsConfig: expandDnsConfig(d.Get("dns_config")), }, MasterAuth: expandMasterAuth(d.Get("master_auth")), @@ -1960,6 +1982,9 @@ func resourceContainerClusterRead(d *schema.ResourceData, meta interface{}) erro if err := d.Set("notification_config", flattenNotificationConfig(cluster.NotificationConfig)); err != nil { return err } + if err := d.Set("enable_l4_ilb_subsetting", cluster.NetworkConfig.EnableL4ilbSubsetting); err != nil { + return fmt.Errorf("Error setting enable_l4_ilb_subsetting: %s", err) + } if err := d.Set("cost_management_config", flattenManagementConfig(cluster.CostManagementConfig)); err != nil { return fmt.Errorf("Error setting cost_management_config: %s", err) } @@ -2315,6 +2340,43 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er log.Printf("[INFO] GKE cluster %s Private IPv6 Google Access has been updated", d.Id()) } + if d.HasChange("enable_l4_ilb_subsetting") { + // This field can be changed from false to true but not from false to true. CustomizeDiff handles that check. + enabled := d.Get("enable_l4_ilb_subsetting").(bool) + req := &container.UpdateClusterRequest{ + Update: &container.ClusterUpdate{ + DesiredL4ilbSubsettingConfig: &container.ILBSubsettingConfig{ + Enabled: enabled, + ForceSendFields: []string{"Enabled"}, + }, + }, + } + updateF := func() error { + log.Println("[DEBUG] updating enable_l4_ilb_subsetting") + name := containerClusterFullName(project, location, clusterName) + clusterUpdateCall := config.NewContainerClient(userAgent).Projects.Locations.Clusters.Update(name, req) + if config.UserProjectOverride { + clusterUpdateCall.Header().Add("X-Goog-User-Project", project) + } + op, err := clusterUpdateCall.Do() + if err != nil { + return err + } + + // Wait until it's updated + err = containerOperationWait(config, op, project, location, "updating L4", userAgent, d.Timeout(schema.TimeoutUpdate)) + log.Println("[DEBUG] done updating enable_intranode_visibility") + return err + } + + // Call update serially. + if err := lockedCall(lockKey, updateF); err != nil { + return err + } + + log.Printf("[INFO] GKE cluster %s L4 ILB Subsetting has been updated to %v", d.Id(), enabled) + } + if d.HasChange("cost_management_config") { c := d.Get("cost_management_config") req := &container.UpdateClusterRequest{ diff --git a/google/resource_container_cluster_test.go b/google/resource_container_cluster_test.go index 4b1a8d7a8d..a598cdbf4e 100644 --- a/google/resource_container_cluster_test.go +++ b/google/resource_container_cluster_test.go @@ -323,6 +323,45 @@ func TestAccContainerCluster_withConfidentialNodes(t *testing.T) { }) } +func TestAccContainerCluster_withILBSubsetting(t *testing.T) { + t.Parallel() + + clusterName := fmt.Sprintf("tf-test-cluster-%s", randString(t, 10)) + npName := fmt.Sprintf("tf-test-cluster-nodepool-%s", randString(t, 10)) + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckContainerClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccContainerCluster_disableILBSubSetting(clusterName, npName), + }, + { + ResourceName: "google_container_cluster.confidential_nodes", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccContainerCluster_withILBSubSetting(clusterName, npName), + }, + { + ResourceName: "google_container_cluster.confidential_nodes", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccContainerCluster_disableILBSubSetting(clusterName, npName), + }, + { + ResourceName: "google_container_cluster.confidential_nodes", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccContainerCluster_withMasterAuthConfig_NoCert(t *testing.T) { t.Parallel() @@ -3150,6 +3189,50 @@ resource "google_container_cluster" "confidential_nodes" { `, clusterName, npName) } +func testAccContainerCluster_withILBSubSetting(clusterName string, npName string) string { + return fmt.Sprintf(` +resource "google_container_cluster" "confidential_nodes" { + name = "%s" + location = "us-central1-a" + release_channel { + channel = "RAPID" + } + + node_pool { + name = "%s" + initial_node_count = 1 + node_config { + machine_type = "e2-medium" + } + } + + enable_l4_ilb_subsetting = true +} +`, clusterName, npName) +} + +func testAccContainerCluster_disableILBSubSetting(clusterName string, npName string) string { + return fmt.Sprintf(` +resource "google_container_cluster" "confidential_nodes" { + name = "%s" + location = "us-central1-a" + release_channel { + channel = "RAPID" + } + + node_pool { + name = "%s" + initial_node_count = 1 + node_config { + machine_type = "e2-medium" + } + } + + enable_l4_ilb_subsetting = false +} +`, clusterName, npName) +} + func testAccContainerCluster_withNetworkPolicyEnabled(clusterName string) string { return fmt.Sprintf(` resource "google_container_cluster" "with_network_policy_enabled" {