Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions huaweicloud/services/evs/resource_huaweicloud_evs_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,11 @@ func ResourceEvsSnapshot() *schema.Resource {
Computed: true,
},
"metadata_origin": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Type: schema.TypeMap,
Optional: true,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
DiffSuppressFunc: utils.SuppressDiffAll,
Description: utils.SchemaDesc(
`The script configuration value of this change is also the original value used for comparison with
the new value next time the change is made. The corresponding parameter name is 'metadata'.`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,11 @@ func ResourceV3Snapshot() *schema.Resource {
Computed: true,
},
"metadata_origin": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Type: schema.TypeMap,
Optional: true,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
DiffSuppressFunc: utils.SuppressDiffAll,
Description: utils.SchemaDesc(
`The script configuration value of this change is also the original value used for
comparison with the new value next time the change is made. The corresponding parameter name is
Expand Down
9 changes: 6 additions & 3 deletions huaweicloud/services/fgs/resource_huaweicloud_fgs_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ CIDR blocks used by the service.`,
"lts_custom_tag": {
Type: schema.TypeMap,
Optional: true,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
DiffSuppressFunc: utils.SuppressMapDiffs(),
// The custom tags can be set to empty, so computed behavior cannot be supported.
Expand Down Expand Up @@ -646,9 +647,11 @@ CIDR blocks used by the service.`,
Description: `The version of the function.`,
},
"lts_custom_tag_origin": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Type: schema.TypeMap,
Optional: true,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
DiffSuppressFunc: utils.SuppressDiffAll,
Description: utils.SchemaDesc(
`The script configuration value of this change is also the original value used for comparison with
the new value next time the change is made. The corresponding parameter name is 'lts_custom_tag'.`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,40 +319,131 @@ func diffObjectParam(paramKey, _, _ string, d *schema.ResourceData) bool {

func SuppressMapDiffs() schema.SchemaDiffSuppressFunc {
return func(paramKey, o, n string, d *schema.ResourceData) bool {
log.Printf("[DEBUG][SuppressMapDiffs] Called with paramKey='%s', old='%s', new='%s'", paramKey, o, n)

// Ignore length change judgment, because this method will judge each changed key one by one
if strings.HasSuffix(paramKey, ".%") {
// Ignore the length judgment, because this method will judge each changed key one by one.
log.Printf("[DEBUG][SuppressMapDiffs] Ignoring length change for '%s'", paramKey)
return true
}
if n != "" {
log.Printf("[DEBUG] The new value is found and report this change directly, the value is: %s", n)
// When the new value is not empty and the key is in the *terraform.InstanceDiff.Attributes list, it means
// that the value has been modified compared to the value returned by the console, report this change
// directly.
return false

// Handle the case where the entire map is being changed
if !strings.Contains(paramKey, ".") {
return suppressEntireMapDiff(paramKey, d)
}

var (
// The absolute path of the current key.
categories = strings.Split(paramKey, ".")
mapCategory = strings.Join(categories[:len(categories)-1], ".")
originMapCategory = fmt.Sprintf("%s_origin", mapCategory)
keyName = categories[len(categories)-1]
)

originMap, ok := d.Get(originMapCategory).(map[string]interface{})
if !ok {
log.Printf("[WARN] Unable to find corresponding origin parameter (%s) in current category, please check your schema definition",
originMapCategory)
return true
// Handle single key changes
return suppressSingleKeyDiff(paramKey, d)
}
}

// suppressEntireMapDiff handles changes to the entire map
func suppressEntireMapDiff(paramKey string, d *schema.ResourceData) bool {
originMapCategory := fmt.Sprintf("%s_origin", paramKey)
log.Printf("[DEBUG][EntireMapDiff] Handling entire map change for '%s', origin map category: '%s'",
paramKey, originMapCategory)

originMapVal := d.Get(originMapCategory)
if originMapVal == nil {
log.Printf("[DEBUG][EntireMapDiff] Origin map '%s' is nil, suppressing diff for entire map '%s'",
originMapCategory, paramKey)
return true
}

originMap := TryMapValueAnalysis(originMapVal)
if len(originMap) == 0 {
log.Printf("[DEBUG][EntireMapDiff] Origin map '%s' is empty, suppressing diff for entire map '%s'",
originMapCategory, paramKey)
return true
}

// For entire map changes, we need to check if all keys in the new value exist in origin
// This is a simplified approach - in practice, you might want more sophisticated comparison
log.Printf("[DEBUG][EntireMapDiff] Entire map '%s' change detected, checking against origin", paramKey)
return false // For now, report the change and let individual key suppression handle it
}

// suppressSingleKeyDiff handles changes to a single key
func suppressSingleKeyDiff(paramKey string, d *schema.ResourceData) bool {
categories := strings.Split(paramKey, ".")
mapCategory := strings.Join(categories[:len(categories)-1], ".")
originMapCategory := fmt.Sprintf("%s_origin", mapCategory)
keyName := categories[len(categories)-1]

log.Printf("[DEBUG][SingleKeyDiff] Processing key '%s', mapCategory='%s', originMapCategory='%s', keyName='%s'",
paramKey, mapCategory, originMapCategory, keyName)

// Get origin map (last local configuration)
originMapVal := d.Get(originMapCategory)
originMap := TryMapValueAnalysis(originMapVal)
log.Printf("[DEBUG][SingleKeyDiff] Origin map '%s' content: %+v", originMapCategory, originMap)

// Get current configuration map
currentMapVal := GetNestedObjectFromRawConfig(d.GetRawConfig(), mapCategory)
if currentMapVal == nil {
log.Printf("[DEBUG][SingleKeyDiff] Current map '%s' is nil, suppressing diff for key '%s'",
mapCategory, keyName)
return true
}

currentMap := TryMapValueAnalysis(currentMapVal)
log.Printf("[DEBUG][SingleKeyDiff] Current map '%s' content: %+v", mapCategory, currentMap)

// Check if the key exists in current configuration
existsInCurrent := keyExists(currentMap, keyName)
existsInOrigin := keyExists(originMap, keyName)
isOriginEmpty := originMapVal == nil || len(originMap) == 0

// Determine suppression based on key existence
return determineSuppression(existsInCurrent, existsInOrigin, isOriginEmpty, keyName)
}

// keyExists checks if a key exists in the map
func keyExists(m map[string]interface{}, key string) bool {
_, exists := m[key]
return exists
}

// determineSuppression determines whether to suppress the diff based on key existence
func determineSuppression(existsInCurrent, existsInOrigin, isOriginEmpty bool, keyName string) bool {
if existsInCurrent {
// The key exists in current configuration
if isOriginEmpty {
// Origin is empty or nil, report the change (locally added)
log.Printf("[DEBUG] The key '%s' found in current config but origin is empty", keyName)
return false
}

if _, ok := originMap[keyName]; ok {
// The key is found in the origin parameter value and report this change directly.
if existsInOrigin {
// The key exists in both current config and origin, report this change
log.Printf("[DEBUG] The key '%s' found in both current config and origin", keyName)
return false
}
// The relevant value is not configured locally, and the change is ignored.

// The key exists in current config but not in origin (locally added)
log.Printf("[DEBUG] The key '%s' found in current config but not in origin", keyName)
return false
}

// The key does not exist in current configuration
if isOriginEmpty {
// Origin is empty or nil, suppress the diff (remotely added)
log.Printf("[DEBUG] The key '%s' not found in current config and origin is empty, suppressing diff",
keyName)
return true
}

if existsInOrigin {
// The key exists in origin but not in current config (locally removed)
log.Printf("[DEBUG] The key '%s' found in origin but not in current config (locally removed)",
keyName)
return false
}

// The key does not exist in either current config or origin (remotely added)
log.Printf("[DEBUG] The key '%s' not found in either current config or origin (remotely added), suppressing diff",
keyName)
return true
}

// TakeObjectsDifferent is a method that used to recursively get the complement of object A (objA) compared to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils"
)

func TestDiffSuppressFunc_ContainsAllKeyValues(t *testing.T) {
func TestResourceDiffunc_ContainsAllKeyValues(t *testing.T) {
var (
compareObject = map[string]interface{}{
"A": map[string]interface{}{
Expand Down Expand Up @@ -81,7 +81,7 @@ func TestDiffSuppressFunc_ContainsAllKeyValues(t *testing.T) {
t.Logf("All processing results of the ContainsAllKeyValues method meets expectation")
}

func TestDiffSuppressFunc_FindDecreaseKeys(t *testing.T) {
func TestResourceDiffunc_FindDecreaseKeys(t *testing.T) {
var (
decreaseCacls = []map[string]interface{}{
{
Expand Down Expand Up @@ -124,7 +124,7 @@ func TestDiffSuppressFunc_FindDecreaseKeys(t *testing.T) {
t.Logf("All processing results of the FindDecreaseKeys method meets expectation")
}

func TestDiffSuppressFunc_TakeObjectsDifferent(t *testing.T) {
func TestResourceDiffunc_TakeObjectsDifferent(t *testing.T) {
var (
diffCacls = []map[string]interface{}{
{
Expand Down
Loading
Loading