mirror of
https://github.com/opentffoundation/opentf.git
synced 2026-04-04 21:00:39 -04:00
69 lines
2.8 KiB
Go
69 lines
2.8 KiB
Go
// Copyright (c) The OpenTofu Authors
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright (c) 2023 HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package tofu
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/opentofu/opentofu/internal/addrs"
|
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
|
)
|
|
|
|
// nodeExpandApplyableResource handles the first layer of resource
|
|
// expansion during apply. Even though the resource instances themselves are already expanded from the plan,
|
|
// we still need to register resource nodes in instances.Expander with their absolute addresses
|
|
// based on the expanded module instances.
|
|
//
|
|
// "Expand" in the name refers to instances.Expander usage. This node doesn't generate a dynamic subgraph.
|
|
type nodeExpandApplyableResource struct {
|
|
*NodeAbstractResource
|
|
}
|
|
|
|
var (
|
|
_ GraphNodeExecutable = (*nodeExpandApplyableResource)(nil)
|
|
_ GraphNodeReferenceable = (*nodeExpandApplyableResource)(nil)
|
|
_ GraphNodeReferencer = (*nodeExpandApplyableResource)(nil)
|
|
_ GraphNodeConfigResource = (*nodeExpandApplyableResource)(nil)
|
|
_ GraphNodeAttachResourceConfig = (*nodeExpandApplyableResource)(nil)
|
|
// nodeExpandApplyableResource needs to be retained during unused nodes pruning
|
|
// to register the resource for expanded module instances in `instances.Expander`
|
|
_ graphNodeRetainedByPruneUnusedNodesTransformer = (*nodeExpandApplyableResource)(nil)
|
|
_ GraphNodeTargetable = (*nodeExpandApplyableResource)(nil)
|
|
)
|
|
|
|
func (n *nodeExpandApplyableResource) retainDuringUnusedPruning() {
|
|
}
|
|
|
|
func (n *nodeExpandApplyableResource) References() []*addrs.Reference {
|
|
refs := n.NodeAbstractResource.References()
|
|
|
|
// The expand node needs to connect to the individual resource instances it
|
|
// references, but cannot refer to it's own instances without causing
|
|
// cycles. It would be preferable to entirely disallow self references
|
|
// without the `self` identifier, but those were allowed in provisioners
|
|
// for compatibility with legacy configuration. We also can't always just
|
|
// filter them out for all resource node types, because the only method we
|
|
// have for catching certain invalid configurations are the cycles that
|
|
// result from these inter-instance references.
|
|
return filterSelfRefs(n.Addr.Resource, refs)
|
|
}
|
|
|
|
func (n *nodeExpandApplyableResource) Name() string {
|
|
return n.NodeAbstractResource.Name() + " (expand)"
|
|
}
|
|
|
|
func (n *nodeExpandApplyableResource) Execute(ctx context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
|
var diags tfdiags.Diagnostics
|
|
expander := evalCtx.InstanceExpander()
|
|
moduleInstances := expander.ExpandModule(n.Addr.Module)
|
|
for _, module := range moduleInstances {
|
|
evalCtx = evalCtx.WithPath(module)
|
|
diags = diags.Append(n.writeResourceState(ctx, evalCtx, n.Addr.Resource.Absolute(module)))
|
|
}
|
|
|
|
return diags
|
|
}
|