From cf7a0dc40c05a6f3d53d768e980cce0773f8a403 Mon Sep 17 00:00:00 2001 From: Abhijeet Dargude <144316709+dargudear-google@users.noreply.github.com> Date: Tue, 4 Jun 2024 00:05:44 +0530 Subject: [PATCH] Add support secret manager csi addon in beta (#10841) --- .../resource_container_cluster.go.erb | 103 ++++++++++++++++++ .../resource_container_cluster_test.go.erb | 88 +++++++++++++++ .../docs/r/container_cluster.html.markdown | 8 ++ 3 files changed, 199 insertions(+) diff --git a/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb b/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb index 38028f27021d..85808489e5d6 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb @@ -1501,6 +1501,24 @@ func ResourceContainerCluster() *schema.Resource { }, }, <% end -%> +<% unless version == "ga" -%> + "secret_manager_config": { + Type: schema.TypeList, + Optional: true, + Description: `Configuration for the Secret Manager feature.`, + MaxItems: 1, + DiffSuppressFunc: SecretManagerCfgSuppress, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + Description: `Enable the Secret manager csi component.`, + }, + }, + }, + }, +<% end -%> "project": { Type: schema.TypeString, @@ -2273,6 +2291,9 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er IpAllocationPolicy: ipAllocationBlock, <% unless version == "ga" -%> PodSecurityPolicyConfig: expandPodSecurityPolicyConfig(d.Get("pod_security_policy_config")), +<% end -%> +<% unless version == "ga" -%> + SecretManagerConfig: expandSecretManagerConfig(d.Get("secret_manager_config")), <% end -%> Autoscaling: expandClusterAutoscaling(d.Get("cluster_autoscaling"), d), BinaryAuthorization: expandBinaryAuthorization(d.Get("binary_authorization")), @@ -2915,6 +2936,10 @@ func resourceContainerClusterRead(d *schema.ResourceData, meta interface{}) erro if err := d.Set("cluster_telemetry", flattenClusterTelemetry(cluster.ClusterTelemetry)); err != nil { return err } + + if err := d.Set("secret_manager_config", flattenSecretManagerConfig(cluster.SecretManagerConfig)); err != nil { + return err + } <% end -%> if err := d.Set("resource_labels", cluster.ResourceLabels); err != nil { @@ -3901,6 +3926,35 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er } <% end -%> +<% unless version == 'ga' -%> + if d.HasChange("secret_manager_config") { + c := d.Get("secret_manager_config") + req := &container.UpdateClusterRequest{ + Update: &container.ClusterUpdate{ + DesiredSecretManagerConfig: expandSecretManagerConfig(c), + }, + } + + updateF := func() error { + 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 + return ContainerOperationWait(config, op, project, location, "updating secret manager csi driver config", userAgent, d.Timeout(schema.TimeoutUpdate)) + } + if err := transport_tpg.LockedCall(lockKey, updateF); err != nil { + return err + } + log.Printf("[INFO] GKE cluster %s secret manager csi add-on has been updated", d.Id()) + } +<% end -%> + if d.HasChange("workload_identity_config") { // Because GKE uses a non-RESTful update function, when removing the // feature you need to specify a fairly full request body or it fails: @@ -5274,6 +5328,21 @@ func expandPodSecurityPolicyConfig(configured interface{}) *container.PodSecurit } <% end -%> +<% unless version == 'ga' -%> +func expandSecretManagerConfig(configured interface{}) *container.SecretManagerConfig { + l := configured.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil + } + + config := l[0].(map[string]interface{}) + return &container.SecretManagerConfig{ + Enabled: config["enabled"].(bool), + ForceSendFields: []string{"Enabled"}, + } +} +<% end -%> + func expandDefaultMaxPodsConstraint(v interface{}) *container.MaxPodsConstraint { if v == nil { return nil @@ -6140,6 +6209,24 @@ func flattenPodSecurityPolicyConfig(c *container.PodSecurityPolicyConfig) []map[ <% end -%> +<% unless version == 'ga' -%> +func flattenSecretManagerConfig(c *container.SecretManagerConfig) []map[string]interface{} { + if c == nil { + return []map[string]interface{}{ + { + "enabled": false, + }, + } + } + return []map[string]interface{}{ + { + "enabled": c.Enabled, + }, + } +} + +<% end -%> + func flattenResourceUsageExportConfig(c *container.ResourceUsageExportConfig) []map[string]interface{} { if c == nil { return nil @@ -6589,6 +6676,22 @@ func podSecurityPolicyCfgSuppress(k, old, new string, r *schema.ResourceData) bo } <% end -%> +<% unless version == 'ga' -%> +func SecretManagerCfgSuppress(k, old, new string, r *schema.ResourceData) bool { + if k == "secret_manager_config.#" && old == "1" && new == "0" { + if v, ok := r.GetOk("secret_manager_config"); ok { + cfgList := v.([]interface{}) + if len(cfgList) > 0 { + d := cfgList[0].(map[string]interface{}) + // Suppress if old value was {enabled == false} + return !d["enabled"].(bool) + } + } + } + return false +} +<% end -%> + func containerClusterNetworkPolicyDiffSuppress(k, old, new string, r *schema.ResourceData) bool { // if network_policy configuration is empty, we store it as populated and enabled=false, and // provider=PROVIDER_UNSPECIFIED, in the case that it was previously stored with this state, diff --git a/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb b/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb index a1b47beaa7d2..e8cad2c7d0e0 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb @@ -3223,6 +3223,59 @@ func TestAccContainerCluster_withIdentityServiceConfig(t *testing.T) { }) } +<% unless version == 'ga' -%> +func TestAccContainerCluster_withSecretManagerConfig(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_basic(clusterName, networkName, subnetworkName), + }, + { + ResourceName: "google_container_cluster.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection"}, + }, + { + Config: testAccContainerCluster_withSecretManagerConfigEnabled(clusterName, networkName, subnetworkName), + }, + { + ResourceName: "google_container_cluster.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection"}, + }, + { + Config: testAccContainerCluster_withSecretManagerConfigUpdated(clusterName, networkName, subnetworkName), + }, + { + ResourceName: "google_container_cluster.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection"}, + }, + { + Config: testAccContainerCluster_basic(clusterName, networkName, subnetworkName), + }, + { + ResourceName: "google_container_cluster.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection"}, + }, + }, + }) +} +<% end -%> + func TestAccContainerCluster_withLoggingConfig(t *testing.T) { t.Parallel() @@ -9227,6 +9280,41 @@ resource "google_container_cluster" "primary" { `, name, networkName, subnetworkName) } +<% unless version == 'ga' -%> +func testAccContainerCluster_withSecretManagerConfigEnabled(name, networkName, subnetworkName string) string { + return fmt.Sprintf(` +resource "google_container_cluster" "primary" { + name = "%s" + location = "us-central1-a" + initial_node_count = 1 + secret_manager_config { + enabled = true + } + deletion_protection = false + network = "%s" + subnetwork = "%s" +} +`, name, networkName, subnetworkName) +} + +func testAccContainerCluster_withSecretManagerConfigUpdated(name, networkName, subnetworkName string) string { + return fmt.Sprintf(` +resource "google_container_cluster" "primary" { + name = "%s" + location = "us-central1-a" + initial_node_count = 1 + + secret_manager_config { + enabled = false + } + deletion_protection = false + network = "%s" + subnetwork = "%s" +} +`, name, networkName, subnetworkName) +} +<% end -%> + func testAccContainerCluster_withLoggingConfigEnabled(name, networkName, subnetworkName string) string { return fmt.Sprintf(` resource "google_container_cluster" "primary" { 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 3b7c6f6d39cf..94443c5c1d4a 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 @@ -292,6 +292,10 @@ region are guaranteed to support the same version. [PodSecurityPolicy](https://cloud.google.com/kubernetes-engine/docs/how-to/pod-security-policies) feature. Structure is [documented below](#nested_pod_security_policy_config). +* `secret_manager_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Configuration for the + [SecretManagerConfig](https://cloud.google.com/secret-manager/docs/secret-manager-managed-csi-component) feature. + Structure is [documented below](#nested_secret_manager_config). + * `authenticator_groups_config` - (Optional) Configuration for the [Google Groups for GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control#groups-setup-gsuite) feature. Structure is [documented below](#nested_authenticator_groups_config). @@ -1106,6 +1110,10 @@ notification_config { * `enabled` (Required) - Enable the PodSecurityPolicy controller for this cluster. If enabled, pods must be valid under a PodSecurityPolicy to be created. +The `secret_manager_config` block supports: + +* `enabled` (Required) - Enable the Secret Manager add-on for this cluster. + The `private_cluster_config` block supports: * `enable_private_nodes` (Optional) - Enables the private cluster feature,