Skip to content

Commit 1a73f0f

Browse files
committed
fix: using getrawstate to compare against the real state rather than materialized state with zero values
1 parent 33a275d commit 1a73f0f

File tree

1 file changed

+78
-82
lines changed

1 file changed

+78
-82
lines changed

provider/resource_rediscloud_active_active_database.go

Lines changed: 78 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -592,16 +592,6 @@ func resourceRedisCloudActiveActiveDatabaseRead(ctx context.Context, d *schema.R
592592
stateRegionMap := stateRegion.(map[string]interface{})
593593
region := stateRegionMap["name"].(string)
594594

595-
// Debug: log what keys are in stateRegionMap
596-
mapKeys := make([]string, 0, len(stateRegionMap))
597-
for k := range stateRegionMap {
598-
mapKeys = append(mapKeys, k)
599-
}
600-
tflog.Debug(ctx, "Read: StateRegionMap keys", map[string]interface{}{
601-
"region": region,
602-
"keys": mapKeys,
603-
})
604-
605595
// Look up corresponding API data
606596
regionDb, exists := apiRegions[region]
607597
if !exists {
@@ -1042,20 +1032,58 @@ func isEnableDefaultUserExplicitlySetInConfig(d *schema.ResourceData, regionName
10421032
return false
10431033
}
10441034

1035+
// isEnableDefaultUserInActualPersistedState checks if enable_default_user was in the ACTUAL
1036+
// persisted Terraform state (not the materialized Go map) for a specific region.
1037+
// Uses GetRawState to bypass TypeSet materialization that adds all fields with zero-values.
1038+
func isEnableDefaultUserInActualPersistedState(d *schema.ResourceData, regionName string) bool {
1039+
rawState := d.GetRawState()
1040+
1041+
// During Read, raw state should be available (contains previous state)
1042+
if rawState.IsNull() {
1043+
return false
1044+
}
1045+
1046+
// Check if override_region exists in raw state
1047+
if !rawState.Type().HasAttribute("override_region") {
1048+
return false
1049+
}
1050+
1051+
overrideRegionAttr := rawState.GetAttr("override_region")
1052+
if overrideRegionAttr.IsNull() {
1053+
return false
1054+
}
1055+
1056+
// Iterate through the set to find the matching region
1057+
if overrideRegionAttr.Type().IsSetType() {
1058+
iter := overrideRegionAttr.ElementIterator()
1059+
for iter.Next() {
1060+
_, regionVal := iter.Element()
1061+
1062+
// Check if this is the region we're looking for
1063+
if regionVal.Type().HasAttribute("name") {
1064+
nameAttr := regionVal.GetAttr("name")
1065+
if !nameAttr.IsNull() && nameAttr.AsString() == regionName {
1066+
// Found the matching region, check if enable_default_user exists
1067+
if regionVal.Type().HasAttribute("enable_default_user") {
1068+
fieldAttr := regionVal.GetAttr("enable_default_user")
1069+
// If the attribute exists and is not null, it was in the state
1070+
return !fieldAttr.IsNull()
1071+
}
1072+
// Field doesn't exist in persisted state for this region
1073+
return false
1074+
}
1075+
}
1076+
}
1077+
}
1078+
1079+
// Region not found
1080+
return false
1081+
}
1082+
10451083
// buildRegionConfigFromAPIAndState builds a region config map from API data and state data.
10461084
// This function handles all the complex logic for determining which fields to include in the
10471085
// region config based on what's in the API response and what was previously in the state.
10481086
func buildRegionConfigFromAPIAndState(ctx context.Context, d *schema.ResourceData, db *databases.ActiveActiveDatabase, region string, regionDb *databases.CrdbDatabase, stateOverrideRegion map[string]interface{}) map[string]interface{} {
1049-
tflog.Debug(ctx, "Read: Processing region from state", map[string]interface{}{
1050-
"region": region,
1051-
"stateHasEnableDefaultUser": stateOverrideRegion["enable_default_user"] != nil,
1052-
"stateHasOverrideGlobalSourceIps": stateOverrideRegion["override_global_source_ips"] != nil,
1053-
"stateHasOverrideGlobalDataPersistence": stateOverrideRegion["override_global_data_persistence"] != nil,
1054-
"stateHasOverrideGlobalPassword": stateOverrideRegion["override_global_password"] != nil && stateOverrideRegion["override_global_password"] != "",
1055-
"stateHasOverrideGlobalAlert": stateOverrideRegion["override_global_alert"] != nil,
1056-
"stateHasRemoteBackup": stateOverrideRegion["remote_backup"] != nil,
1057-
})
1058-
10591087
regionDbConfig := map[string]interface{}{
10601088
"name": region,
10611089
}
@@ -1148,88 +1176,56 @@ func buildRegionConfigFromAPIAndState(ctx context.Context, d *schema.ResourceDat
11481176
rawConfig := d.GetRawConfig()
11491177
getRawConfigAvailable := !rawConfig.IsNull()
11501178

1151-
tflog.Debug(ctx, "Read: enable_default_user - checking GetRawConfig availability", map[string]interface{}{
1152-
"region": region,
1153-
"getRawConfigAvailable": getRawConfigAvailable,
1154-
"globalValue": globalEnableDefaultUser,
1155-
"regionValue": regionEnableDefaultUser,
1156-
"isDifferent": regionEnableDefaultUser != globalEnableDefaultUser,
1157-
})
1179+
var shouldIncludeField bool
1180+
var decisionReason string
11581181

11591182
if getRawConfigAvailable {
11601183
// GetRawConfig available - use config-based detection
11611184
wasExplicitlySet := isEnableDefaultUserExplicitlySetInConfig(d, region)
11621185

1163-
tflog.Debug(ctx, "Read: Using config-based detection (GetRawConfig available)", map[string]interface{}{
1164-
"region": region,
1165-
"wasExplicitlySet": wasExplicitlySet,
1166-
})
1167-
11681186
if wasExplicitlySet {
1169-
tflog.Debug(ctx, "Read: Setting enable_default_user (explicitly in config)", map[string]interface{}{
1170-
"region": region,
1171-
"value": regionEnableDefaultUser,
1172-
})
1173-
regionDbConfig["enable_default_user"] = regionEnableDefaultUser
1187+
shouldIncludeField = true
1188+
decisionReason = "explicitly set in config"
11741189
} else if regionEnableDefaultUser != globalEnableDefaultUser {
1175-
tflog.Debug(ctx, "Read: Setting enable_default_user (not in config but differs from global)", map[string]interface{}{
1176-
"region": region,
1177-
"value": regionEnableDefaultUser,
1178-
})
1179-
regionDbConfig["enable_default_user"] = regionEnableDefaultUser
1190+
shouldIncludeField = true
1191+
decisionReason = "differs from global (API override)"
11801192
} else {
1181-
tflog.Debug(ctx, "Read: NOT setting enable_default_user (not in config, matches global)", map[string]interface{}{
1182-
"region": region,
1183-
})
1193+
shouldIncludeField = false
1194+
decisionReason = "matches global (inherited)"
11841195
}
11851196
} else {
1186-
// GetRawConfig unavailable (Refresh) - use state preservation
1187-
fieldWasInOldState := stateOverrideRegion["enable_default_user"] != nil
1188-
var oldStateValue interface{}
1189-
if fieldWasInOldState {
1190-
oldStateValue = stateOverrideRegion["enable_default_user"]
1191-
}
1197+
// GetRawConfig unavailable (Refresh) - use GetRawState to check ACTUAL persisted state
1198+
fieldWasInActualState := isEnableDefaultUserInActualPersistedState(d, region)
11921199

1193-
tflog.Debug(ctx, "Read: Using state-based preservation (GetRawConfig unavailable)", map[string]interface{}{
1194-
"region": region,
1195-
"fieldWasInOldState": fieldWasInOldState,
1196-
"oldStateValue": oldStateValue,
1197-
})
1198-
1199-
if fieldWasInOldState {
1200-
// Field was in previous state - preserve it if it still makes sense
1200+
if fieldWasInActualState {
1201+
shouldIncludeField = true
12011202
if regionEnableDefaultUser != globalEnableDefaultUser {
1202-
// Still differs from global - definitely keep it
1203-
tflog.Debug(ctx, "Read: Setting enable_default_user (was in old state, differs from global)", map[string]interface{}{
1204-
"region": region,
1205-
"value": regionEnableDefaultUser,
1206-
})
1207-
regionDbConfig["enable_default_user"] = regionEnableDefaultUser
1203+
decisionReason = "was in state, differs from global"
12081204
} else {
1209-
// Matches global but was in old state - assume user still wants it explicit
1210-
tflog.Debug(ctx, "Read: Setting enable_default_user (was in old state, preserving even though matches global)", map[string]interface{}{
1211-
"region": region,
1212-
"value": regionEnableDefaultUser,
1213-
})
1214-
regionDbConfig["enable_default_user"] = regionEnableDefaultUser
1205+
decisionReason = "was in state, preserving (user explicit)"
12151206
}
12161207
} else {
1217-
// Field was NOT in previous state
12181208
if regionEnableDefaultUser != globalEnableDefaultUser {
1219-
// Not in old state but differs - might be new override
1220-
tflog.Debug(ctx, "Read: Setting enable_default_user (not in old state, but differs from global)", map[string]interface{}{
1221-
"region": region,
1222-
"value": regionEnableDefaultUser,
1223-
})
1224-
regionDbConfig["enable_default_user"] = regionEnableDefaultUser
1209+
shouldIncludeField = true
1210+
decisionReason = "not in state, but differs from global"
12251211
} else {
1226-
// Not in old state and matches global - don't add (inherited)
1227-
tflog.Debug(ctx, "Read: NOT setting enable_default_user (not in old state, matches global)", map[string]interface{}{
1228-
"region": region,
1229-
})
1212+
shouldIncludeField = false
1213+
decisionReason = "not in state, matches global (inherited)"
12301214
}
12311215
}
12321216
}
1217+
1218+
if shouldIncludeField {
1219+
regionDbConfig["enable_default_user"] = regionEnableDefaultUser
1220+
}
1221+
1222+
tflog.Debug(ctx, "Read: enable_default_user decision", map[string]interface{}{
1223+
"region": region,
1224+
"getRawConfigAvailable": getRawConfigAvailable,
1225+
"shouldInclude": shouldIncludeField,
1226+
"value": regionEnableDefaultUser,
1227+
"reason": decisionReason,
1228+
})
12331229
}
12341230

12351231
tflog.Debug(ctx, "Read: Completed region config", map[string]interface{}{

0 commit comments

Comments
 (0)