Skip to content

Commit

Permalink
Add DeletionProtectionEnabled to Redis Cluster (#10367) (#7995)
Browse files Browse the repository at this point in the history
[upstream:820e403355ea94ddbf666b9327231eb35bbfd5d8]

Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored Aug 16, 2024
1 parent 651e313 commit 6ccc989
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 52 deletions.
3 changes: 3 additions & 0 deletions .changelog/10367.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
redis: added a `deletion_protection_enabled` field with a default value of `true` to the `google_redis_cluster` resource
```
35 changes: 35 additions & 0 deletions google-beta/services/redis/resource_redis_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ projects/{network_project_id_or_number}/global/networks/{network_id}.`,
Description: `Optional. The authorization mode of the Redis cluster. If not provided, auth feature is disabled for the cluster. Default value: "AUTH_MODE_DISABLED" Possible values: ["AUTH_MODE_UNSPECIFIED", "AUTH_MODE_IAM_AUTH", "AUTH_MODE_DISABLED"]`,
Default: "AUTH_MODE_DISABLED",
},
"deletion_protection_enabled": {
Type: schema.TypeBool,
Optional: true,
Description: `Optional. Indicates if the cluster is deletion protected or not.
If the value if set to true, any delete cluster operation will fail.
Default value is true.`,
Default: true,
},
"node_type": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -347,6 +355,12 @@ func resourceRedisClusterCreate(d *schema.ResourceData, meta interface{}) error
} else if v, ok := d.GetOkExists("shard_count"); !tpgresource.IsEmptyValue(reflect.ValueOf(shardCountProp)) && (ok || !reflect.DeepEqual(v, shardCountProp)) {
obj["shardCount"] = shardCountProp
}
deletionProtectionEnabledProp, err := expandRedisClusterDeletionProtectionEnabled(d.Get("deletion_protection_enabled"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("deletion_protection_enabled"); !tpgresource.IsEmptyValue(reflect.ValueOf(deletionProtectionEnabledProp)) && (ok || !reflect.DeepEqual(v, deletionProtectionEnabledProp)) {
obj["deletionProtectionEnabled"] = deletionProtectionEnabledProp
}
redisConfigsProp, err := expandRedisClusterRedisConfigs(d.Get("redis_configs"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -502,6 +516,9 @@ func resourceRedisClusterRead(d *schema.ResourceData, meta interface{}) error {
if err := d.Set("shard_count", flattenRedisClusterShardCount(res["shardCount"], d, config)); err != nil {
return fmt.Errorf("Error reading Cluster: %s", err)
}
if err := d.Set("deletion_protection_enabled", flattenRedisClusterDeletionProtectionEnabled(res["deletionProtectionEnabled"], d, config)); err != nil {
return fmt.Errorf("Error reading Cluster: %s", err)
}
if err := d.Set("redis_configs", flattenRedisClusterRedisConfigs(res["redisConfigs"], d, config)); err != nil {
return fmt.Errorf("Error reading Cluster: %s", err)
}
Expand Down Expand Up @@ -543,6 +560,12 @@ func resourceRedisClusterUpdate(d *schema.ResourceData, meta interface{}) error
} else if v, ok := d.GetOkExists("shard_count"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, shardCountProp)) {
obj["shardCount"] = shardCountProp
}
deletionProtectionEnabledProp, err := expandRedisClusterDeletionProtectionEnabled(d.Get("deletion_protection_enabled"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("deletion_protection_enabled"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, deletionProtectionEnabledProp)) {
obj["deletionProtectionEnabled"] = deletionProtectionEnabledProp
}
redisConfigsProp, err := expandRedisClusterRedisConfigs(d.Get("redis_configs"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -571,6 +594,10 @@ func resourceRedisClusterUpdate(d *schema.ResourceData, meta interface{}) error
updateMask = append(updateMask, "shardCount")
}

if d.HasChange("deletion_protection_enabled") {
updateMask = append(updateMask, "deletionProtectionEnabled")
}

if d.HasChange("redis_configs") {
updateMask = append(updateMask, "redisConfigs")
}
Expand Down Expand Up @@ -958,6 +985,10 @@ func flattenRedisClusterShardCount(v interface{}, d *schema.ResourceData, config
return v // let terraform core handle it otherwise
}

func flattenRedisClusterDeletionProtectionEnabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenRedisClusterRedisConfigs(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
Expand Down Expand Up @@ -1042,6 +1073,10 @@ func expandRedisClusterShardCount(v interface{}, d tpgresource.TerraformResource
return v, nil
}

func expandRedisClusterDeletionProtectionEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandRedisClusterRedisConfigs(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) {
if v == nil {
return map[string]string{}, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ func TestAccRedisCluster_redisClusterHaExample(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"prevent_destroy": false,
"random_suffix": acctest.RandString(t, 10),
"deletion_protection_enabled": false,
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
Expand Down Expand Up @@ -72,16 +72,14 @@ resource "google_redis_cluster" "cluster-ha" {
redis_configs = {
maxmemory-policy = "volatile-ttl"
}
deletion_protection_enabled = false
zone_distribution_config {
mode = "MULTI_ZONE"
}
depends_on = [
google_network_connectivity_service_connection_policy.default
]
lifecycle {
prevent_destroy = %{prevent_destroy}
}
}
resource "google_network_connectivity_service_connection_policy" "default" {
Expand Down Expand Up @@ -113,8 +111,8 @@ func TestAccRedisCluster_redisClusterHaSingleZoneExample(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"prevent_destroy": false,
"random_suffix": acctest.RandString(t, 10),
"deletion_protection_enabled": false,
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
Expand Down Expand Up @@ -148,13 +146,11 @@ resource "google_redis_cluster" "cluster-ha-single-zone" {
mode = "SINGLE_ZONE"
zone = "us-central1-f"
}
deletion_protection_enabled = false
depends_on = [
google_network_connectivity_service_connection_policy.default
]
lifecycle {
prevent_destroy = %{prevent_destroy}
}
}
resource "google_network_connectivity_service_connection_policy" "default" {
Expand Down
97 changes: 63 additions & 34 deletions google-beta/services/redis/resource_redis_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
)

func TestAccRedisCluster_createClusterWithNodeType(t *testing.T) {

t.Parallel()

name := fmt.Sprintf("tf-test-%d", acctest.RandInt(t))
Expand All @@ -23,7 +24,7 @@ func TestAccRedisCluster_createClusterWithNodeType(t *testing.T) {
Steps: []resource.TestStep{
{
// create cluster with replica count 1
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, preventDestroy: true, nodeType: "REDIS_STANDARD_SMALL", zoneDistributionMode: "MULTI_ZONE"}),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, deletionProtectionEnabled: true, nodeType: "REDIS_STANDARD_SMALL", zoneDistributionMode: "MULTI_ZONE"}),
},
{
ResourceName: "google_redis_cluster.test",
Expand All @@ -33,7 +34,7 @@ func TestAccRedisCluster_createClusterWithNodeType(t *testing.T) {
},
{
// clean up the resource
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, preventDestroy: false, nodeType: "REDIS_STANDARD_SMALL", zoneDistributionMode: "MULTI_ZONE"}),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, deletionProtectionEnabled: false, nodeType: "REDIS_STANDARD_SMALL", zoneDistributionMode: "MULTI_ZONE"}),
},
},
})
Expand All @@ -52,7 +53,7 @@ func TestAccRedisCluster_createClusterWithZoneDistribution(t *testing.T) {
Steps: []resource.TestStep{
{
// create cluster with replica count 1
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, preventDestroy: false, zoneDistributionMode: "SINGLE_ZONE", zone: "us-central1-b"}),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: false, zoneDistributionMode: "SINGLE_ZONE", zone: "us-central1-b"}),
},
{
ResourceName: "google_redis_cluster.test",
Expand All @@ -62,7 +63,7 @@ func TestAccRedisCluster_createClusterWithZoneDistribution(t *testing.T) {
},
{
// clean up the resource
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, preventDestroy: false, zoneDistributionMode: "SINGLE_ZONE", zone: "us-central1-b"}),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: false, zoneDistributionMode: "SINGLE_ZONE", zone: "us-central1-b"}),
},
},
})
Expand All @@ -81,7 +82,7 @@ func TestAccRedisCluster_updateReplicaCount(t *testing.T) {
Steps: []resource.TestStep{
{
// create cluster with replica count 1
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, preventDestroy: true, zoneDistributionMode: "MULTI_ZONE"}),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, deletionProtectionEnabled: true, zoneDistributionMode: "MULTI_ZONE"}),
},
{
ResourceName: "google_redis_cluster.test",
Expand All @@ -91,21 +92,17 @@ func TestAccRedisCluster_updateReplicaCount(t *testing.T) {
},
{
// update replica count to 2
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 2, shardCount: 3, preventDestroy: true, zoneDistributionMode: "MULTI_ZONE"}),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 2, shardCount: 3, deletionProtectionEnabled: true, zoneDistributionMode: "MULTI_ZONE"}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
},
{
// clean up the resource
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, preventDestroy: false, zoneDistributionMode: "MULTI_ZONE"}),
},
{
// update replica count to 0
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, preventDestroy: true, zoneDistributionMode: "MULTI_ZONE"}),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: true, zoneDistributionMode: "MULTI_ZONE"}),
},
{
ResourceName: "google_redis_cluster.test",
Expand All @@ -115,7 +112,7 @@ func TestAccRedisCluster_updateReplicaCount(t *testing.T) {
},
{
// clean up the resource
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, preventDestroy: false, zoneDistributionMode: "MULTI_ZONE"}),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: false, zoneDistributionMode: "MULTI_ZONE"}),
},
},
})
Expand All @@ -134,7 +131,7 @@ func TestAccRedisCluster_updateShardCount(t *testing.T) {
Steps: []resource.TestStep{
{
// create cluster with shard count 3
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, preventDestroy: true, zoneDistributionMode: "MULTI_ZONE"}),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, deletionProtectionEnabled: true, zoneDistributionMode: "MULTI_ZONE"}),
},
{
ResourceName: "google_redis_cluster.test",
Expand All @@ -144,7 +141,7 @@ func TestAccRedisCluster_updateShardCount(t *testing.T) {
},
{
// update shard count to 5
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 5, preventDestroy: true, zoneDistributionMode: "MULTI_ZONE"}),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 5, deletionProtectionEnabled: true, zoneDistributionMode: "MULTI_ZONE"}),
},
{
ResourceName: "google_redis_cluster.test",
Expand All @@ -154,7 +151,7 @@ func TestAccRedisCluster_updateShardCount(t *testing.T) {
},
{
// clean up the resource
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 5, preventDestroy: false, zoneDistributionMode: "MULTI_ZONE"}),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 5, deletionProtectionEnabled: false, zoneDistributionMode: "MULTI_ZONE"}),
},
},
})
Expand Down Expand Up @@ -212,25 +209,57 @@ func TestAccRedisCluster_updateRedisConfigs(t *testing.T) {
})
}

// Validate that deletion protection enabled/disabled cluster is created updated
func TestAccRedisCluster_createUpdateDeletionProtection(t *testing.T) {
t.Parallel()

name := fmt.Sprintf("tf-test-%d", acctest.RandInt(t))

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t),
CheckDestroy: testAccCheckRedisClusterDestroyProducer(t),
Steps: []resource.TestStep{
{
// create cluster with deletion protection set to false
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: false, zoneDistributionMode: "MULTI_ZONE"}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
},
{
// update deletion protection to true
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: true, zoneDistributionMode: "MULTI_ZONE"}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
},
{
// update deletion protection to false and delete the cluster
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: false, zoneDistributionMode: "MULTI_ZONE"}),
},
},
})
}

type ClusterParams struct {
name string
replicaCount int
shardCount int
preventDestroy bool
nodeType string
redisConfigs map[string]string
zoneDistributionMode string
zone string
name string
replicaCount int
shardCount int
deletionProtectionEnabled bool
nodeType string
redisConfigs map[string]string
zoneDistributionMode string
zone string
}

func createOrUpdateRedisCluster(params *ClusterParams) string {
lifecycleBlock := ""
if params.preventDestroy {
lifecycleBlock = `
lifecycle {
prevent_destroy = true
}`
}
var strBuilder strings.Builder
for key, value := range params.redisConfigs {
strBuilder.WriteString(fmt.Sprintf("%s = \"%s\"\n", key, value))
Expand All @@ -253,6 +282,7 @@ resource "google_redis_cluster" "test" {
replica_count = %d
shard_count = %d
node_type = "%s"
deletion_protection_enabled = %v
region = "us-central1"
psc_configs {
network = google_compute_network.producer_net.id
Expand All @@ -262,9 +292,8 @@ resource "google_redis_cluster" "test" {
}
%s
depends_on = [
google_network_connectivity_service_connection_policy.default
]
%s
google_network_connectivity_service_connection_policy.default
]
}
resource "google_network_connectivity_service_connection_policy" "default" {
Expand Down Expand Up @@ -292,5 +321,5 @@ resource "google_compute_network" "producer_net" {
name = "%s"
auto_create_subnetworks = false
}
`, params.name, params.replicaCount, params.shardCount, params.nodeType, strBuilder.String(), zoneDistributionConfigBlock, lifecycleBlock, params.name, params.name, params.name)
`, params.name, params.replicaCount, params.shardCount, params.nodeType, params.deletionProtectionEnabled, strBuilder.String(), zoneDistributionConfigBlock, params.name, params.name, params.name)
}
Loading

0 comments on commit 6ccc989

Please sign in to comment.