Merge pull request #21291 from hashicorp/jbardin/read-empty-containers

only hold back empty container changes in apply
This commit is contained in:
James Bardin 2019-05-13 19:20:07 -04:00 committed by GitHub
commit ea6b5b010a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 12 deletions

View File

@ -1163,27 +1163,24 @@ func normalizeNullValues(dst, src cty.Value, apply bool) cty.Value {
if !src.IsNull() && !src.IsKnown() { if !src.IsNull() && !src.IsKnown() {
// Return src during plan to retain unknown interpolated placeholders, // Return src during plan to retain unknown interpolated placeholders,
// which could be lost if we're only updating a resource. If this is a // which could be lost if we're only updating a resource. If this is a
// read scenario, then there shouldn't be any unknowns all. // read scenario, then there shouldn't be any unknowns at all.
if dst.IsNull() && !apply { if dst.IsNull() && !apply {
return src return src
} }
return dst return dst
} }
// handle null/empty changes for collections // Handle null/empty changes for collections during apply.
if ty.IsCollectionType() { // A change between null and empty values prefers src to make sure the state
if src.IsNull() && !dst.IsNull() && dst.IsKnown() { // is consistent between plan and apply.
if dst.LengthInt() == 0 { if ty.IsCollectionType() && apply {
return src dstEmpty := !dst.IsNull() && dst.IsKnown() && dst.LengthInt() == 0
} srcEmpty := !src.IsNull() && src.IsKnown() && src.LengthInt() == 0
}
if dst.IsNull() && !src.IsNull() && src.IsKnown() { if (src.IsNull() && dstEmpty) || (srcEmpty && dst.IsNull()) {
if src.LengthInt() == 0 {
return src return src
} }
} }
}
if src.IsNull() || !src.IsKnown() || !dst.IsKnown() { if src.IsNull() || !src.IsKnown() || !dst.IsKnown() {
return dst return dst
@ -1214,6 +1211,7 @@ func normalizeNullValues(dst, src cty.Value, apply bool) cty.Value {
} }
dstVal = cty.NullVal(v.Type()) dstVal = cty.NullVal(v.Type())
} }
dstMap[key] = normalizeNullValues(dstVal, v, apply) dstMap[key] = normalizeNullValues(dstVal, v, apply)
} }

View File

@ -1141,6 +1141,41 @@ func TestNormalizeNullValues(t *testing.T) {
}), }),
}), }),
}, },
{
Src: cty.ObjectVal(map[string]cty.Value{
"set": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{
"list": cty.List(cty.String),
}))),
}),
Dst: cty.ObjectVal(map[string]cty.Value{
"set": cty.SetValEmpty(cty.Object(map[string]cty.Type{
"list": cty.List(cty.String),
})),
}),
Expect: cty.ObjectVal(map[string]cty.Value{
"set": cty.SetValEmpty(cty.Object(map[string]cty.Type{
"list": cty.List(cty.String),
})),
}),
},
{
Src: cty.ObjectVal(map[string]cty.Value{
"set": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{
"list": cty.List(cty.String),
}))),
}),
Dst: cty.ObjectVal(map[string]cty.Value{
"set": cty.SetValEmpty(cty.Object(map[string]cty.Type{
"list": cty.List(cty.String),
})),
}),
Expect: cty.ObjectVal(map[string]cty.Value{
"set": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{
"list": cty.List(cty.String),
}))),
}),
Apply: true,
},
} { } {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
got := normalizeNullValues(tc.Dst, tc.Src, tc.Apply) got := normalizeNullValues(tc.Dst, tc.Src, tc.Apply)