more precise handling of removed list elements
When elements are removed from a list, all attributes may not be present in the diff. Once the individual attributes diffs are applied, use the length to truncate the flatmapped list to the correct length.
This commit is contained in:
parent
3b04b41250
commit
6f7e1ff8eb
|
@ -4,6 +4,7 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -494,11 +495,12 @@ func (d *InstanceDiff) applyBlockDiff(path []string, attrs map[string]string, sc
|
||||||
// we need to find the set of all keys that traverse this block
|
// we need to find the set of all keys that traverse this block
|
||||||
candidateKeys := map[string]bool{}
|
candidateKeys := map[string]bool{}
|
||||||
blockKey := blockPrefix + n + "."
|
blockKey := blockPrefix + n + "."
|
||||||
|
localBlockPrefix := localPrefix + n + "."
|
||||||
|
|
||||||
// we can only trust the diff for sets, since the path changes, so don't
|
// we can only trust the diff for sets, since the path changes, so don't
|
||||||
// count existing values as candidate keys. If it turns out we're
|
// count existing values as candidate keys. If it turns out we're
|
||||||
// keeping the attributes, we will check catch it down below with
|
// keeping the attributes, we will catch it down below with "keepBlock"
|
||||||
// "keepBlock" after we check the set count.
|
// after we check the set count.
|
||||||
if block.Nesting != configschema.NestingSet {
|
if block.Nesting != configschema.NestingSet {
|
||||||
for k := range attrs {
|
for k := range attrs {
|
||||||
if strings.HasPrefix(k, blockKey) {
|
if strings.HasPrefix(k, blockKey) {
|
||||||
|
@ -570,7 +572,7 @@ func (d *InstanceDiff) applyBlockDiff(path []string, attrs map[string]string, sc
|
||||||
}
|
}
|
||||||
|
|
||||||
for attr, v := range newAttrs {
|
for attr, v := range newAttrs {
|
||||||
result[localPrefix+n+"."+attr] = v
|
result[localBlockPrefix+attr] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,24 +591,51 @@ func (d *InstanceDiff) applyBlockDiff(path []string, attrs map[string]string, sc
|
||||||
if strings.HasPrefix(k, blockKey) {
|
if strings.HasPrefix(k, blockKey) {
|
||||||
// we need the key relative to this block, so remove the
|
// we need the key relative to this block, so remove the
|
||||||
// entire prefix, then re-insert the block name.
|
// entire prefix, then re-insert the block name.
|
||||||
localKey := n + "." + k[len(blockKey):]
|
localKey := localBlockPrefix + k[len(blockKey):]
|
||||||
|
|
||||||
result[localKey] = v
|
result[localKey] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if countDiff, ok := d.Attributes[strings.Join(append(path, n, ".#"), ".")]; ok {
|
if countDiff, ok := d.Attributes[strings.Join(append(path, n, "#"), ".")]; ok {
|
||||||
|
|
||||||
if countDiff.NewComputed {
|
if countDiff.NewComputed {
|
||||||
result[localPrefix+n+".#"] = hcl2shim.UnknownVariableValue
|
result[localBlockPrefix+"#"] = hcl2shim.UnknownVariableValue
|
||||||
} else {
|
} else {
|
||||||
result[localPrefix+n+".#"] = countDiff.New
|
result[localBlockPrefix+"#"] = countDiff.New
|
||||||
|
|
||||||
|
// While sets are complete, list are not, and we may not have all the
|
||||||
|
// information to track removals. If the list was truncated, we need to
|
||||||
|
// remove the extra items from the result.
|
||||||
|
if block.Nesting == configschema.NestingList &&
|
||||||
|
countDiff.New != "" && countDiff.New != hcl2shim.UnknownVariableValue {
|
||||||
|
length, _ := strconv.Atoi(countDiff.New)
|
||||||
|
for k := range result {
|
||||||
|
if !strings.HasPrefix(k, localBlockPrefix) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
index := k[len(localBlockPrefix):]
|
||||||
|
nextDot := strings.Index(index, ".")
|
||||||
|
if nextDot < 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
index = index[:nextDot]
|
||||||
|
i, err := strconv.Atoi(index)
|
||||||
|
if err != nil {
|
||||||
|
// this shouldn't happen since we added these
|
||||||
|
// ourself, but make note of it just in case.
|
||||||
|
log.Printf("[ERROR] bas list index in %q: %s", k, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i >= length {
|
||||||
|
delete(result, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result[localPrefix+n+".#"] = countFlatmapContainerValues(localPrefix+n+".#", result)
|
result[localBlockPrefix+"#"] = countFlatmapContainerValues(localBlockPrefix+"#", result)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
|
|
Loading…
Reference in New Issue