Skip to content

Commit

Permalink
core: Ensure hasComputedSubKeys iterates over Sets and Lists properly
Browse files Browse the repository at this point in the history
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 #6527.
Fixes #8271.

This possibly fixes other non-CloudFront related issues too.
  • Loading branch information
vancluever committed Oct 10, 2016
1 parent 7642c94 commit 0cc7bcb
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions helper/schema/field_reader_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
}
Expand Down

0 comments on commit 0cc7bcb

Please sign in to comment.