From 14ec3e6078afa5cd4aecfd4170bc67f374f3ecc8 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Tue, 24 Mar 2020 18:44:02 -0400 Subject: [PATCH] Expander.ExpandResource cannot expand all modules ExpandResource must only check the specific ModuleInstances in the requested path, because the resource may not have been registered yet in all module instances. --- instances/expander.go | 51 +++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/instances/expander.go b/instances/expander.go index e7fdceb5b..1a2f1dd2a 100644 --- a/instances/expander.go +++ b/instances/expander.go @@ -136,7 +136,7 @@ func (e *Expander) ExpandModuleResource(moduleAddr addrs.Module, resourceAddr ad // (moduleInstances does plenty of allocations itself, so the benefit of // pre-allocating this is marginal but it's not hard to do.) moduleInstanceAddr := make(addrs.ModuleInstance, 0, 4) - ret := e.exps.resourceInstances(moduleAddr, resourceAddr, moduleInstanceAddr) + ret := e.exps.moduleResourceInstances(moduleAddr, resourceAddr, moduleInstanceAddr) sort.SliceStable(ret, func(i, j int) bool { return ret[i].Less(ret[j]) }) @@ -150,16 +150,14 @@ func (e *Expander) ExpandModuleResource(moduleAddr addrs.Module, resourceAddr ad // itself must already have had their expansion registered using one of the // SetModule*/SetResource* methods before calling, or this method will panic. func (e *Expander) ExpandResource(resourceAddr addrs.AbsResource) []addrs.AbsResourceInstance { - var ret []addrs.AbsResourceInstance + e.mu.RLock() + defer e.mu.RUnlock() - // Take the full set of expanded resource instances and filter for only - // those within our module instance. - for _, r := range e.ExpandModuleResource(resourceAddr.Module.Module(), resourceAddr.Resource) { - if !r.Module.Equal(resourceAddr.Module) { - continue - } - ret = append(ret, r) - } + moduleInstanceAddr := make(addrs.ModuleInstance, 0, 4) + ret := e.exps.resourceInstances(resourceAddr.Module, resourceAddr.Resource, moduleInstanceAddr) + sort.SliceStable(ret, func(i, j int) bool { + return ret[i].Less(ret[j]) + }) return ret } @@ -297,10 +295,9 @@ func (m *expanderModule) moduleInstances(addr addrs.Module, parentAddr addrs.Mod return ret } -func (m *expanderModule) resourceInstances(moduleAddr addrs.Module, resourceAddr addrs.Resource, parentAddr addrs.ModuleInstance) []addrs.AbsResourceInstance { - var ret []addrs.AbsResourceInstance - +func (m *expanderModule) moduleResourceInstances(moduleAddr addrs.Module, resourceAddr addrs.Resource, parentAddr addrs.ModuleInstance) []addrs.AbsResourceInstance { if len(moduleAddr) > 0 { + var ret []addrs.AbsResourceInstance // We need to traverse through the module levels first, so we can // then iterate resource expansions in the context of each module // path leading to them. @@ -317,11 +314,37 @@ func (m *expanderModule) resourceInstances(moduleAddr addrs.Module, resourceAddr continue } moduleInstAddr := append(parentAddr, step) - ret = append(ret, inst.resourceInstances(moduleAddr[1:], resourceAddr, moduleInstAddr)...) + ret = append(ret, inst.moduleResourceInstances(moduleAddr[1:], resourceAddr, moduleInstAddr)...) } return ret } + return m.onlyResourceInstances(resourceAddr, parentAddr) +} + +func (m *expanderModule) resourceInstances(moduleAddr addrs.ModuleInstance, resourceAddr addrs.Resource, parentAddr addrs.ModuleInstance) []addrs.AbsResourceInstance { + if len(moduleAddr) > 0 { + // We need to traverse through the module levels first, using only the + // module instances for our specific resource, as the resource may not + // yet be expanded in all module instances. + step := moduleAddr[0] + callName := step.Name + if _, ok := m.moduleCalls[addrs.ModuleCall{Name: callName}]; !ok { + // This is a bug in the caller, because it should always register + // expansions for an object and all of its ancestors before requesting + // expansion of it. + panic(fmt.Sprintf("no expansion has been registered for %s", parentAddr.Child(callName, addrs.NoKey))) + } + + inst := m.childInstances[step] + moduleInstAddr := append(parentAddr, step) + return inst.resourceInstances(moduleAddr[1:], resourceAddr, moduleInstAddr) + } + return m.onlyResourceInstances(resourceAddr, parentAddr) +} + +func (m *expanderModule) onlyResourceInstances(resourceAddr addrs.Resource, parentAddr addrs.ModuleInstance) []addrs.AbsResourceInstance { + var ret []addrs.AbsResourceInstance exp, ok := m.resources[resourceAddr] if !ok { panic(fmt.Sprintf("no expansion has been registered for %s", resourceAddr.Absolute(parentAddr)))