Skip to content

Commit dcd2690

Browse files
Add RDB & AOF Persistence support to Memorystore for Redis Cluster (#12219) (#20212)
[upstream:a3ffd4e196c5e93a506d53f83464004474bc69f4] Signed-off-by: Modular Magician <[email protected]>
1 parent 9b49cd8 commit dcd2690

File tree

4 files changed

+641
-0
lines changed

4 files changed

+641
-0
lines changed

.changelog/12219.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
redis: added `persistence_config` to `google_redis_cluster`. Fixed https://github.com/hashicorp/terraform-provider-google/issues/17999
3+
```

google/services/redis/resource_redis_cluster.go

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,81 @@ resolution and up to nine fractional digits.`,
207207
Description: `The nodeType for the Redis cluster.
208208
If not provided, REDIS_HIGHMEM_MEDIUM will be used as default Possible values: ["REDIS_SHARED_CORE_NANO", "REDIS_HIGHMEM_MEDIUM", "REDIS_HIGHMEM_XLARGE", "REDIS_STANDARD_SMALL"]`,
209209
},
210+
"persistence_config": {
211+
Type: schema.TypeList,
212+
Computed: true,
213+
Optional: true,
214+
Description: `Persistence config (RDB, AOF) for the cluster.`,
215+
MaxItems: 1,
216+
Elem: &schema.Resource{
217+
Schema: map[string]*schema.Schema{
218+
"aof_config": {
219+
Type: schema.TypeList,
220+
Computed: true,
221+
Optional: true,
222+
Description: `AOF configuration. This field will be ignored if mode is not AOF.`,
223+
MaxItems: 1,
224+
Elem: &schema.Resource{
225+
Schema: map[string]*schema.Schema{
226+
"append_fsync": {
227+
Type: schema.TypeString,
228+
Computed: true,
229+
Optional: true,
230+
ValidateFunc: verify.ValidateEnum([]string{"APPEND_FSYNC_UNSPECIFIED", "NO", "EVERYSEC", "ALWAYS", ""}),
231+
Description: `Optional. Available fsync modes.
232+
233+
- NO - Do not explicilty call fsync(). Rely on OS defaults.
234+
- EVERYSEC - Call fsync() once per second in a background thread. A balance between performance and durability.
235+
- ALWAYS - Call fsync() for earch write command. Possible values: ["APPEND_FSYNC_UNSPECIFIED", "NO", "EVERYSEC", "ALWAYS"]`,
236+
},
237+
},
238+
},
239+
},
240+
"mode": {
241+
Type: schema.TypeString,
242+
Computed: true,
243+
Optional: true,
244+
ValidateFunc: verify.ValidateEnum([]string{"PERSISTENCE_MODE_UNSPECIFIED", "DISABLED", "RDB", "AOF", ""}),
245+
Description: `Optional. Controls whether Persistence features are enabled. If not provided, the existing value will be used.
246+
247+
- DISABLED: Persistence (both backup and restore) is disabled for the cluster.
248+
- RDB: RDB based Persistence is enabled.
249+
- AOF: AOF based Persistence is enabled. Possible values: ["PERSISTENCE_MODE_UNSPECIFIED", "DISABLED", "RDB", "AOF"]`,
250+
},
251+
"rdb_config": {
252+
Type: schema.TypeList,
253+
Computed: true,
254+
Optional: true,
255+
Description: `RDB configuration. This field will be ignored if mode is not RDB.`,
256+
MaxItems: 1,
257+
Elem: &schema.Resource{
258+
Schema: map[string]*schema.Schema{
259+
"rdb_snapshot_period": {
260+
Type: schema.TypeString,
261+
Computed: true,
262+
Optional: true,
263+
ValidateFunc: verify.ValidateEnum([]string{"SNAPSHOT_PERIOD_UNSPECIFIED", "ONE_HOUR", "SIX_HOURS", "TWELVE_HOURS", "TWENTY_FOUR_HOURS", ""}),
264+
Description: `Optional. Available snapshot periods for scheduling.
265+
266+
- ONE_HOUR: Snapshot every 1 hour.
267+
- SIX_HOURS: Snapshot every 6 hours.
268+
- TWELVE_HOURS: Snapshot every 12 hours.
269+
- TWENTY_FOUR_HOURS: Snapshot every 24 hours. Possible values: ["SNAPSHOT_PERIOD_UNSPECIFIED", "ONE_HOUR", "SIX_HOURS", "TWELVE_HOURS", "TWENTY_FOUR_HOURS"]`,
270+
},
271+
"rdb_snapshot_start_time": {
272+
Type: schema.TypeString,
273+
Computed: true,
274+
Optional: true,
275+
Description: `The time that the first snapshot was/will be attempted, and to which
276+
future snapshots will be aligned.
277+
If not provided, the current time will be used.`,
278+
},
279+
},
280+
},
281+
},
282+
},
283+
},
284+
},
210285
"redis_configs": {
211286
Type: schema.TypeMap,
212287
Optional: true,
@@ -493,6 +568,12 @@ func resourceRedisClusterCreate(d *schema.ResourceData, meta interface{}) error
493568
} else if v, ok := d.GetOkExists("redis_configs"); !tpgresource.IsEmptyValue(reflect.ValueOf(redisConfigsProp)) && (ok || !reflect.DeepEqual(v, redisConfigsProp)) {
494569
obj["redisConfigs"] = redisConfigsProp
495570
}
571+
persistenceConfigProp, err := expandRedisClusterPersistenceConfig(d.Get("persistence_config"), d, config)
572+
if err != nil {
573+
return err
574+
} else if v, ok := d.GetOkExists("persistence_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(persistenceConfigProp)) && (ok || !reflect.DeepEqual(v, persistenceConfigProp)) {
575+
obj["persistenceConfig"] = persistenceConfigProp
576+
}
496577
maintenancePolicyProp, err := expandRedisClusterMaintenancePolicy(d.Get("maintenance_policy"), d, config)
497578
if err != nil {
498579
return err
@@ -654,6 +735,9 @@ func resourceRedisClusterRead(d *schema.ResourceData, meta interface{}) error {
654735
if err := d.Set("redis_configs", flattenRedisClusterRedisConfigs(res["redisConfigs"], d, config)); err != nil {
655736
return fmt.Errorf("Error reading Cluster: %s", err)
656737
}
738+
if err := d.Set("persistence_config", flattenRedisClusterPersistenceConfig(res["persistenceConfig"], d, config)); err != nil {
739+
return fmt.Errorf("Error reading Cluster: %s", err)
740+
}
657741
if err := d.Set("maintenance_policy", flattenRedisClusterMaintenancePolicy(res["maintenancePolicy"], d, config)); err != nil {
658742
return fmt.Errorf("Error reading Cluster: %s", err)
659743
}
@@ -710,6 +794,12 @@ func resourceRedisClusterUpdate(d *schema.ResourceData, meta interface{}) error
710794
} else if v, ok := d.GetOkExists("redis_configs"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, redisConfigsProp)) {
711795
obj["redisConfigs"] = redisConfigsProp
712796
}
797+
persistenceConfigProp, err := expandRedisClusterPersistenceConfig(d.Get("persistence_config"), d, config)
798+
if err != nil {
799+
return err
800+
} else if v, ok := d.GetOkExists("persistence_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, persistenceConfigProp)) {
801+
obj["persistenceConfig"] = persistenceConfigProp
802+
}
713803
maintenancePolicyProp, err := expandRedisClusterMaintenancePolicy(d.Get("maintenance_policy"), d, config)
714804
if err != nil {
715805
return err
@@ -746,6 +836,10 @@ func resourceRedisClusterUpdate(d *schema.ResourceData, meta interface{}) error
746836
updateMask = append(updateMask, "redisConfigs")
747837
}
748838

839+
if d.HasChange("persistence_config") {
840+
updateMask = append(updateMask, "persistenceConfig")
841+
}
842+
749843
if d.HasChange("maintenance_policy") {
750844
updateMask = append(updateMask, "maintenancePolicy")
751845
}
@@ -1141,6 +1235,67 @@ func flattenRedisClusterRedisConfigs(v interface{}, d *schema.ResourceData, conf
11411235
return v
11421236
}
11431237

1238+
func flattenRedisClusterPersistenceConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1239+
if v == nil {
1240+
return nil
1241+
}
1242+
original := v.(map[string]interface{})
1243+
if len(original) == 0 {
1244+
return nil
1245+
}
1246+
transformed := make(map[string]interface{})
1247+
transformed["mode"] =
1248+
flattenRedisClusterPersistenceConfigMode(original["mode"], d, config)
1249+
transformed["rdb_config"] =
1250+
flattenRedisClusterPersistenceConfigRdbConfig(original["rdbConfig"], d, config)
1251+
transformed["aof_config"] =
1252+
flattenRedisClusterPersistenceConfigAofConfig(original["aofConfig"], d, config)
1253+
return []interface{}{transformed}
1254+
}
1255+
func flattenRedisClusterPersistenceConfigMode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1256+
return v
1257+
}
1258+
1259+
func flattenRedisClusterPersistenceConfigRdbConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1260+
if v == nil {
1261+
return nil
1262+
}
1263+
original := v.(map[string]interface{})
1264+
if len(original) == 0 {
1265+
return nil
1266+
}
1267+
transformed := make(map[string]interface{})
1268+
transformed["rdb_snapshot_period"] =
1269+
flattenRedisClusterPersistenceConfigRdbConfigRdbSnapshotPeriod(original["rdbSnapshotPeriod"], d, config)
1270+
transformed["rdb_snapshot_start_time"] =
1271+
flattenRedisClusterPersistenceConfigRdbConfigRdbSnapshotStartTime(original["rdbSnapshotStartTime"], d, config)
1272+
return []interface{}{transformed}
1273+
}
1274+
func flattenRedisClusterPersistenceConfigRdbConfigRdbSnapshotPeriod(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1275+
return v
1276+
}
1277+
1278+
func flattenRedisClusterPersistenceConfigRdbConfigRdbSnapshotStartTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1279+
return v
1280+
}
1281+
1282+
func flattenRedisClusterPersistenceConfigAofConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1283+
if v == nil {
1284+
return nil
1285+
}
1286+
original := v.(map[string]interface{})
1287+
if len(original) == 0 {
1288+
return nil
1289+
}
1290+
transformed := make(map[string]interface{})
1291+
transformed["append_fsync"] =
1292+
flattenRedisClusterPersistenceConfigAofConfigAppendFsync(original["appendFsync"], d, config)
1293+
return []interface{}{transformed}
1294+
}
1295+
func flattenRedisClusterPersistenceConfigAofConfigAppendFsync(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1296+
return v
1297+
}
1298+
11441299
func flattenRedisClusterMaintenancePolicy(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
11451300
if v == nil {
11461301
return nil
@@ -1402,6 +1557,100 @@ func expandRedisClusterRedisConfigs(v interface{}, d tpgresource.TerraformResour
14021557
return m, nil
14031558
}
14041559

1560+
func expandRedisClusterPersistenceConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1561+
l := v.([]interface{})
1562+
if len(l) == 0 || l[0] == nil {
1563+
return nil, nil
1564+
}
1565+
raw := l[0]
1566+
original := raw.(map[string]interface{})
1567+
transformed := make(map[string]interface{})
1568+
1569+
transformedMode, err := expandRedisClusterPersistenceConfigMode(original["mode"], d, config)
1570+
if err != nil {
1571+
return nil, err
1572+
} else if val := reflect.ValueOf(transformedMode); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1573+
transformed["mode"] = transformedMode
1574+
}
1575+
1576+
transformedRdbConfig, err := expandRedisClusterPersistenceConfigRdbConfig(original["rdb_config"], d, config)
1577+
if err != nil {
1578+
return nil, err
1579+
} else if val := reflect.ValueOf(transformedRdbConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1580+
transformed["rdbConfig"] = transformedRdbConfig
1581+
}
1582+
1583+
transformedAofConfig, err := expandRedisClusterPersistenceConfigAofConfig(original["aof_config"], d, config)
1584+
if err != nil {
1585+
return nil, err
1586+
} else if val := reflect.ValueOf(transformedAofConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1587+
transformed["aofConfig"] = transformedAofConfig
1588+
}
1589+
1590+
return transformed, nil
1591+
}
1592+
1593+
func expandRedisClusterPersistenceConfigMode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1594+
return v, nil
1595+
}
1596+
1597+
func expandRedisClusterPersistenceConfigRdbConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1598+
l := v.([]interface{})
1599+
if len(l) == 0 || l[0] == nil {
1600+
return nil, nil
1601+
}
1602+
raw := l[0]
1603+
original := raw.(map[string]interface{})
1604+
transformed := make(map[string]interface{})
1605+
1606+
transformedRdbSnapshotPeriod, err := expandRedisClusterPersistenceConfigRdbConfigRdbSnapshotPeriod(original["rdb_snapshot_period"], d, config)
1607+
if err != nil {
1608+
return nil, err
1609+
} else if val := reflect.ValueOf(transformedRdbSnapshotPeriod); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1610+
transformed["rdbSnapshotPeriod"] = transformedRdbSnapshotPeriod
1611+
}
1612+
1613+
transformedRdbSnapshotStartTime, err := expandRedisClusterPersistenceConfigRdbConfigRdbSnapshotStartTime(original["rdb_snapshot_start_time"], d, config)
1614+
if err != nil {
1615+
return nil, err
1616+
} else if val := reflect.ValueOf(transformedRdbSnapshotStartTime); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1617+
transformed["rdbSnapshotStartTime"] = transformedRdbSnapshotStartTime
1618+
}
1619+
1620+
return transformed, nil
1621+
}
1622+
1623+
func expandRedisClusterPersistenceConfigRdbConfigRdbSnapshotPeriod(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1624+
return v, nil
1625+
}
1626+
1627+
func expandRedisClusterPersistenceConfigRdbConfigRdbSnapshotStartTime(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1628+
return v, nil
1629+
}
1630+
1631+
func expandRedisClusterPersistenceConfigAofConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1632+
l := v.([]interface{})
1633+
if len(l) == 0 || l[0] == nil {
1634+
return nil, nil
1635+
}
1636+
raw := l[0]
1637+
original := raw.(map[string]interface{})
1638+
transformed := make(map[string]interface{})
1639+
1640+
transformedAppendFsync, err := expandRedisClusterPersistenceConfigAofConfigAppendFsync(original["append_fsync"], d, config)
1641+
if err != nil {
1642+
return nil, err
1643+
} else if val := reflect.ValueOf(transformedAppendFsync); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1644+
transformed["appendFsync"] = transformedAppendFsync
1645+
}
1646+
1647+
return transformed, nil
1648+
}
1649+
1650+
func expandRedisClusterPersistenceConfigAofConfigAppendFsync(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1651+
return v, nil
1652+
}
1653+
14051654
func expandRedisClusterMaintenancePolicy(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
14061655
l := v.([]interface{})
14071656
if len(l) == 0 || l[0] == nil {

0 commit comments

Comments
 (0)