Skip to content

Commit

Permalink
Add RDB & AOF Persistence support to Memorystore for Redis Cluster (#…
Browse files Browse the repository at this point in the history
…12219) (#20212)

[upstream:a3ffd4e196c5e93a506d53f83464004474bc69f4]

Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored Nov 6, 2024
1 parent 9b49cd8 commit dcd2690
Show file tree
Hide file tree
Showing 4 changed files with 641 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/12219.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
redis: added `persistence_config` to `google_redis_cluster`. Fixed https://github.com/hashicorp/terraform-provider-google/issues/17999
```
249 changes: 249 additions & 0 deletions google/services/redis/resource_redis_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,81 @@ resolution and up to nine fractional digits.`,
Description: `The nodeType for the Redis cluster.
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"]`,
},
"persistence_config": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Description: `Persistence config (RDB, AOF) for the cluster.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"aof_config": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Description: `AOF configuration. This field will be ignored if mode is not AOF.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"append_fsync": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: verify.ValidateEnum([]string{"APPEND_FSYNC_UNSPECIFIED", "NO", "EVERYSEC", "ALWAYS", ""}),
Description: `Optional. Available fsync modes.
- NO - Do not explicilty call fsync(). Rely on OS defaults.
- EVERYSEC - Call fsync() once per second in a background thread. A balance between performance and durability.
- ALWAYS - Call fsync() for earch write command. Possible values: ["APPEND_FSYNC_UNSPECIFIED", "NO", "EVERYSEC", "ALWAYS"]`,
},
},
},
},
"mode": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: verify.ValidateEnum([]string{"PERSISTENCE_MODE_UNSPECIFIED", "DISABLED", "RDB", "AOF", ""}),
Description: `Optional. Controls whether Persistence features are enabled. If not provided, the existing value will be used.
- DISABLED: Persistence (both backup and restore) is disabled for the cluster.
- RDB: RDB based Persistence is enabled.
- AOF: AOF based Persistence is enabled. Possible values: ["PERSISTENCE_MODE_UNSPECIFIED", "DISABLED", "RDB", "AOF"]`,
},
"rdb_config": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Description: `RDB configuration. This field will be ignored if mode is not RDB.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"rdb_snapshot_period": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: verify.ValidateEnum([]string{"SNAPSHOT_PERIOD_UNSPECIFIED", "ONE_HOUR", "SIX_HOURS", "TWELVE_HOURS", "TWENTY_FOUR_HOURS", ""}),
Description: `Optional. Available snapshot periods for scheduling.
- ONE_HOUR: Snapshot every 1 hour.
- SIX_HOURS: Snapshot every 6 hours.
- TWELVE_HOURS: Snapshot every 12 hours.
- TWENTY_FOUR_HOURS: Snapshot every 24 hours. Possible values: ["SNAPSHOT_PERIOD_UNSPECIFIED", "ONE_HOUR", "SIX_HOURS", "TWELVE_HOURS", "TWENTY_FOUR_HOURS"]`,
},
"rdb_snapshot_start_time": {
Type: schema.TypeString,
Computed: true,
Optional: true,
Description: `The time that the first snapshot was/will be attempted, and to which
future snapshots will be aligned.
If not provided, the current time will be used.`,
},
},
},
},
},
},
},
"redis_configs": {
Type: schema.TypeMap,
Optional: true,
Expand Down Expand Up @@ -493,6 +568,12 @@ func resourceRedisClusterCreate(d *schema.ResourceData, meta interface{}) error
} else if v, ok := d.GetOkExists("redis_configs"); !tpgresource.IsEmptyValue(reflect.ValueOf(redisConfigsProp)) && (ok || !reflect.DeepEqual(v, redisConfigsProp)) {
obj["redisConfigs"] = redisConfigsProp
}
persistenceConfigProp, err := expandRedisClusterPersistenceConfig(d.Get("persistence_config"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("persistence_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(persistenceConfigProp)) && (ok || !reflect.DeepEqual(v, persistenceConfigProp)) {
obj["persistenceConfig"] = persistenceConfigProp
}
maintenancePolicyProp, err := expandRedisClusterMaintenancePolicy(d.Get("maintenance_policy"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -654,6 +735,9 @@ func resourceRedisClusterRead(d *schema.ResourceData, meta interface{}) error {
if err := d.Set("redis_configs", flattenRedisClusterRedisConfigs(res["redisConfigs"], d, config)); err != nil {
return fmt.Errorf("Error reading Cluster: %s", err)
}
if err := d.Set("persistence_config", flattenRedisClusterPersistenceConfig(res["persistenceConfig"], d, config)); err != nil {
return fmt.Errorf("Error reading Cluster: %s", err)
}
if err := d.Set("maintenance_policy", flattenRedisClusterMaintenancePolicy(res["maintenancePolicy"], d, config)); err != nil {
return fmt.Errorf("Error reading Cluster: %s", err)
}
Expand Down Expand Up @@ -710,6 +794,12 @@ func resourceRedisClusterUpdate(d *schema.ResourceData, meta interface{}) error
} else if v, ok := d.GetOkExists("redis_configs"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, redisConfigsProp)) {
obj["redisConfigs"] = redisConfigsProp
}
persistenceConfigProp, err := expandRedisClusterPersistenceConfig(d.Get("persistence_config"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("persistence_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, persistenceConfigProp)) {
obj["persistenceConfig"] = persistenceConfigProp
}
maintenancePolicyProp, err := expandRedisClusterMaintenancePolicy(d.Get("maintenance_policy"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -746,6 +836,10 @@ func resourceRedisClusterUpdate(d *schema.ResourceData, meta interface{}) error
updateMask = append(updateMask, "redisConfigs")
}

if d.HasChange("persistence_config") {
updateMask = append(updateMask, "persistenceConfig")
}

if d.HasChange("maintenance_policy") {
updateMask = append(updateMask, "maintenancePolicy")
}
Expand Down Expand Up @@ -1141,6 +1235,67 @@ func flattenRedisClusterRedisConfigs(v interface{}, d *schema.ResourceData, conf
return v
}

func flattenRedisClusterPersistenceConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["mode"] =
flattenRedisClusterPersistenceConfigMode(original["mode"], d, config)
transformed["rdb_config"] =
flattenRedisClusterPersistenceConfigRdbConfig(original["rdbConfig"], d, config)
transformed["aof_config"] =
flattenRedisClusterPersistenceConfigAofConfig(original["aofConfig"], d, config)
return []interface{}{transformed}
}
func flattenRedisClusterPersistenceConfigMode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenRedisClusterPersistenceConfigRdbConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["rdb_snapshot_period"] =
flattenRedisClusterPersistenceConfigRdbConfigRdbSnapshotPeriod(original["rdbSnapshotPeriod"], d, config)
transformed["rdb_snapshot_start_time"] =
flattenRedisClusterPersistenceConfigRdbConfigRdbSnapshotStartTime(original["rdbSnapshotStartTime"], d, config)
return []interface{}{transformed}
}
func flattenRedisClusterPersistenceConfigRdbConfigRdbSnapshotPeriod(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

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

func flattenRedisClusterPersistenceConfigAofConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["append_fsync"] =
flattenRedisClusterPersistenceConfigAofConfigAppendFsync(original["appendFsync"], d, config)
return []interface{}{transformed}
}
func flattenRedisClusterPersistenceConfigAofConfigAppendFsync(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenRedisClusterMaintenancePolicy(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
Expand Down Expand Up @@ -1402,6 +1557,100 @@ func expandRedisClusterRedisConfigs(v interface{}, d tpgresource.TerraformResour
return m, nil
}

func expandRedisClusterPersistenceConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedMode, err := expandRedisClusterPersistenceConfigMode(original["mode"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedMode); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["mode"] = transformedMode
}

transformedRdbConfig, err := expandRedisClusterPersistenceConfigRdbConfig(original["rdb_config"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedRdbConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["rdbConfig"] = transformedRdbConfig
}

transformedAofConfig, err := expandRedisClusterPersistenceConfigAofConfig(original["aof_config"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedAofConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["aofConfig"] = transformedAofConfig
}

return transformed, nil
}

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

func expandRedisClusterPersistenceConfigRdbConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedRdbSnapshotPeriod, err := expandRedisClusterPersistenceConfigRdbConfigRdbSnapshotPeriod(original["rdb_snapshot_period"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedRdbSnapshotPeriod); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["rdbSnapshotPeriod"] = transformedRdbSnapshotPeriod
}

transformedRdbSnapshotStartTime, err := expandRedisClusterPersistenceConfigRdbConfigRdbSnapshotStartTime(original["rdb_snapshot_start_time"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedRdbSnapshotStartTime); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["rdbSnapshotStartTime"] = transformedRdbSnapshotStartTime
}

return transformed, nil
}

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

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

func expandRedisClusterPersistenceConfigAofConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedAppendFsync, err := expandRedisClusterPersistenceConfigAofConfigAppendFsync(original["append_fsync"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedAppendFsync); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["appendFsync"] = transformedAppendFsync
}

return transformed, nil
}

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

func expandRedisClusterMaintenancePolicy(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
Expand Down
Loading

0 comments on commit dcd2690

Please sign in to comment.