Merge pull request #29398 from hashicorp/jbardin/diff-nested-attrs
Empty nested attribute handling in diffs
This commit is contained in:
commit
bd8cae3970
|
@ -471,9 +471,29 @@ func (p *blockBodyDiffPrinter) writeAttrDiff(name string, attrS *configschema.At
|
|||
}
|
||||
|
||||
if attrS.NestedType != nil {
|
||||
renderNested := true
|
||||
|
||||
// If the collection values are empty or null, we render them as single attributes
|
||||
switch attrS.NestedType.Nesting {
|
||||
case configschema.NestingList, configschema.NestingSet, configschema.NestingMap:
|
||||
var oldLen, newLen int
|
||||
if !old.IsNull() && old.IsKnown() {
|
||||
oldLen = old.LengthInt()
|
||||
}
|
||||
if !new.IsNull() && new.IsKnown() {
|
||||
newLen = new.LengthInt()
|
||||
}
|
||||
|
||||
if oldLen+newLen == 0 {
|
||||
renderNested = false
|
||||
}
|
||||
}
|
||||
|
||||
if renderNested {
|
||||
p.writeNestedAttrDiff(name, attrS.NestedType, old, new, nameLen, indent, path, action, showJustNew)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
p.buf.WriteString("\n")
|
||||
|
||||
|
@ -613,6 +633,7 @@ func (p *blockBodyDiffPrinter) writeNestedAttrDiff(
|
|||
allItems := make([]cty.Value, 0, len(oldItems)+len(newItems))
|
||||
allItems = append(allItems, oldItems...)
|
||||
allItems = append(allItems, newItems...)
|
||||
|
||||
all := cty.SetVal(allItems)
|
||||
|
||||
p.buf.WriteString(" = [")
|
||||
|
@ -625,11 +646,11 @@ func (p *blockBodyDiffPrinter) writeNestedAttrDiff(
|
|||
case !val.IsKnown():
|
||||
action = plans.Update
|
||||
newValue = val
|
||||
case !old.HasElement(val).True():
|
||||
case old.IsNull() || !old.HasElement(val).True():
|
||||
action = plans.Create
|
||||
oldValue = cty.NullVal(val.Type())
|
||||
newValue = val
|
||||
case !new.HasElement(val).True():
|
||||
case new.IsNull() || !new.HasElement(val).True():
|
||||
action = plans.Delete
|
||||
oldValue = val
|
||||
newValue = cty.NullVal(val.Type())
|
||||
|
|
|
@ -2861,6 +2861,97 @@ func TestResourceChange_nestedSet(t *testing.T) {
|
|||
- volume_type = "gp2" -> null
|
||||
}
|
||||
}
|
||||
`,
|
||||
},
|
||||
"in-place update - empty nested sets": {
|
||||
Action: plans.Update,
|
||||
Mode: addrs.ManagedResourceMode,
|
||||
Before: cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||
"ami": cty.StringVal("ami-BEFORE"),
|
||||
"disks": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{
|
||||
"mount_point": cty.String,
|
||||
"size": cty.String,
|
||||
}))),
|
||||
"root_block_device": cty.SetValEmpty(cty.Object(map[string]cty.Type{
|
||||
"volume_type": cty.String,
|
||||
})),
|
||||
}),
|
||||
After: cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||
"ami": cty.StringVal("ami-AFTER"),
|
||||
"disks": cty.SetValEmpty(cty.Object(map[string]cty.Type{
|
||||
"mount_point": cty.String,
|
||||
"size": cty.String,
|
||||
})),
|
||||
"root_block_device": cty.SetValEmpty(cty.Object(map[string]cty.Type{
|
||||
"volume_type": cty.String,
|
||||
})),
|
||||
}),
|
||||
RequiredReplace: cty.NewPathSet(),
|
||||
Schema: testSchema(configschema.NestingSet),
|
||||
ExpectedOutput: ` # test_instance.example will be updated in-place
|
||||
~ resource "test_instance" "example" {
|
||||
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
||||
+ disks = []
|
||||
id = "i-02ae66f368e8518a9"
|
||||
}
|
||||
`,
|
||||
},
|
||||
"in-place update - null insertion": {
|
||||
Action: plans.Update,
|
||||
Mode: addrs.ManagedResourceMode,
|
||||
Before: cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||
"ami": cty.StringVal("ami-BEFORE"),
|
||||
"disks": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{
|
||||
"mount_point": cty.String,
|
||||
"size": cty.String,
|
||||
}))),
|
||||
"root_block_device": cty.SetVal([]cty.Value{
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"volume_type": cty.StringVal("gp2"),
|
||||
"new_field": cty.NullVal(cty.String),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
After: cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||
"ami": cty.StringVal("ami-AFTER"),
|
||||
"disks": cty.SetVal([]cty.Value{
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"mount_point": cty.StringVal("/var/diska"),
|
||||
"size": cty.StringVal("50GB"),
|
||||
}),
|
||||
}),
|
||||
"root_block_device": cty.SetVal([]cty.Value{
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"volume_type": cty.StringVal("gp2"),
|
||||
"new_field": cty.StringVal("new_value"),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
RequiredReplace: cty.NewPathSet(),
|
||||
Schema: testSchemaPlus(configschema.NestingSet),
|
||||
ExpectedOutput: ` # test_instance.example will be updated in-place
|
||||
~ resource "test_instance" "example" {
|
||||
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
||||
+ disks = [
|
||||
+ {
|
||||
+ mount_point = "/var/diska"
|
||||
+ size = "50GB"
|
||||
},
|
||||
]
|
||||
id = "i-02ae66f368e8518a9"
|
||||
|
||||
+ root_block_device {
|
||||
+ new_field = "new_value"
|
||||
+ volume_type = "gp2"
|
||||
}
|
||||
- root_block_device {
|
||||
- volume_type = "gp2" -> null
|
||||
}
|
||||
}
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue