From e2b74247f2afc18f93d8250602536a1be4b15ebd Mon Sep 17 00:00:00 2001 From: James Bardin Date: Mon, 7 Feb 2022 09:39:14 -0500 Subject: [PATCH] track contributing instances Track individual instance drift rather than whole resources which contributed to the plan. This will allow the output to be more precise, and we can still use NoKey instances as a proxy for containing resources when needed. --- internal/command/views/operation_test.go | 2 +- internal/command/views/plan.go | 2 +- .../globalref/analyzer_meta_references.go | 4 ++-- internal/lang/globalref/reference.go | 20 +++++++++---------- internal/plans/plan.go | 6 +++--- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/internal/command/views/operation_test.go b/internal/command/views/operation_test.go index eca2c3909..9b0323a27 100644 --- a/internal/command/views/operation_test.go +++ b/internal/command/views/operation_test.go @@ -189,7 +189,7 @@ func TestOperation_planNoChanges(t *testing.T) { Changes: changes, DriftedResources: drs, RelevantAttributes: []globalref.ResourceAttr{{ - Resource: addr.ContainingResource(), + Resource: addr, Attr: cty.GetAttrPath("id"), }}, } diff --git a/internal/command/views/plan.go b/internal/command/views/plan.go index 11cfc872e..c3c1283cf 100644 --- a/internal/command/views/plan.go +++ b/internal/command/views/plan.go @@ -459,7 +459,7 @@ func filterRefreshChange(change *plans.ResourceInstanceChange, contributing []gl } var relevantAttrs []cty.Path - resAddr := change.Addr.ContainingResource() + resAddr := change.Addr for _, attr := range contributing { if resAddr.Equal(attr.Resource) { diff --git a/internal/lang/globalref/analyzer_meta_references.go b/internal/lang/globalref/analyzer_meta_references.go index 4646b55e5..9a2bb8992 100644 --- a/internal/lang/globalref/analyzer_meta_references.go +++ b/internal/lang/globalref/analyzer_meta_references.go @@ -56,8 +56,8 @@ func (a *Analyzer) MetaReferences(ref Reference) []Reference { // this latter to distingish these two cases better. return a.metaReferencesModuleCall(moduleAddr, targetAddr.Instance(addrs.NoKey), remaining) case addrs.CountAttr, addrs.ForEachAttr: - if resourceAddr, ok := ref.ResourceAddr(); ok { - return a.metaReferencesCountOrEach(resourceAddr) + if resourceAddr, ok := ref.ResourceInstance(); ok { + return a.metaReferencesCountOrEach(resourceAddr.ContainingResource()) } return nil case addrs.ResourceInstance: diff --git a/internal/lang/globalref/reference.go b/internal/lang/globalref/reference.go index 4fc2f14a9..d47cecfa7 100644 --- a/internal/lang/globalref/reference.go +++ b/internal/lang/globalref/reference.go @@ -80,29 +80,27 @@ func (r Reference) ModuleAddr() addrs.ModuleInstance { } } -// ResourceAddr returns the address of the resource where the reference +// ResourceInstance returns the address of the resource where the reference // would be resolved, if there is one. // // Because not all references belong to resources, the extra boolean return // value indicates whether the returned address is valid. -func (r Reference) ResourceAddr() (addrs.AbsResource, bool) { - moduleInstance := addrs.RootModuleInstance - +func (r Reference) ResourceInstance() (addrs.AbsResourceInstance, bool) { switch container := r.ContainerAddr.(type) { case addrs.ModuleInstance: - moduleInstance = container + moduleInstance := container switch ref := r.LocalRef.Subject.(type) { case addrs.Resource: - return ref.Absolute(moduleInstance), true + return ref.Instance(addrs.NoKey).Absolute(moduleInstance), true case addrs.ResourceInstance: - return ref.ContainingResource().Absolute(moduleInstance), true + return ref.Absolute(moduleInstance), true } - return addrs.AbsResource{}, false + return addrs.AbsResourceInstance{}, false case addrs.AbsResourceInstance: - return container.ContainingResource(), true + return container, true default: // NOTE: We're intentionally using only a subset of possible // addrs.Targetable implementations here, so anything else @@ -134,7 +132,7 @@ func (r Reference) DebugString() string { // Because not all references belong to resources, the extra boolean return // value indicates whether the returned address is valid. func (r Reference) ResourceAttr() (ResourceAttr, bool) { - res, ok := r.ResourceAddr() + res, ok := r.ResourceInstance() if !ok { return ResourceAttr{}, ok } @@ -193,7 +191,7 @@ type referenceAddrKey string // This is a more specific form of the Reference type since it can only refer // to a specific AbsResource and one of its attributes. type ResourceAttr struct { - Resource addrs.AbsResource + Resource addrs.AbsResourceInstance Attr cty.Path } diff --git a/internal/plans/plan.go b/internal/plans/plan.go index f7a2df1ad..766da885a 100644 --- a/internal/plans/plan.go +++ b/internal/plans/plan.go @@ -37,9 +37,9 @@ type Plan struct { ForceReplaceAddrs []addrs.AbsResourceInstance Backend Backend - // RelevantAttributes is a set of resource addresses and attributes that are - // either directly affected by proposed changes or may have indirectly - // contributed to them via references in expressions. + // RelevantAttributes is a set of resource instance addresses and + // attributes that are either directly affected by proposed changes or may + // have indirectly contributed to them via references in expressions. // // This is the result of a heuristic and is intended only as a hint to // the UI layer in case it wants to emphasize or de-emphasize certain