get whether parent modules have depends_on set

During refresh, data sources need to know if their parent modules have
depends_on configured at all. Pass this info back through the search for
depends_on resources, and delay refresh when it's set.
This commit is contained in:
James Bardin 2020-06-04 14:21:50 -04:00
parent 4637be4377
commit c3ec4d8e26
1 changed files with 55 additions and 24 deletions

View File

@ -178,14 +178,10 @@ func (t attachDataResourceDependenciesTransformer) Transform(g *Graph) error {
// depMap will only add resource references then dedupe // depMap will only add resource references then dedupe
deps := make(depMap) deps := make(depMap)
for _, dep := range refMap.dependsOn(g, depender) { dependsOnDeps, fromModule := refMap.dependsOn(g, depender)
for _, dep := range dependsOnDeps {
// any the dependency // any the dependency
deps.add(dep) deps.add(dep)
// and check any ancestors for transitive dependencies
ans, _ := g.Ancestors(dep)
for _, v := range ans {
deps.add(v)
}
} }
res := make([]addrs.ConfigResource, 0, len(deps)) res := make([]addrs.ConfigResource, 0, len(deps))
@ -194,7 +190,7 @@ func (t attachDataResourceDependenciesTransformer) Transform(g *Graph) error {
} }
log.Printf("[TRACE] attachDataDependenciesTransformer: %s depends on %s", depender.ResourceAddr(), res) log.Printf("[TRACE] attachDataDependenciesTransformer: %s depends on %s", depender.ResourceAddr(), res)
depender.AttachResourceDependencies(res, false) depender.AttachResourceDependencies(res, fromModule)
} }
return nil return nil
@ -266,6 +262,16 @@ func (t AttachDependenciesTransformer) Transform(g *Graph) error {
return nil return nil
} }
func isDependableResource(v dag.Vertex) bool {
switch v.(type) {
case GraphNodeResourceInstance:
return true
case GraphNodeConfigResource:
return true
}
return false
}
// ReferenceMap is a structure that can be used to efficiently check // ReferenceMap is a structure that can be used to efficiently check
// for references on a graph, mapping internal reference keys (as produced by // for references on a graph, mapping internal reference keys (as produced by
// the mapKey method) to one or more vertices that are identified by each key. // the mapKey method) to one or more vertices that are identified by each key.
@ -317,18 +323,27 @@ func (m ReferenceMap) References(v dag.Vertex) []dag.Vertex {
} }
// dependsOn returns the set of vertices that the given vertex refers to from // dependsOn returns the set of vertices that the given vertex refers to from
// the configured depends_on. // the configured depends_on. The bool return value indicates if depends_on was
func (m ReferenceMap) dependsOn(g *Graph, depender graphNodeDependsOn) []dag.Vertex { // found in a parent module configuration.
var matches []dag.Vertex func (m ReferenceMap) dependsOn(g *Graph, depender graphNodeDependsOn) ([]dag.Vertex, bool) {
var res []dag.Vertex
fromModule := false
refs := depender.DependsOn() refs := depender.DependsOn()
// This is where we record that a module has depends_on configured.
if _, ok := depender.(*nodeExpandModule); ok && len(refs) > 0 {
fromModule = true
}
for _, ref := range refs { for _, ref := range refs {
subject := ref.Subject subject := ref.Subject
key := m.referenceMapKey(depender, subject) key := m.referenceMapKey(depender, subject)
vertices, ok := m[key] vertices, ok := m[key]
if !ok { if !ok {
log.Printf("[WARN] DependsOn: reference not found: %q", subject) // the ReferenceMap generates all possible keys, so any warning
// here is probably not useful for this implementation.
continue continue
} }
for _, rv := range vertices { for _, rv := range vertices {
@ -336,42 +351,58 @@ func (m ReferenceMap) dependsOn(g *Graph, depender graphNodeDependsOn) []dag.Ver
if rv == depender { if rv == depender {
continue continue
} }
matches = append(matches, rv) res = append(res, rv)
// and check any ancestors for transitive dependencies
ans, _ := g.Ancestors(rv)
for _, v := range ans {
if isDependableResource(v) {
res = append(res, v)
}
}
} }
} }
matches = append(matches, m.parentModuleDependsOn(g, depender)...) parentDeps, fromParentModule := m.parentModuleDependsOn(g, depender)
res = append(res, parentDeps...)
return matches return res, fromModule || fromParentModule
} }
// parentModuleDependsOn returns the set of vertices that a data sources parent // parentModuleDependsOn returns the set of vertices that a data sources parent
// module references through the module call's depends_on. // module references through the module call's depends_on. The bool return
func (n ReferenceMap) parentModuleDependsOn(g *Graph, depender graphNodeDependsOn) []dag.Vertex { // value indicates if depends_on was found in a parent module configuration.
func (n ReferenceMap) parentModuleDependsOn(g *Graph, depender graphNodeDependsOn) ([]dag.Vertex, bool) {
var res []dag.Vertex var res []dag.Vertex
fromModule := false
// look for containing modules with DependsOn // Look for containing modules with DependsOn.
// This should be connected directly to the module node, so we only need to
// look one step away.
for _, v := range g.DownEdges(depender) { for _, v := range g.DownEdges(depender) {
// we're only concerned with module expansion nodes here.
mod, ok := v.(*nodeExpandModule) mod, ok := v.(*nodeExpandModule)
if !ok { if !ok {
continue continue
} }
for _, dep := range n.dependsOn(g, mod) { deps, fromParentModule := n.dependsOn(g, mod)
for _, dep := range deps {
// add the dependency // add the dependency
res = append(res, dep) res = append(res, dep)
// and check any ancestors
// and check any transitive resource dependencies for more resources
ans, _ := g.Ancestors(dep) ans, _ := g.Ancestors(dep)
for _, v := range ans { for _, v := range ans {
res = append(res, v) if isDependableResource(v) {
res = append(res, v)
}
} }
} }
fromModule = fromModule || fromParentModule
// recurse up through parent modules
res = append(res, n.parentModuleDependsOn(g, mod)...)
} }
return res return res, fromModule
} }
func (m *ReferenceMap) mapKey(path addrs.Module, addr addrs.Referenceable) string { func (m *ReferenceMap) mapKey(path addrs.Module, addr addrs.Referenceable) string {