mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-28 18:01:01 -06:00
get more depends_on info for data source
Since data sources may be read during refresh or early in plan, they need to know if there are any inherited dependencies from containing modules too.
This commit is contained in:
parent
a03c86f612
commit
e74ebe1787
@ -43,6 +43,12 @@ type GraphNodeAttachDependencies interface {
|
||||
AttachDependencies([]addrs.ConfigResource)
|
||||
}
|
||||
|
||||
// graphNodeDependsOn is implemented by resources that need to expose any
|
||||
// references set via DependsOn in their configuration.
|
||||
type graphNodeDependsOn interface {
|
||||
DependsOn() []*addrs.Reference
|
||||
}
|
||||
|
||||
// graphNodeAttachResourceDependencies records all resources that are transitively
|
||||
// referenced through depends_on in the configuration. This is used by data
|
||||
// resources to determine if they can be read during the plan, or if they need
|
||||
@ -55,8 +61,8 @@ type GraphNodeAttachDependencies interface {
|
||||
// "perpetual diff"
|
||||
type graphNodeAttachResourceDependencies interface {
|
||||
GraphNodeConfigResource
|
||||
graphNodeDependsOn
|
||||
AttachResourceDependencies([]addrs.ConfigResource)
|
||||
DependsOn() []*addrs.Reference
|
||||
}
|
||||
|
||||
// GraphNodeReferenceOutside is an interface that can optionally be implemented.
|
||||
@ -122,7 +128,7 @@ func (t *ReferenceTransformer) Transform(g *Graph) error {
|
||||
|
||||
type depMap map[string]addrs.ConfigResource
|
||||
|
||||
// addDep adds the vertex if it represents a resource in the
|
||||
// add stores the vertex if it represents a resource in the
|
||||
// graph.
|
||||
func (m depMap) add(v dag.Vertex) {
|
||||
// we're only concerned with resources which may have changes that
|
||||
@ -155,34 +161,32 @@ func (t attachDataResourceDependenciesTransformer) Transform(g *Graph) error {
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
selfAddr := depender.ResourceAddr()
|
||||
|
||||
// Only data need to attach depends_on, so they can determine if they
|
||||
// are eligible to be read during plan.
|
||||
if selfAddr.Resource.Mode != addrs.DataResourceMode {
|
||||
if depender.ResourceAddr().Resource.Mode != addrs.DataResourceMode {
|
||||
continue
|
||||
}
|
||||
|
||||
// depMap will only add resource references and dedupe
|
||||
m := make(depMap)
|
||||
|
||||
for _, dep := range refMap.DependsOn(v) {
|
||||
// depMap will only add resource references then dedupe
|
||||
deps := make(depMap)
|
||||
for _, dep := range refMap.dependsOn(g, depender) {
|
||||
// any the dependency
|
||||
m.add(dep)
|
||||
// and check any ancestors
|
||||
deps.add(dep)
|
||||
// and check any ancestors for transitive dependencies
|
||||
ans, _ := g.Ancestors(dep)
|
||||
for _, v := range ans {
|
||||
m.add(v)
|
||||
deps.add(v)
|
||||
}
|
||||
}
|
||||
|
||||
deps := make([]addrs.ConfigResource, 0, len(m))
|
||||
for _, d := range m {
|
||||
deps = append(deps, d)
|
||||
res := make([]addrs.ConfigResource, 0, len(deps))
|
||||
for _, d := range deps {
|
||||
res = append(res, d)
|
||||
}
|
||||
|
||||
log.Printf("[TRACE] AttachDependsOnTransformer: %s depends on %s", depender.ResourceAddr(), deps)
|
||||
depender.AttachResourceDependencies(deps)
|
||||
log.Printf("[TRACE] attachDataDependenciesTransformer: %s depends on %s", depender.ResourceAddr(), res)
|
||||
depender.AttachResourceDependencies(res)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -304,37 +308,64 @@ func (m ReferenceMap) References(v dag.Vertex) []dag.Vertex {
|
||||
return matches
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (m ReferenceMap) DependsOn(v dag.Vertex) []dag.Vertex {
|
||||
depender, ok := v.(graphNodeAttachResourceDependencies)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m ReferenceMap) dependsOn(g *Graph, depender graphNodeDependsOn) []dag.Vertex {
|
||||
var matches []dag.Vertex
|
||||
refs := depender.DependsOn()
|
||||
|
||||
for _, ref := range depender.DependsOn() {
|
||||
for _, ref := range refs {
|
||||
subject := ref.Subject
|
||||
|
||||
key := m.referenceMapKey(v, subject)
|
||||
key := m.referenceMapKey(depender, subject)
|
||||
vertices, ok := m[key]
|
||||
if !ok {
|
||||
log.Printf("[WARN] DependOn: reference not found: %q", subject)
|
||||
log.Printf("[WARN] DependsOn: reference not found: %q", subject)
|
||||
continue
|
||||
}
|
||||
for _, rv := range vertices {
|
||||
// don't include self-references
|
||||
if rv == v {
|
||||
if rv == depender {
|
||||
continue
|
||||
}
|
||||
matches = append(matches, rv)
|
||||
}
|
||||
}
|
||||
|
||||
matches = append(matches, m.parentModuleDependsOn(g, depender)...)
|
||||
|
||||
return matches
|
||||
}
|
||||
|
||||
// parentModuleDependsOn returns the set of vertices that a data sources parent
|
||||
// module references through the module call's depends_on.
|
||||
func (n ReferenceMap) parentModuleDependsOn(g *Graph, depender graphNodeDependsOn) []dag.Vertex {
|
||||
var res []dag.Vertex
|
||||
|
||||
// look for containing modules with DependsOn
|
||||
for _, v := range g.DownEdges(depender) {
|
||||
mod, ok := v.(*nodeExpandModule)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, dep := range n.dependsOn(g, mod) {
|
||||
// add the dependency
|
||||
res = append(res, dep)
|
||||
// and check any ancestors
|
||||
ans, _ := g.Ancestors(dep)
|
||||
for _, v := range ans {
|
||||
res = append(res, v)
|
||||
}
|
||||
}
|
||||
|
||||
// recurse up through parent modules
|
||||
res = append(res, n.parentModuleDependsOn(g, mod)...)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (m *ReferenceMap) mapKey(path addrs.Module, addr addrs.Referenceable) string {
|
||||
return fmt.Sprintf("%s|%s", path.String(), addr.String())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user