Skip to content

Commit 18d241c

Browse files
Add DeletionProtectionEnabled to Redis Cluster (#10367)
Co-authored-by: Nick Elliot <[email protected]> [upstream:820e403355ea94ddbf666b9327231eb35bbfd5d8] Signed-off-by: Modular Magician <[email protected]>
1 parent 651e313 commit 18d241c

File tree

5 files changed

+117
-52
lines changed

5 files changed

+117
-52
lines changed

.changelog/10367.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
redis: added a `deletion_protection_enabled` field with a default value of `true` to the `google_redis_cluster` resource
3+
```

google-beta/services/redis/resource_redis_cluster.go

+35
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ projects/{network_project_id_or_number}/global/networks/{network_id}.`,
9595
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"]`,
9696
Default: "AUTH_MODE_DISABLED",
9797
},
98+
"deletion_protection_enabled": {
99+
Type: schema.TypeBool,
100+
Optional: true,
101+
Description: `Optional. Indicates if the cluster is deletion protected or not.
102+
If the value if set to true, any delete cluster operation will fail.
103+
Default value is true.`,
104+
Default: true,
105+
},
98106
"node_type": {
99107
Type: schema.TypeString,
100108
Computed: true,
@@ -347,6 +355,12 @@ func resourceRedisClusterCreate(d *schema.ResourceData, meta interface{}) error
347355
} else if v, ok := d.GetOkExists("shard_count"); !tpgresource.IsEmptyValue(reflect.ValueOf(shardCountProp)) && (ok || !reflect.DeepEqual(v, shardCountProp)) {
348356
obj["shardCount"] = shardCountProp
349357
}
358+
deletionProtectionEnabledProp, err := expandRedisClusterDeletionProtectionEnabled(d.Get("deletion_protection_enabled"), d, config)
359+
if err != nil {
360+
return err
361+
} else if v, ok := d.GetOkExists("deletion_protection_enabled"); !tpgresource.IsEmptyValue(reflect.ValueOf(deletionProtectionEnabledProp)) && (ok || !reflect.DeepEqual(v, deletionProtectionEnabledProp)) {
362+
obj["deletionProtectionEnabled"] = deletionProtectionEnabledProp
363+
}
350364
redisConfigsProp, err := expandRedisClusterRedisConfigs(d.Get("redis_configs"), d, config)
351365
if err != nil {
352366
return err
@@ -502,6 +516,9 @@ func resourceRedisClusterRead(d *schema.ResourceData, meta interface{}) error {
502516
if err := d.Set("shard_count", flattenRedisClusterShardCount(res["shardCount"], d, config)); err != nil {
503517
return fmt.Errorf("Error reading Cluster: %s", err)
504518
}
519+
if err := d.Set("deletion_protection_enabled", flattenRedisClusterDeletionProtectionEnabled(res["deletionProtectionEnabled"], d, config)); err != nil {
520+
return fmt.Errorf("Error reading Cluster: %s", err)
521+
}
505522
if err := d.Set("redis_configs", flattenRedisClusterRedisConfigs(res["redisConfigs"], d, config)); err != nil {
506523
return fmt.Errorf("Error reading Cluster: %s", err)
507524
}
@@ -543,6 +560,12 @@ func resourceRedisClusterUpdate(d *schema.ResourceData, meta interface{}) error
543560
} else if v, ok := d.GetOkExists("shard_count"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, shardCountProp)) {
544561
obj["shardCount"] = shardCountProp
545562
}
563+
deletionProtectionEnabledProp, err := expandRedisClusterDeletionProtectionEnabled(d.Get("deletion_protection_enabled"), d, config)
564+
if err != nil {
565+
return err
566+
} else if v, ok := d.GetOkExists("deletion_protection_enabled"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, deletionProtectionEnabledProp)) {
567+
obj["deletionProtectionEnabled"] = deletionProtectionEnabledProp
568+
}
546569
redisConfigsProp, err := expandRedisClusterRedisConfigs(d.Get("redis_configs"), d, config)
547570
if err != nil {
548571
return err
@@ -571,6 +594,10 @@ func resourceRedisClusterUpdate(d *schema.ResourceData, meta interface{}) error
571594
updateMask = append(updateMask, "shardCount")
572595
}
573596

597+
if d.HasChange("deletion_protection_enabled") {
598+
updateMask = append(updateMask, "deletionProtectionEnabled")
599+
}
600+
574601
if d.HasChange("redis_configs") {
575602
updateMask = append(updateMask, "redisConfigs")
576603
}
@@ -958,6 +985,10 @@ func flattenRedisClusterShardCount(v interface{}, d *schema.ResourceData, config
958985
return v // let terraform core handle it otherwise
959986
}
960987

988+
func flattenRedisClusterDeletionProtectionEnabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
989+
return v
990+
}
991+
961992
func flattenRedisClusterRedisConfigs(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
962993
return v
963994
}
@@ -1042,6 +1073,10 @@ func expandRedisClusterShardCount(v interface{}, d tpgresource.TerraformResource
10421073
return v, nil
10431074
}
10441075

1076+
func expandRedisClusterDeletionProtectionEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1077+
return v, nil
1078+
}
1079+
10451080
func expandRedisClusterRedisConfigs(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) {
10461081
if v == nil {
10471082
return map[string]string{}, nil

google-beta/services/redis/resource_redis_cluster_generated_test.go

+7-11
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ func TestAccRedisCluster_redisClusterHaExample(t *testing.T) {
3434
t.Parallel()
3535

3636
context := map[string]interface{}{
37-
"prevent_destroy": false,
38-
"random_suffix": acctest.RandString(t, 10),
37+
"deletion_protection_enabled": false,
38+
"random_suffix": acctest.RandString(t, 10),
3939
}
4040

4141
acctest.VcrTest(t, resource.TestCase{
@@ -72,16 +72,14 @@ resource "google_redis_cluster" "cluster-ha" {
7272
redis_configs = {
7373
maxmemory-policy = "volatile-ttl"
7474
}
75+
deletion_protection_enabled = false
76+
7577
zone_distribution_config {
7678
mode = "MULTI_ZONE"
7779
}
7880
depends_on = [
7981
google_network_connectivity_service_connection_policy.default
8082
]
81-
82-
lifecycle {
83-
prevent_destroy = %{prevent_destroy}
84-
}
8583
}
8684
8785
resource "google_network_connectivity_service_connection_policy" "default" {
@@ -113,8 +111,8 @@ func TestAccRedisCluster_redisClusterHaSingleZoneExample(t *testing.T) {
113111
t.Parallel()
114112

115113
context := map[string]interface{}{
116-
"prevent_destroy": false,
117-
"random_suffix": acctest.RandString(t, 10),
114+
"deletion_protection_enabled": false,
115+
"random_suffix": acctest.RandString(t, 10),
118116
}
119117

120118
acctest.VcrTest(t, resource.TestCase{
@@ -148,13 +146,11 @@ resource "google_redis_cluster" "cluster-ha-single-zone" {
148146
mode = "SINGLE_ZONE"
149147
zone = "us-central1-f"
150148
}
149+
deletion_protection_enabled = false
151150
depends_on = [
152151
google_network_connectivity_service_connection_policy.default
153152
]
154153
155-
lifecycle {
156-
prevent_destroy = %{prevent_destroy}
157-
}
158154
}
159155
160156
resource "google_network_connectivity_service_connection_policy" "default" {

google-beta/services/redis/resource_redis_cluster_test.go

+63-34
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
)
1313

1414
func TestAccRedisCluster_createClusterWithNodeType(t *testing.T) {
15+
1516
t.Parallel()
1617

1718
name := fmt.Sprintf("tf-test-%d", acctest.RandInt(t))
@@ -23,7 +24,7 @@ func TestAccRedisCluster_createClusterWithNodeType(t *testing.T) {
2324
Steps: []resource.TestStep{
2425
{
2526
// create cluster with replica count 1
26-
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, preventDestroy: true, nodeType: "REDIS_STANDARD_SMALL", zoneDistributionMode: "MULTI_ZONE"}),
27+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, deletionProtectionEnabled: true, nodeType: "REDIS_STANDARD_SMALL", zoneDistributionMode: "MULTI_ZONE"}),
2728
},
2829
{
2930
ResourceName: "google_redis_cluster.test",
@@ -33,7 +34,7 @@ func TestAccRedisCluster_createClusterWithNodeType(t *testing.T) {
3334
},
3435
{
3536
// clean up the resource
36-
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, preventDestroy: false, nodeType: "REDIS_STANDARD_SMALL", zoneDistributionMode: "MULTI_ZONE"}),
37+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, deletionProtectionEnabled: false, nodeType: "REDIS_STANDARD_SMALL", zoneDistributionMode: "MULTI_ZONE"}),
3738
},
3839
},
3940
})
@@ -52,7 +53,7 @@ func TestAccRedisCluster_createClusterWithZoneDistribution(t *testing.T) {
5253
Steps: []resource.TestStep{
5354
{
5455
// create cluster with replica count 1
55-
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, preventDestroy: false, zoneDistributionMode: "SINGLE_ZONE", zone: "us-central1-b"}),
56+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: false, zoneDistributionMode: "SINGLE_ZONE", zone: "us-central1-b"}),
5657
},
5758
{
5859
ResourceName: "google_redis_cluster.test",
@@ -62,7 +63,7 @@ func TestAccRedisCluster_createClusterWithZoneDistribution(t *testing.T) {
6263
},
6364
{
6465
// clean up the resource
65-
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, preventDestroy: false, zoneDistributionMode: "SINGLE_ZONE", zone: "us-central1-b"}),
66+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: false, zoneDistributionMode: "SINGLE_ZONE", zone: "us-central1-b"}),
6667
},
6768
},
6869
})
@@ -81,7 +82,7 @@ func TestAccRedisCluster_updateReplicaCount(t *testing.T) {
8182
Steps: []resource.TestStep{
8283
{
8384
// create cluster with replica count 1
84-
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, preventDestroy: true, zoneDistributionMode: "MULTI_ZONE"}),
85+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, deletionProtectionEnabled: true, zoneDistributionMode: "MULTI_ZONE"}),
8586
},
8687
{
8788
ResourceName: "google_redis_cluster.test",
@@ -91,21 +92,17 @@ func TestAccRedisCluster_updateReplicaCount(t *testing.T) {
9192
},
9293
{
9394
// update replica count to 2
94-
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 2, shardCount: 3, preventDestroy: true, zoneDistributionMode: "MULTI_ZONE"}),
95+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 2, shardCount: 3, deletionProtectionEnabled: true, zoneDistributionMode: "MULTI_ZONE"}),
9596
},
9697
{
9798
ResourceName: "google_redis_cluster.test",
9899
ImportState: true,
99100
ImportStateVerify: true,
100101
ImportStateVerifyIgnore: []string{"psc_configs"},
101102
},
102-
{
103-
// clean up the resource
104-
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, preventDestroy: false, zoneDistributionMode: "MULTI_ZONE"}),
105-
},
106103
{
107104
// update replica count to 0
108-
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, preventDestroy: true, zoneDistributionMode: "MULTI_ZONE"}),
105+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: true, zoneDistributionMode: "MULTI_ZONE"}),
109106
},
110107
{
111108
ResourceName: "google_redis_cluster.test",
@@ -115,7 +112,7 @@ func TestAccRedisCluster_updateReplicaCount(t *testing.T) {
115112
},
116113
{
117114
// clean up the resource
118-
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, preventDestroy: false, zoneDistributionMode: "MULTI_ZONE"}),
115+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: false, zoneDistributionMode: "MULTI_ZONE"}),
119116
},
120117
},
121118
})
@@ -134,7 +131,7 @@ func TestAccRedisCluster_updateShardCount(t *testing.T) {
134131
Steps: []resource.TestStep{
135132
{
136133
// create cluster with shard count 3
137-
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, preventDestroy: true, zoneDistributionMode: "MULTI_ZONE"}),
134+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, deletionProtectionEnabled: true, zoneDistributionMode: "MULTI_ZONE"}),
138135
},
139136
{
140137
ResourceName: "google_redis_cluster.test",
@@ -144,7 +141,7 @@ func TestAccRedisCluster_updateShardCount(t *testing.T) {
144141
},
145142
{
146143
// update shard count to 5
147-
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 5, preventDestroy: true, zoneDistributionMode: "MULTI_ZONE"}),
144+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 5, deletionProtectionEnabled: true, zoneDistributionMode: "MULTI_ZONE"}),
148145
},
149146
{
150147
ResourceName: "google_redis_cluster.test",
@@ -154,7 +151,7 @@ func TestAccRedisCluster_updateShardCount(t *testing.T) {
154151
},
155152
{
156153
// clean up the resource
157-
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 5, preventDestroy: false, zoneDistributionMode: "MULTI_ZONE"}),
154+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 5, deletionProtectionEnabled: false, zoneDistributionMode: "MULTI_ZONE"}),
158155
},
159156
},
160157
})
@@ -212,25 +209,57 @@ func TestAccRedisCluster_updateRedisConfigs(t *testing.T) {
212209
})
213210
}
214211

212+
// Validate that deletion protection enabled/disabled cluster is created updated
213+
func TestAccRedisCluster_createUpdateDeletionProtection(t *testing.T) {
214+
t.Parallel()
215+
216+
name := fmt.Sprintf("tf-test-%d", acctest.RandInt(t))
217+
218+
acctest.VcrTest(t, resource.TestCase{
219+
PreCheck: func() { acctest.AccTestPreCheck(t) },
220+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t),
221+
CheckDestroy: testAccCheckRedisClusterDestroyProducer(t),
222+
Steps: []resource.TestStep{
223+
{
224+
// create cluster with deletion protection set to false
225+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: false, zoneDistributionMode: "MULTI_ZONE"}),
226+
},
227+
{
228+
ResourceName: "google_redis_cluster.test",
229+
ImportState: true,
230+
ImportStateVerify: true,
231+
ImportStateVerifyIgnore: []string{"psc_configs"},
232+
},
233+
{
234+
// update deletion protection to true
235+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: true, zoneDistributionMode: "MULTI_ZONE"}),
236+
},
237+
{
238+
ResourceName: "google_redis_cluster.test",
239+
ImportState: true,
240+
ImportStateVerify: true,
241+
ImportStateVerifyIgnore: []string{"psc_configs"},
242+
},
243+
{
244+
// update deletion protection to false and delete the cluster
245+
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, deletionProtectionEnabled: false, zoneDistributionMode: "MULTI_ZONE"}),
246+
},
247+
},
248+
})
249+
}
250+
215251
type ClusterParams struct {
216-
name string
217-
replicaCount int
218-
shardCount int
219-
preventDestroy bool
220-
nodeType string
221-
redisConfigs map[string]string
222-
zoneDistributionMode string
223-
zone string
252+
name string
253+
replicaCount int
254+
shardCount int
255+
deletionProtectionEnabled bool
256+
nodeType string
257+
redisConfigs map[string]string
258+
zoneDistributionMode string
259+
zone string
224260
}
225261

226262
func createOrUpdateRedisCluster(params *ClusterParams) string {
227-
lifecycleBlock := ""
228-
if params.preventDestroy {
229-
lifecycleBlock = `
230-
lifecycle {
231-
prevent_destroy = true
232-
}`
233-
}
234263
var strBuilder strings.Builder
235264
for key, value := range params.redisConfigs {
236265
strBuilder.WriteString(fmt.Sprintf("%s = \"%s\"\n", key, value))
@@ -253,6 +282,7 @@ resource "google_redis_cluster" "test" {
253282
replica_count = %d
254283
shard_count = %d
255284
node_type = "%s"
285+
deletion_protection_enabled = %v
256286
region = "us-central1"
257287
psc_configs {
258288
network = google_compute_network.producer_net.id
@@ -262,9 +292,8 @@ resource "google_redis_cluster" "test" {
262292
}
263293
%s
264294
depends_on = [
265-
google_network_connectivity_service_connection_policy.default
266-
]
267-
%s
295+
google_network_connectivity_service_connection_policy.default
296+
]
268297
}
269298
270299
resource "google_network_connectivity_service_connection_policy" "default" {
@@ -292,5 +321,5 @@ resource "google_compute_network" "producer_net" {
292321
name = "%s"
293322
auto_create_subnetworks = false
294323
}
295-
`, params.name, params.replicaCount, params.shardCount, params.nodeType, strBuilder.String(), zoneDistributionConfigBlock, lifecycleBlock, params.name, params.name, params.name)
324+
`, params.name, params.replicaCount, params.shardCount, params.nodeType, params.deletionProtectionEnabled, strBuilder.String(), zoneDistributionConfigBlock, params.name, params.name, params.name)
296325
}

0 commit comments

Comments
 (0)