mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-29 10:21:01 -06:00
core: Ensure hasComputedSubKeys iterates over Sets and Lists properly
This fixes some edge-ish cases where a set in a config has a set or list in it that contains computed values, but non-set or list values in the parent do not. This can cause "diffs didn't match during apply" errors in a scenario such as when a set's hash is calculated off of child items (including any sub-lists or sets, as it should be), and the hash changes between the plan and apply diffs due to the computed values present in the sub-list or set items. These will be marked as computed, but due to the fact that the function was not iterating over the list or set items properly (ie: not adding the item number to the address, so set.0.set.foo was being yielded instead of set.0.set.0.foo), these computed values were not being properly propagated to the parent set to be marked as computed. Fixes hashicorp/terraform#6527. Fixes hashicorp/terraform#8271. This possibly fixes other non-CloudFront related issues too.
This commit is contained in:
parent
283d49f12f
commit
4d8208d840
@ -265,12 +265,30 @@ func (r *ConfigFieldReader) hasComputedSubKeys(key string, schema *Schema) bool
|
||||
switch t := schema.Elem.(type) {
|
||||
case *Resource:
|
||||
for k, schema := range t.Schema {
|
||||
if r.Config.IsComputed(prefix + k) {
|
||||
addr := prefix + k
|
||||
if r.Config.IsComputed(addr) {
|
||||
return true
|
||||
}
|
||||
|
||||
if r.hasComputedSubKeys(prefix+k, schema) {
|
||||
return true
|
||||
// We need to loop into sets and lists to ensure we pass the correct
|
||||
// address to the raw config - otherwise for sets we get something like
|
||||
// set.0.set.item instead of set.0.set.0.item, which renders an
|
||||
// inaccurate result.
|
||||
if schema.Type == TypeSet || schema.Type == TypeList {
|
||||
raw, err := readListField(&nestedConfigFieldReader{r}, strings.Split(addr, "."), schema)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("readListField failed when field was supposed to be list-like: %v", err))
|
||||
}
|
||||
// Just range into the address space here, we don't need the value.
|
||||
for i := range raw.Value.([]interface{}) {
|
||||
if r.hasComputedSubKeys(addr+"."+strconv.Itoa(i), schema) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if r.hasComputedSubKeys(addr, schema) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user