diff --git a/builtin/providers/test/resource_test.go b/builtin/providers/test/resource_test.go index 9277e9f62..5aedba214 100644 --- a/builtin/providers/test/resource_test.go +++ b/builtin/providers/test/resource_test.go @@ -1086,3 +1086,86 @@ resource "test_resource" "foo" { }, }) } + +// Verify we can use use numeric indices in `ignore_changes` paths. +func TestResource_ignoreChangesIndex(t *testing.T) { + resource.UnitTest(t, resource.TestCase{ + Providers: testAccProviders, + CheckDestroy: testAccCheckResourceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: strings.TrimSpace(` +resource "test_resource" "foo" { + required = "yep" + required_map = { + key = "value" + } + list_of_map = [ + { + a = "b" + } + ] + + lifecycle { + ignore_changes = [list_of_map[0]["a"]] + } +} + `), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "test_resource.foo", "list_of_map.0.a", "b", + ), + ), + }, + resource.TestStep{ + Config: strings.TrimSpace(` +resource "test_resource" "foo" { + required = "yep" + required_map = { + key = "value" + } + list_of_map = [ + { + a = "c" + } + ] + + lifecycle { + ignore_changes = [list_of_map[0]["a"]] + } +} + `), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "test_resource.foo", "list_of_map.0.a", "b", + ), + ), + }, + // set ignore_changes to a prefix of the changed value + resource.TestStep{ + Config: strings.TrimSpace(` +resource "test_resource" "foo" { + required = "yep" + required_map = { + key = "value" + } + list_of_map = [ + { + a = "d" + } + ] + + lifecycle { + ignore_changes = [list_of_map[0]] + } +} + `), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "test_resource.foo", "list_of_map.0.a", "b", + ), + ), + }, + }, + }) +} diff --git a/go.mod b/go.mod index 6b0d58cfe..b491d1593 100644 --- a/go.mod +++ b/go.mod @@ -115,7 +115,7 @@ require ( github.com/xanzy/ssh-agent v0.2.1 github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18 // indirect github.com/xlab/treeprint v0.0.0-20161029104018-1d6e34225557 - github.com/zclconf/go-cty v1.0.0 + github.com/zclconf/go-cty v1.0.1-0.20190708163926-19588f92a98f github.com/zclconf/go-cty-yaml v0.1.0 go.uber.org/atomic v1.3.2 // indirect go.uber.org/multierr v1.1.0 // indirect diff --git a/go.sum b/go.sum index 0170dab86..3c39d6c73 100644 --- a/go.sum +++ b/go.sum @@ -425,6 +425,8 @@ github.com/zclconf/go-cty v0.0.0-20190516203816-4fecf87372ec h1:MSeYjmyjucsFbecM github.com/zclconf/go-cty v0.0.0-20190516203816-4fecf87372ec/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.0.0 h1:EWtv3gKe2wPLIB9hQRQJa7k/059oIfAqcEkCNnaVckk= github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= +github.com/zclconf/go-cty v1.0.1-0.20190708163926-19588f92a98f h1:sq2p8SN6ji66CFEQFIWLlD/gFmGtr5hBrOzv5nLlGfA= +github.com/zclconf/go-cty v1.0.1-0.20190708163926-19588f92a98f/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty-yaml v0.1.0 h1:OP5nkApyAuXB88t8mRUqxD9gbKZocSLuVovrBAt8z10= github.com/zclconf/go-cty-yaml v0.1.0/go.mod h1:Lk26EcRlO3XbaQ8U2fxIJbEtbgEteSZFUpEr3XFTtsU= go.opencensus.io v0.18.0 h1:Mk5rgZcggtbvtAun5aJzAtjKKN/t0R3jJPlWILlv938= diff --git a/terraform/eval_diff.go b/terraform/eval_diff.go index 3ac23b709..20af9593c 100644 --- a/terraform/eval_diff.go +++ b/terraform/eval_diff.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "log" - "reflect" "strings" "github.com/hashicorp/hcl2/hcl" @@ -532,7 +531,7 @@ func processIgnoreChangesIndividual(prior, proposed cty.Value, ignoreChanges []h // away any deeper values we already produced at that point. var ignoreTraversal hcl.Traversal for i, candidate := range ignoreChangesPath { - if reflect.DeepEqual(path, candidate) { + if path.Equals(candidate) { ignoreTraversal = ignoreChanges[i] } } diff --git a/vendor/github.com/zclconf/go-cty/cty/path.go b/vendor/github.com/zclconf/go-cty/cty/path.go index bf1a7c15a..b31444954 100644 --- a/vendor/github.com/zclconf/go-cty/cty/path.go +++ b/vendor/github.com/zclconf/go-cty/cty/path.go @@ -71,6 +71,48 @@ func (p Path) GetAttr(name string) Path { return ret } +// Equals compares 2 Paths for exact equality. +func (p Path) Equals(other Path) bool { + if len(p) != len(other) { + return false + } + + for i := range p { + pv := p[i] + switch pv := pv.(type) { + case GetAttrStep: + ov, ok := other[i].(GetAttrStep) + if !ok || pv != ov { + return false + } + case IndexStep: + ov, ok := other[i].(IndexStep) + if !ok { + return false + } + + if !pv.Key.RawEquals(ov.Key) { + return false + } + default: + // Any invalid steps default to evaluating false. + return false + } + } + + return true + +} + +// HasPrefix determines if the path p contains the provided prefix. +func (p Path) HasPrefix(prefix Path) bool { + if len(prefix) > len(p) { + return false + } + + return p[:len(prefix)].Equals(prefix) +} + // GetAttrPath is a convenience method to start a new Path with a GetAttrStep. func GetAttrPath(name string) Path { return Path{}.GetAttr(name) diff --git a/vendor/modules.txt b/vendor/modules.txt index dbc18a3fa..46da2747d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -459,7 +459,7 @@ github.com/vmihailenco/msgpack/codes github.com/xanzy/ssh-agent # github.com/xlab/treeprint v0.0.0-20161029104018-1d6e34225557 github.com/xlab/treeprint -# github.com/zclconf/go-cty v1.0.0 +# github.com/zclconf/go-cty v1.0.1-0.20190708163926-19588f92a98f github.com/zclconf/go-cty/cty github.com/zclconf/go-cty/cty/gocty github.com/zclconf/go-cty/cty/convert