Merge pull request #7249 from hashicorp/jbardin/GH-7244

core: don't compare map diffs for computed values
This commit is contained in:
James Bardin 2016-06-27 11:19:59 -04:00 committed by GitHub
commit b80c2f76f6
2 changed files with 44 additions and 10 deletions

View File

@ -471,12 +471,12 @@ func (d *InstanceDiff) Same(d2 *InstanceDiff) (bool, string) {
}
}
// This is a little tricky, but when a diff contains a computed list
// or set that can only be interpolated after the apply command has
// created the dependent resources, it could turn out that the result
// is actually the same as the existing state which would remove the
// key from the diff.
if diffOld.NewComputed && strings.HasSuffix(k, ".#") {
// This is a little tricky, but when a diff contains a computed
// list, set, or map that can only be interpolated after the apply
// command has created the dependent resources, it could turn out
// that the result is actually the same as the existing state which
// would remove the key from the diff.
if diffOld.NewComputed && (strings.HasSuffix(k, ".#") || strings.HasSuffix(k, ".%")) {
ok = true
}
@ -492,10 +492,16 @@ func (d *InstanceDiff) Same(d2 *InstanceDiff) (bool, string) {
}
}
if diffOld.NewComputed && strings.HasSuffix(k, ".#") {
// This is a computed list or set, so remove any keys with this
// prefix from the check list.
kprefix := k[:len(k)-1]
// search for the suffix of the base of a [computed] map, list or set.
multiVal := regexp.MustCompile(`\.(#|~#|%)$`)
match := multiVal.FindStringSubmatch(k)
if diffOld.NewComputed && len(match) == 2 {
matchLen := len(match[1])
// This is a computed list, set, or map, so remove any keys with
// this prefix from the check list.
kprefix := k[:len(k)-matchLen]
for k2, _ := range checkOld {
if strings.HasPrefix(k2, kprefix) {
delete(checkOld, k2)

View File

@ -566,6 +566,34 @@ func TestInstanceDiffSame(t *testing.T) {
"",
},
// Computed values in maps will fail the "Same" check as well
{
&InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"foo.%": &ResourceAttrDiff{
Old: "",
New: "",
NewComputed: true,
},
},
},
&InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"foo.%": &ResourceAttrDiff{
Old: "0",
New: "1",
NewComputed: false,
},
"foo.val": &ResourceAttrDiff{
Old: "",
New: "something",
},
},
},
true,
"",
},
// In a DESTROY/CREATE scenario, the plan diff will be run against the
// state of the old instance, while the apply diff will be run against an
// empty state (because the state is cleared when the destroy runs.)