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,