find meta references through locals

This commit is contained in:
James Bardin 2022-02-03 17:31:23 -05:00
parent 4181b6e106
commit b3adcf06a1
4 changed files with 31 additions and 2 deletions

View File

@ -40,6 +40,8 @@ func (a *Analyzer) MetaReferences(ref Reference) []Reference {
switch targetAddr := ref.LocalRef.Subject.(type) { switch targetAddr := ref.LocalRef.Subject.(type) {
case addrs.InputVariable: case addrs.InputVariable:
return a.metaReferencesInputVariable(moduleAddr, targetAddr, remaining) return a.metaReferencesInputVariable(moduleAddr, targetAddr, remaining)
case addrs.LocalValue:
return a.metaReferencesLocalValue(moduleAddr, targetAddr, remaining)
case addrs.ModuleCallInstanceOutput: case addrs.ModuleCallInstanceOutput:
return a.metaReferencesOutputValue(moduleAddr, targetAddr, remaining) return a.metaReferencesOutputValue(moduleAddr, targetAddr, remaining)
case addrs.ModuleCallInstance: case addrs.ModuleCallInstance:
@ -136,6 +138,23 @@ func (a *Analyzer) metaReferencesOutputValue(callerAddr addrs.ModuleInstance, ad
return absoluteRefs(calleeAddr, refs) return absoluteRefs(calleeAddr, refs)
} }
func (a *Analyzer) metaReferencesLocalValue(moduleAddr addrs.ModuleInstance, addr addrs.LocalValue, remain hcl.Traversal) []Reference {
modCfg := a.ModuleConfig(moduleAddr)
if modCfg == nil {
return nil
}
local := modCfg.Locals[addr.Name]
if local == nil {
return nil
}
// We don't check for errors here because we'll make a best effort to
// analyze whatever partial result HCL is able to extract.
refs, _ := lang.ReferencesInExpr(local.Expr)
return absoluteRefs(moduleAddr, refs)
}
func (a *Analyzer) metaReferencesModuleCall(callerAddr addrs.ModuleInstance, addr addrs.ModuleCallInstance, remain hcl.Traversal) []Reference { func (a *Analyzer) metaReferencesModuleCall(callerAddr addrs.ModuleInstance, addr addrs.ModuleCallInstance, remain hcl.Traversal) []Reference {
calleeAddr := callerAddr.Child(addr.Call.Name, addr.Key) calleeAddr := callerAddr.Child(addr.Call.Name, addr.Key)
@ -181,6 +200,7 @@ func (a *Analyzer) metaReferencesResourceInstance(moduleAddr addrs.ModuleInstanc
if providerSchema == nil { if providerSchema == nil {
return nil return nil
} }
resourceTypeSchema, _ := providerSchema.SchemaForResourceAddr(addr.Resource) resourceTypeSchema, _ := providerSchema.SchemaForResourceAddr(addr.Resource)
if resourceTypeSchema == nil { if resourceTypeSchema == nil {
return nil return nil

View File

@ -19,6 +19,13 @@ func TestAnalyzerMetaReferences(t *testing.T) {
`local.a`, `local.a`,
nil, nil,
}, },
{
``,
`local.single`,
[]string{
"::test_thing.single.id",
},
},
{ {
``, ``,
`test_thing.single`, `test_thing.single`,

View File

@ -1,7 +1,7 @@
locals { locals {
a = "hello world" a = "hello world"
b = 2 b = 2
single = test_thing.single.id
} }
resource "test_thing" "single" { resource "test_thing" "single" {

View File

@ -20,6 +20,8 @@ locals {
} }
] ]
]) ])
controllers = test_thing.controller
} }
resource "test_thing" "worker" { resource "test_thing" "worker" {
@ -39,7 +41,7 @@ resource "test_thing" "load_balancer" {
string = var.network.vpc_id string = var.network.vpc_id
dynamic "list" { dynamic "list" {
for_each = test_thing.controller for_each = local.controllers
content { content {
z = list.value.string z = list.value.string
} }