Merge pull request #17127 from hashicorp/jbardin/ignore_changes
don't ignore partial containers in diffs
This commit is contained in:
commit
d29994e247
|
@ -396,11 +396,6 @@ type ResourceAttrDiff struct {
|
||||||
Type DiffAttrType
|
Type DiffAttrType
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modified returns the inequality of Old and New for this attr
|
|
||||||
func (d *ResourceAttrDiff) Modified() bool {
|
|
||||||
return d.Old != d.New
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty returns true if the diff for this attr is neutral
|
// Empty returns true if the diff for this attr is neutral
|
||||||
func (d *ResourceAttrDiff) Empty() bool {
|
func (d *ResourceAttrDiff) Empty() bool {
|
||||||
return d.Old == d.New && !d.NewComputed && !d.NewRemoved
|
return d.Old == d.New && !d.NewComputed && !d.NewRemoved
|
||||||
|
|
|
@ -256,13 +256,15 @@ func (n *EvalDiff) processIgnoreChanges(diff *InstanceDiff) error {
|
||||||
containers := groupContainers(diff)
|
containers := groupContainers(diff)
|
||||||
keep := map[string]bool{}
|
keep := map[string]bool{}
|
||||||
for _, v := range containers {
|
for _, v := range containers {
|
||||||
if v.keepDiff() {
|
if v.keepDiff(ignorableAttrKeys) {
|
||||||
// At least one key has changes, so list all the sibling keys
|
// At least one key has changes, so list all the sibling keys
|
||||||
// to keep in the diff if any values have changed
|
// to keep in the diff
|
||||||
for k := range v {
|
for k := range v {
|
||||||
if v[k].Modified() {
|
|
||||||
keep[k] = true
|
keep[k] = true
|
||||||
}
|
// this key may have been added by the user to ignore, but
|
||||||
|
// if it's a subkey in a container, we need to un-ignore it
|
||||||
|
// to keep the complete containter.
|
||||||
|
delete(ignorableAttrKeys, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -294,10 +296,17 @@ func (n *EvalDiff) processIgnoreChanges(diff *InstanceDiff) error {
|
||||||
// a group of key-*ResourceAttrDiff pairs from the same flatmapped container
|
// a group of key-*ResourceAttrDiff pairs from the same flatmapped container
|
||||||
type flatAttrDiff map[string]*ResourceAttrDiff
|
type flatAttrDiff map[string]*ResourceAttrDiff
|
||||||
|
|
||||||
// we need to keep all keys if any of them have a diff
|
// we need to keep all keys if any of them have a diff that's not ignored
|
||||||
func (f flatAttrDiff) keepDiff() bool {
|
func (f flatAttrDiff) keepDiff(ignoreChanges map[string]bool) bool {
|
||||||
for _, v := range f {
|
for k, v := range f {
|
||||||
if !v.Empty() && !v.NewComputed {
|
ignore := false
|
||||||
|
for attr := range ignoreChanges {
|
||||||
|
if strings.HasPrefix(k, attr) {
|
||||||
|
ignore = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.Empty() && !v.NewComputed && !ignore {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package terraform
|
package terraform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -79,7 +80,7 @@ func TestEvalFilterDiff(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestProcessIgnoreChangesOnResourceIgnoredWithRequiresNew(t *testing.T) {
|
func TestProcessIgnoreChanges(t *testing.T) {
|
||||||
var evalDiff *EvalDiff
|
var evalDiff *EvalDiff
|
||||||
var instanceDiff *InstanceDiff
|
var instanceDiff *InstanceDiff
|
||||||
|
|
||||||
|
@ -94,53 +95,84 @@ func TestProcessIgnoreChangesOnResourceIgnoredWithRequiresNew(t *testing.T) {
|
||||||
&InstanceDiff{
|
&InstanceDiff{
|
||||||
Destroy: true,
|
Destroy: true,
|
||||||
Attributes: map[string]*ResourceAttrDiff{
|
Attributes: map[string]*ResourceAttrDiff{
|
||||||
|
"resource.%": {
|
||||||
|
Old: "3",
|
||||||
|
New: "3",
|
||||||
|
},
|
||||||
"resource.changed": {
|
"resource.changed": {
|
||||||
RequiresNew: true,
|
RequiresNew: true,
|
||||||
Type: DiffAttrInput,
|
Type: DiffAttrInput,
|
||||||
Old: "old",
|
Old: "old",
|
||||||
New: "new",
|
New: "new",
|
||||||
},
|
},
|
||||||
"resource.unchanged": {
|
"resource.maybe": {
|
||||||
Old: "unchanged",
|
Old: "",
|
||||||
New: newAttribute,
|
New: newAttribute,
|
||||||
},
|
},
|
||||||
|
"resource.same": {
|
||||||
|
Old: "same",
|
||||||
|
New: "same",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
evalDiff, instanceDiff = testDiffs([]string{"resource.changed"}, "unchanged")
|
for i, tc := range []struct {
|
||||||
|
ignore []string
|
||||||
|
newAttr string
|
||||||
|
attrDiffs int
|
||||||
|
}{
|
||||||
|
// attr diffs should be all (4), or nothing
|
||||||
|
{
|
||||||
|
ignore: []string{"resource.changed"},
|
||||||
|
attrDiffs: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ignore: []string{"resource.changed"},
|
||||||
|
newAttr: "new",
|
||||||
|
attrDiffs: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
attrDiffs: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ignore: []string{"resource.maybe"},
|
||||||
|
newAttr: "new",
|
||||||
|
attrDiffs: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
newAttr: "new",
|
||||||
|
attrDiffs: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ignore: []string{"resource"},
|
||||||
|
newAttr: "new",
|
||||||
|
attrDiffs: 0,
|
||||||
|
},
|
||||||
|
// extra ignored values shouldn't effect the diff
|
||||||
|
{
|
||||||
|
ignore: []string{"resource.missing", "resource.maybe"},
|
||||||
|
newAttr: "new",
|
||||||
|
attrDiffs: 4,
|
||||||
|
},
|
||||||
|
// this isn't useful, but make sure it doesn't break
|
||||||
|
{
|
||||||
|
ignore: []string{"resource.%"},
|
||||||
|
attrDiffs: 4,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
||||||
|
evalDiff, instanceDiff = testDiffs(tc.ignore, tc.newAttr)
|
||||||
err := evalDiff.processIgnoreChanges(instanceDiff)
|
err := evalDiff.processIgnoreChanges(instanceDiff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
if len(instanceDiff.Attributes) > 0 {
|
if len(instanceDiff.Attributes) != tc.attrDiffs {
|
||||||
t.Fatalf("Expected all resources to be ignored, found %d", len(instanceDiff.Attributes))
|
t.Errorf("expected %d diffs, found %d", tc.attrDiffs, len(instanceDiff.Attributes))
|
||||||
}
|
for k, attr := range instanceDiff.Attributes {
|
||||||
|
fmt.Printf(" %s:%#v\n", k, attr)
|
||||||
evalDiff, instanceDiff = testDiffs([]string{}, "unchanged")
|
}
|
||||||
err = evalDiff.processIgnoreChanges(instanceDiff)
|
}
|
||||||
if err != nil {
|
})
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
if len(instanceDiff.Attributes) != 2 {
|
|
||||||
t.Fatalf("Expected 2 resources to be found, found %d", len(instanceDiff.Attributes))
|
|
||||||
}
|
|
||||||
|
|
||||||
evalDiff, instanceDiff = testDiffs([]string{"resource.changed"}, "changed")
|
|
||||||
err = evalDiff.processIgnoreChanges(instanceDiff)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
if len(instanceDiff.Attributes) != 1 {
|
|
||||||
t.Fatalf("Expected 1 resource to be found, found %d", len(instanceDiff.Attributes))
|
|
||||||
}
|
|
||||||
|
|
||||||
evalDiff, instanceDiff = testDiffs([]string{}, "changed")
|
|
||||||
err = evalDiff.processIgnoreChanges(instanceDiff)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
if len(instanceDiff.Attributes) != 2 {
|
|
||||||
t.Fatalf("Expected 2 resource to be found, found %d", len(instanceDiff.Attributes))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1675,7 +1675,10 @@ aws_instance.foo:
|
||||||
const testTFPlanDiffIgnoreChangesWithFlatmaps = `
|
const testTFPlanDiffIgnoreChangesWithFlatmaps = `
|
||||||
UPDATE: aws_instance.foo
|
UPDATE: aws_instance.foo
|
||||||
lst.#: "1" => "2"
|
lst.#: "1" => "2"
|
||||||
|
lst.0: "j" => "j"
|
||||||
lst.1: "" => "k"
|
lst.1: "" => "k"
|
||||||
|
set.#: "1" => "1"
|
||||||
|
set.0.a: "1" => "1"
|
||||||
set.0.b: "" => "2"
|
set.0.b: "" => "2"
|
||||||
type: "" => "aws_instance"
|
type: "" => "aws_instance"
|
||||||
`
|
`
|
||||||
|
|
Loading…
Reference in New Issue