Skip to content

Commit b321ce0

Browse files
committed
chore(origin): refactor the refresh function
1 parent 62f4616 commit b321ce0

7 files changed

+945
-106
lines changed

huaweicloud/services/evs/resource_huaweicloud_evs_snapshot.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,11 @@ func ResourceEvsSnapshot() *schema.Resource {
8787
Computed: true,
8888
},
8989
"metadata_origin": {
90-
Type: schema.TypeMap,
91-
Computed: true,
92-
Elem: &schema.Schema{Type: schema.TypeString},
90+
Type: schema.TypeMap,
91+
Optional: true,
92+
Computed: true,
93+
Elem: &schema.Schema{Type: schema.TypeString},
94+
DiffSuppressFunc: utils.SuppressDiffAll,
9395
Description: utils.SchemaDesc(
9496
`The script configuration value of this change is also the original value used for comparison with
9597
the new value next time the change is made. The corresponding parameter name is 'metadata'.`,

huaweicloud/services/evs/resource_huaweicloud_evsv3_snapshot.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,11 @@ func ResourceV3Snapshot() *schema.Resource {
9797
Computed: true,
9898
},
9999
"metadata_origin": {
100-
Type: schema.TypeMap,
101-
Computed: true,
102-
Elem: &schema.Schema{Type: schema.TypeString},
100+
Type: schema.TypeMap,
101+
Optional: true,
102+
Computed: true,
103+
Elem: &schema.Schema{Type: schema.TypeString},
104+
DiffSuppressFunc: utils.SuppressDiffAll,
103105
Description: utils.SchemaDesc(
104106
`The script configuration value of this change is also the original value used for
105107
comparison with the new value next time the change is made. The corresponding parameter name is

huaweicloud/services/fgs/resource_huaweicloud_fgs_function.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,7 @@ CIDR blocks used by the service.`,
596596
"lts_custom_tag": {
597597
Type: schema.TypeMap,
598598
Optional: true,
599+
Computed: true,
599600
Elem: &schema.Schema{Type: schema.TypeString},
600601
DiffSuppressFunc: utils.SuppressMapDiffs(),
601602
// The custom tags can be set to empty, so computed behavior cannot be supported.
@@ -644,9 +645,11 @@ CIDR blocks used by the service.`,
644645
Description: `The version of the function.`,
645646
},
646647
"lts_custom_tag_origin": {
647-
Type: schema.TypeMap,
648-
Computed: true,
649-
Elem: &schema.Schema{Type: schema.TypeString},
648+
Type: schema.TypeMap,
649+
Optional: true,
650+
Computed: true,
651+
Elem: &schema.Schema{Type: schema.TypeString},
652+
DiffSuppressFunc: utils.SuppressDiffAll,
650653
Description: utils.SchemaDesc(
651654
`The script configuration value of this change is also the original value used for comparison with
652655
the new value next time the change is made. The corresponding parameter name is 'lts_custom_tag'.`,

huaweicloud/utils/diff_suppress_funcs.go renamed to huaweicloud/utils/resource_diff_funcs.go

Lines changed: 130 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package utils
22

33
import (
44
"bytes"
5+
"context"
56
"encoding/base64"
67
"encoding/json"
78
"fmt"
@@ -12,10 +13,26 @@ import (
1213
"strings"
1314
"time"
1415

16+
"github.com/hashicorp/go-multierror"
1517
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1618
awspolicy "github.com/jen20/awspolicyequivalence"
1719
)
1820

21+
// ComposeAnyCustomDiffFunc allows parameters to determine multiple customDiff methods.
22+
// When any method (CustomizeDiffFunc) returns an error, this compose function will record this error and return finally.
23+
func ComposeAnyCustomDiffFunc(fs ...schema.CustomizeDiffFunc) schema.CustomizeDiffFunc {
24+
return func(ctx context.Context, d *schema.ResourceDiff, meta interface{}) error {
25+
var mErr *multierror.Error
26+
27+
for _, f := range fs {
28+
if err := f(ctx, d, meta); err != nil {
29+
mErr = multierror.Append(mErr, err)
30+
}
31+
}
32+
return mErr.ErrorOrNil()
33+
}
34+
}
35+
1936
// ComposeAnySchemaDiffSuppressFunc allows parameters to determine multiple Diff methods.
2037
// When any method (SchemaDiffSuppressFunc) returns true, this compose function will return true.
2138
// It will only return false when all methods (SchemaDiffSuppressFunc) return false.
@@ -319,39 +336,130 @@ func diffObjectParam(paramKey, _, _ string, d *schema.ResourceData) bool {
319336

320337
func SuppressMapDiffs() schema.SchemaDiffSuppressFunc {
321338
return func(paramKey, o, n string, d *schema.ResourceData) bool {
339+
log.Printf("[DEBUG] SuppressMapDiffs: called with paramKey='%s', old='%s', new='%s'", paramKey, o, n)
340+
341+
// Ignore length change judgment, because this method will judge each changed key one by one
322342
if strings.HasSuffix(paramKey, ".%") {
323-
// Ignore the length judgment, because this method will judge each changed key one by one.
343+
log.Printf("[DEBUG] SuppressMapDiffs: ignoring length change for '%s'", paramKey)
324344
return true
325345
}
326-
if n != "" {
327-
log.Printf("[DEBUG] The new value is found and report this change directly, the value is: %s", n)
328-
// When the new value is not empty and the key is in the *terraform.InstanceDiff.Attributes list, it means
329-
// that the value has been modified compared to the value returned by the console, report this change
330-
// directly.
346+
347+
// Handle the case where the entire map is being changed
348+
if !strings.Contains(paramKey, ".") {
349+
return suppressEntireMapDiff(paramKey, d)
350+
}
351+
352+
// Handle single key changes
353+
return suppressSingleKeyDiff(paramKey, d)
354+
}
355+
}
356+
357+
// suppressEntireMapDiff handles changes to the entire map
358+
func suppressEntireMapDiff(paramKey string, d *schema.ResourceData) bool {
359+
originMapCategory := fmt.Sprintf("%s_origin", paramKey)
360+
log.Printf("[DEBUG] SuppressMapDiffs: handling entire map change for '%s', origin map category: '%s'",
361+
paramKey, originMapCategory)
362+
363+
originMapVal := d.Get(originMapCategory)
364+
if originMapVal == nil {
365+
log.Printf("[DEBUG] SuppressMapDiffs: origin map '%s' is nil, suppressing diff for entire map '%s'",
366+
originMapCategory, paramKey)
367+
return true
368+
}
369+
370+
originMap := TryMapValueAnalysis(originMapVal)
371+
if len(originMap) == 0 {
372+
log.Printf("[DEBUG] SuppressMapDiffs: origin map '%s' is empty, suppressing diff for entire map '%s'",
373+
originMapCategory, paramKey)
374+
return true
375+
}
376+
377+
// For entire map changes, we need to check if all keys in the new value exist in origin
378+
// This is a simplified approach - in practice, you might want more sophisticated comparison
379+
log.Printf("[DEBUG] SuppressMapDiffs: entire map '%s' change detected, checking against origin", paramKey)
380+
return false // For now, report the change and let individual key suppression handle it
381+
}
382+
383+
// suppressSingleKeyDiff handles changes to a single key
384+
func suppressSingleKeyDiff(paramKey string, d *schema.ResourceData) bool {
385+
categories := strings.Split(paramKey, ".")
386+
mapCategory := strings.Join(categories[:len(categories)-1], ".")
387+
originMapCategory := fmt.Sprintf("%s_origin", mapCategory)
388+
keyName := categories[len(categories)-1]
389+
390+
log.Printf("[DEBUG] SuppressMapDiffs: processing key '%s', mapCategory='%s', originMapCategory='%s', keyName='%s'",
391+
paramKey, mapCategory, originMapCategory, keyName)
392+
393+
// Get origin map (last local configuration)
394+
originMapVal := d.Get(originMapCategory)
395+
originMap := TryMapValueAnalysis(originMapVal)
396+
log.Printf("[DEBUG] SuppressMapDiffs: origin map '%s' content: %+v", originMapCategory, originMap)
397+
398+
// Get current configuration map
399+
currentMapVal := d.Get(mapCategory)
400+
if currentMapVal == nil {
401+
log.Printf("[DEBUG] SuppressMapDiffs: current map '%s' is nil, suppressing diff for key '%s'",
402+
mapCategory, keyName)
403+
return true
404+
}
405+
406+
currentMap := TryMapValueAnalysis(currentMapVal)
407+
log.Printf("[DEBUG] SuppressMapDiffs: current map '%s' content: %+v", mapCategory, currentMap)
408+
409+
// Check if the key exists in current configuration
410+
existsInCurrent := keyExists(currentMap, keyName)
411+
existsInOrigin := keyExists(originMap, keyName)
412+
isOriginEmpty := originMapVal == nil || len(originMap) == 0
413+
414+
// Determine suppression based on key existence
415+
return determineSuppression(existsInCurrent, existsInOrigin, isOriginEmpty, keyName)
416+
}
417+
418+
// keyExists checks if a key exists in the map
419+
func keyExists(m map[string]interface{}, key string) bool {
420+
_, exists := m[key]
421+
return exists
422+
}
423+
424+
// determineSuppression determines whether to suppress the diff based on key existence
425+
func determineSuppression(existsInCurrent, existsInOrigin, isOriginEmpty bool, keyName string) bool {
426+
if existsInCurrent {
427+
// The key exists in current configuration
428+
if isOriginEmpty {
429+
// Origin is empty or nil, report the change (locally added)
430+
log.Printf("[DEBUG][SuppressMapDiffs] The key '%s' found in current config but origin is empty", keyName)
331431
return false
332432
}
333433

334-
var (
335-
// The absolute path of the current key.
336-
categories = strings.Split(paramKey, ".")
337-
mapCategory = strings.Join(categories[:len(categories)-1], ".")
338-
originMapCategory = fmt.Sprintf("%s_origin", mapCategory)
339-
keyName = categories[len(categories)-1]
340-
)
341-
342-
originMap, ok := d.Get(originMapCategory).(map[string]interface{})
343-
if !ok {
344-
log.Printf("[WARN] Unable to find corresponding origin parameter (%s) in current category, please check your schema definition",
345-
originMapCategory)
434+
if existsInOrigin {
435+
// The key exists in both current config and origin, report this change
436+
log.Printf("[DEBUG][SuppressMapDiffs] The key '%s' found in both current config and origin", keyName)
437+
return false
438+
} else {
439+
// The key exists in current config but not in origin (locally added)
440+
log.Printf("[DEBUG][SuppressMapDiffs] The key '%s' found in current config but not in origin", keyName)
441+
return false
442+
}
443+
} else {
444+
// The key does not exist in current configuration
445+
if isOriginEmpty {
446+
// Origin is empty or nil, suppress the diff (remotely added)
447+
log.Printf("[DEBUG][SuppressMapDiffs] The key '%s' not found in current config and origin is empty, suppressing diff",
448+
keyName)
346449
return true
347450
}
348451

349-
if _, ok := originMap[keyName]; ok {
350-
// The key is found in the origin parameter value and report this change directly.
452+
if existsInOrigin {
453+
// The key exists in origin but not in current config (locally removed)
454+
log.Printf("[DEBUG][SuppressMapDiffs] The key '%s' found in origin but not in current config (locally removed)",
455+
keyName)
351456
return false
457+
} else {
458+
// The key does not exist in either current config or origin (remotely added)
459+
log.Printf("[DEBUG][SuppressMapDiffs] The key '%s' not found in either current config or origin (remotely added), suppressing diff",
460+
keyName)
461+
return true
352462
}
353-
// The relevant value is not configured locally, and the change is ignored.
354-
return true
355463
}
356464
}
357465

0 commit comments

Comments
 (0)