mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-19 17:59:05 -05:00
tofu: GraphNodeExecutable interface takes context.Context
In order to generate OpenTelemetry traces of the main work that OpenTofu Core does we'll need to be able to propagate the active trace context into the main "Execute" method of each graph node, since that's where we typically make requests to providers, and other such work that could take a noticeable amount of time. Changing these frequently-used interfaces is always a noisy diff, so this commit intentionally focuses only on changing the signature of that interface and its one caller, and then dealing with all of the fallout of that on existing unit test code. For any use of Execute that was affected by this change we'll also switch to our newer naming scheme of using "evalCtx" as the name of the tofu.EvalContext variable, in preparation for using "ctx" idiomatically to refer to context.Context. However, the implementations currently don't yet name their context.Context argument because the method bodies don't yet make use of it. We'll name each of those arguments to "ctx" individually as we gradually add tracing support to each graph node type. Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
This commit is contained in:
@@ -5,10 +5,14 @@
|
|||||||
|
|
||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import "github.com/opentofu/opentofu/internal/tfdiags"
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
|
)
|
||||||
|
|
||||||
// GraphNodeExecutable is the interface that graph nodes must implement to
|
// GraphNodeExecutable is the interface that graph nodes must implement to
|
||||||
// enable execution.
|
// enable execution.
|
||||||
type GraphNodeExecutable interface {
|
type GraphNodeExecutable interface {
|
||||||
Execute(EvalContext, walkOperation) tfdiags.Diagnostics
|
Execute(context.Context, EvalContext, walkOperation) tfdiags.Diagnostics
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ func (g *Graph) walk(ctx context.Context, walker GraphWalker) tfdiags.Diagnostic
|
|||||||
|
|
||||||
// If the node is exec-able, then execute it.
|
// If the node is exec-able, then execute it.
|
||||||
if ev, ok := v.(GraphNodeExecutable); ok {
|
if ev, ok := v.(GraphNodeExecutable); ok {
|
||||||
diags = diags.Append(walker.Execute(vertexCtx, ev))
|
diags = diags.Append(walker.Execute(ctx, vertexCtx, ev))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
)
|
)
|
||||||
@@ -16,7 +18,7 @@ type GraphWalker interface {
|
|||||||
EvalContext() EvalContext
|
EvalContext() EvalContext
|
||||||
EnterPath(addrs.ModuleInstance) EvalContext
|
EnterPath(addrs.ModuleInstance) EvalContext
|
||||||
ExitPath(addrs.ModuleInstance)
|
ExitPath(addrs.ModuleInstance)
|
||||||
Execute(EvalContext, GraphNodeExecutable) tfdiags.Diagnostics
|
Execute(context.Context, EvalContext, GraphNodeExecutable) tfdiags.Diagnostics
|
||||||
}
|
}
|
||||||
|
|
||||||
// NullGraphWalker is a GraphWalker implementation that does nothing.
|
// NullGraphWalker is a GraphWalker implementation that does nothing.
|
||||||
@@ -24,7 +26,9 @@ type GraphWalker interface {
|
|||||||
// implementing all the required functions.
|
// implementing all the required functions.
|
||||||
type NullGraphWalker struct{}
|
type NullGraphWalker struct{}
|
||||||
|
|
||||||
func (NullGraphWalker) EvalContext() EvalContext { return new(MockEvalContext) }
|
func (NullGraphWalker) EvalContext() EvalContext { return new(MockEvalContext) }
|
||||||
func (NullGraphWalker) EnterPath(addrs.ModuleInstance) EvalContext { return new(MockEvalContext) }
|
func (NullGraphWalker) EnterPath(addrs.ModuleInstance) EvalContext { return new(MockEvalContext) }
|
||||||
func (NullGraphWalker) ExitPath(addrs.ModuleInstance) {}
|
func (NullGraphWalker) ExitPath(addrs.ModuleInstance) {}
|
||||||
func (NullGraphWalker) Execute(EvalContext, GraphNodeExecutable) tfdiags.Diagnostics { return nil }
|
func (NullGraphWalker) Execute(context.Context, EvalContext, GraphNodeExecutable) tfdiags.Diagnostics {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ type ContextGraphWalker struct {
|
|||||||
provisionerCache map[string]provisioners.Interface
|
provisionerCache map[string]provisioners.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ GraphWalker = (*ContextGraphWalker)(nil)
|
||||||
|
|
||||||
func (w *ContextGraphWalker) EnterPath(path addrs.ModuleInstance) EvalContext {
|
func (w *ContextGraphWalker) EnterPath(path addrs.ModuleInstance) EvalContext {
|
||||||
w.contextLock.Lock()
|
w.contextLock.Lock()
|
||||||
defer w.contextLock.Unlock()
|
defer w.contextLock.Unlock()
|
||||||
@@ -141,10 +143,10 @@ func (w *ContextGraphWalker) init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *ContextGraphWalker) Execute(ctx EvalContext, n GraphNodeExecutable) tfdiags.Diagnostics {
|
func (w *ContextGraphWalker) Execute(ctx context.Context, evalCtx EvalContext, n GraphNodeExecutable) tfdiags.Diagnostics {
|
||||||
// Acquire a lock on the semaphore
|
// Acquire a lock on the semaphore
|
||||||
w.Context.parallelSem.Acquire()
|
w.Context.parallelSem.Acquire()
|
||||||
defer w.Context.parallelSem.Release()
|
defer w.Context.parallelSem.Release()
|
||||||
|
|
||||||
return n.Execute(ctx, w.Operation)
|
return n.Execute(ctx, evalCtx, w.Operation)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
@@ -40,15 +41,15 @@ func (n *nodeReportCheck) ModulePath() addrs.Module {
|
|||||||
return n.addr.Module
|
return n.addr.Module
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nodeReportCheck) Execute(ctx EvalContext, _ walkOperation) tfdiags.Diagnostics {
|
func (n *nodeReportCheck) Execute(_ context.Context, evalCtx EvalContext, _ walkOperation) tfdiags.Diagnostics {
|
||||||
exp := ctx.InstanceExpander()
|
exp := evalCtx.InstanceExpander()
|
||||||
modInsts := exp.ExpandModule(n.ModulePath())
|
modInsts := exp.ExpandModule(n.ModulePath())
|
||||||
|
|
||||||
instAddrs := addrs.MakeSet[addrs.Checkable]()
|
instAddrs := addrs.MakeSet[addrs.Checkable]()
|
||||||
for _, modAddr := range modInsts {
|
for _, modAddr := range modInsts {
|
||||||
instAddrs.Add(n.addr.Check.Absolute(modAddr))
|
instAddrs.Add(n.addr.Check.Absolute(modAddr))
|
||||||
}
|
}
|
||||||
ctx.Checks().ReportCheckableObjects(n.addr, instAddrs)
|
evalCtx.Checks().ReportCheckableObjects(n.addr, instAddrs)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,12 +151,12 @@ func (n *nodeCheckAssert) Path() addrs.ModuleInstance {
|
|||||||
return n.addr.Module
|
return n.addr.Module
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nodeCheckAssert) Execute(ctx EvalContext, _ walkOperation) tfdiags.Diagnostics {
|
func (n *nodeCheckAssert) Execute(_ context.Context, evalCtx EvalContext, _ walkOperation) tfdiags.Diagnostics {
|
||||||
|
|
||||||
// We only want to actually execute the checks during specific
|
// We only want to actually execute the checks during specific
|
||||||
// operations, such as plan and applies.
|
// operations, such as plan and applies.
|
||||||
if n.executeChecks {
|
if n.executeChecks {
|
||||||
if status := ctx.Checks().ObjectCheckStatus(n.addr); status == checks.StatusFail || status == checks.StatusError {
|
if status := evalCtx.Checks().ObjectCheckStatus(n.addr); status == checks.StatusFail || status == checks.StatusError {
|
||||||
// This check is already failing, so we won't try and evaluate it.
|
// This check is already failing, so we won't try and evaluate it.
|
||||||
// This typically means there was an error in a data block within
|
// This typically means there was an error in a data block within
|
||||||
// the check block.
|
// the check block.
|
||||||
@@ -165,7 +166,7 @@ func (n *nodeCheckAssert) Execute(ctx EvalContext, _ walkOperation) tfdiags.Diag
|
|||||||
return evalCheckRules(
|
return evalCheckRules(
|
||||||
addrs.CheckAssertion,
|
addrs.CheckAssertion,
|
||||||
n.config.Asserts,
|
n.config.Asserts,
|
||||||
ctx,
|
evalCtx,
|
||||||
n.addr,
|
n.addr,
|
||||||
EvalDataForNoInstanceKey,
|
EvalDataForNoInstanceKey,
|
||||||
tfdiags.Warning)
|
tfdiags.Warning)
|
||||||
@@ -176,7 +177,7 @@ func (n *nodeCheckAssert) Execute(ctx EvalContext, _ walkOperation) tfdiags.Diag
|
|||||||
// diagnostics if references do not exist etc.
|
// diagnostics if references do not exist etc.
|
||||||
var diags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
for ix, assert := range n.config.Asserts {
|
for ix, assert := range n.config.Asserts {
|
||||||
_, _, moreDiags := validateCheckRule(addrs.NewCheckRule(n.addr, addrs.CheckAssertion, ix), assert, ctx, EvalDataForNoInstanceKey)
|
_, _, moreDiags := validateCheckRule(addrs.NewCheckRule(n.addr, addrs.CheckAssertion, ix), assert, evalCtx, EvalDataForNoInstanceKey)
|
||||||
diags = diags.Append(moreDiags)
|
diags = diags.Append(moreDiags)
|
||||||
}
|
}
|
||||||
return diags
|
return diags
|
||||||
@@ -195,7 +196,7 @@ var (
|
|||||||
// dependency that can enforce this ordering.
|
// dependency that can enforce this ordering.
|
||||||
type nodeCheckStart struct{}
|
type nodeCheckStart struct{}
|
||||||
|
|
||||||
func (n *nodeCheckStart) Execute(context EvalContext, operation walkOperation) tfdiags.Diagnostics {
|
func (n *nodeCheckStart) Execute(_ context.Context, _ EvalContext, _ walkOperation) tfdiags.Diagnostics {
|
||||||
// This node doesn't actually do anything, except simplify the underlying
|
// This node doesn't actually do anything, except simplify the underlying
|
||||||
// graph structure.
|
// graph structure.
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
@@ -22,8 +23,8 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *NodeDestroyableDataResourceInstance) Execute(ctx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
func (n *NodeDestroyableDataResourceInstance) Execute(ctx context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
||||||
log.Printf("[TRACE] NodeDestroyableDataResourceInstance: removing state object for %s", n.Addr)
|
log.Printf("[TRACE] NodeDestroyableDataResourceInstance: removing state object for %s", n.Addr)
|
||||||
ctx.State().SetResourceInstanceCurrent(n.Addr, nil, n.ResolvedProvider.ProviderConfig, nil)
|
evalCtx.State().SetResourceInstanceCurrent(n.Addr, nil, n.ResolvedProvider.ProviderConfig, nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func TestNodeDataDestroyExecute(t *testing.T) {
|
|||||||
},
|
},
|
||||||
addrs.NoKey,
|
addrs.NoKey,
|
||||||
)
|
)
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ func TestNodeDataDestroyExecute(t *testing.T) {
|
|||||||
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
|
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
|
||||||
}}
|
}}
|
||||||
|
|
||||||
diags := node.Execute(ctx, walkApply)
|
diags := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %v", diags.Err())
|
t.Fatalf("unexpected error: %v", diags.Err())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -135,7 +136,7 @@ func (n *NodeLocal) References() []*addrs.Reference {
|
|||||||
// NodeLocal.Execute is an Execute implementation that evaluates the
|
// NodeLocal.Execute is an Execute implementation that evaluates the
|
||||||
// expression for a local value and writes it into a transient part of
|
// expression for a local value and writes it into a transient part of
|
||||||
// the state.
|
// the state.
|
||||||
func (n *NodeLocal) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *NodeLocal) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
expr := n.Config.Expr
|
expr := n.Config.Expr
|
||||||
addr := n.Addr.LocalValue
|
addr := n.Addr.LocalValue
|
||||||
|
|
||||||
@@ -157,19 +158,19 @@ func (n *NodeLocal) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Di
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
val, moreDiags := ctx.EvaluateExpr(expr, cty.DynamicPseudoType, nil)
|
val, moreDiags := evalCtx.EvaluateExpr(expr, cty.DynamicPseudoType, nil)
|
||||||
diags = diags.Append(moreDiags)
|
diags = diags.Append(moreDiags)
|
||||||
if moreDiags.HasErrors() {
|
if moreDiags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
state := ctx.State()
|
state := evalCtx.State()
|
||||||
if state == nil {
|
if state == nil {
|
||||||
diags = diags.Append(fmt.Errorf("cannot write local value to nil state"))
|
diags = diags.Append(fmt.Errorf("cannot write local value to nil state"))
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
state.SetLocalValue(addr.Absolute(ctx.Path()), val)
|
state.SetLocalValue(addr.Absolute(evalCtx.Path()), val)
|
||||||
|
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,13 +56,13 @@ func TestNodeLocalExecute(t *testing.T) {
|
|||||||
Expr: expr,
|
Expr: expr,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: states.NewState().SyncWrapper(),
|
StateState: states.NewState().SyncWrapper(),
|
||||||
|
|
||||||
EvaluateExprResult: hcl2shim.HCL2ValueFromConfigValue(test.Want),
|
EvaluateExprResult: hcl2shim.HCL2ValueFromConfigValue(test.Want),
|
||||||
}
|
}
|
||||||
|
|
||||||
err := n.Execute(ctx, walkApply)
|
err := n.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if (err != nil) != test.Err {
|
if (err != nil) != test.Err {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %s", err)
|
t.Errorf("unexpected error: %s", err)
|
||||||
@@ -71,7 +71,7 @@ func TestNodeLocalExecute(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ms := ctx.StateState.Module(addrs.RootModuleInstance)
|
ms := evalCtx.StateState.Module(addrs.RootModuleInstance)
|
||||||
gotLocals := ms.LocalValues
|
gotLocals := ms.LocalValues
|
||||||
wantLocals := map[string]cty.Value{}
|
wantLocals := map[string]cty.Value{}
|
||||||
if test.Want != nil {
|
if test.Want != nil {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
@@ -112,18 +113,18 @@ func (n *nodeExpandModule) ReferenceOutside() (selfPath, referencePath addrs.Mod
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *nodeExpandModule) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *nodeExpandModule) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
expander := ctx.InstanceExpander()
|
expander := evalCtx.InstanceExpander()
|
||||||
_, call := n.Addr.Call()
|
_, call := n.Addr.Call()
|
||||||
|
|
||||||
// nodeExpandModule itself does not have visibility into how its ancestors
|
// nodeExpandModule itself does not have visibility into how its ancestors
|
||||||
// were expanded, so we use the expander here to provide all possible paths
|
// were expanded, so we use the expander here to provide all possible paths
|
||||||
// to our module, and register module instances with each of them.
|
// to our module, and register module instances with each of them.
|
||||||
for _, module := range expander.ExpandModule(n.Addr.Parent()) {
|
for _, module := range expander.ExpandModule(n.Addr.Parent()) {
|
||||||
ctx = ctx.WithPath(module)
|
evalCtx = evalCtx.WithPath(module)
|
||||||
switch {
|
switch {
|
||||||
case n.ModuleCall.Count != nil:
|
case n.ModuleCall.Count != nil:
|
||||||
count, ctDiags := evaluateCountExpression(n.ModuleCall.Count, ctx, module)
|
count, ctDiags := evaluateCountExpression(n.ModuleCall.Count, evalCtx, module)
|
||||||
diags = diags.Append(ctDiags)
|
diags = diags.Append(ctDiags)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
@@ -131,7 +132,7 @@ func (n *nodeExpandModule) Execute(ctx EvalContext, op walkOperation) (diags tfd
|
|||||||
expander.SetModuleCount(module, call, count)
|
expander.SetModuleCount(module, call, count)
|
||||||
|
|
||||||
case n.ModuleCall.ForEach != nil:
|
case n.ModuleCall.ForEach != nil:
|
||||||
forEach, feDiags := evaluateForEachExpression(n.ModuleCall.ForEach, ctx, module)
|
forEach, feDiags := evaluateForEachExpression(n.ModuleCall.ForEach, evalCtx, module)
|
||||||
diags = diags.Append(feDiags)
|
diags = diags.Append(feDiags)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
@@ -202,19 +203,19 @@ func (n *nodeCloseModule) IsOverridden(addr addrs.Module) bool {
|
|||||||
return modConfig.Module.IsOverridden
|
return modConfig.Module.IsOverridden
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nodeCloseModule) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *nodeCloseModule) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
if !n.Addr.IsRoot() {
|
if !n.Addr.IsRoot() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is the root module, we are cleaning up the walk, so close
|
// If this is the root module, we are cleaning up the walk, so close
|
||||||
// any running provisioners
|
// any running provisioners
|
||||||
diags = diags.Append(ctx.CloseProvisioners())
|
diags = diags.Append(evalCtx.CloseProvisioners())
|
||||||
|
|
||||||
switch op {
|
switch op {
|
||||||
case walkApply, walkDestroy:
|
case walkApply, walkDestroy:
|
||||||
state := ctx.State().Lock()
|
state := evalCtx.State().Lock()
|
||||||
defer ctx.State().Unlock()
|
defer evalCtx.State().Unlock()
|
||||||
|
|
||||||
for modKey, mod := range state.Modules {
|
for modKey, mod := range state.Modules {
|
||||||
// clean out any empty resources
|
// clean out any empty resources
|
||||||
@@ -246,33 +247,33 @@ type nodeValidateModule struct {
|
|||||||
var _ GraphNodeExecutable = (*nodeValidateModule)(nil)
|
var _ GraphNodeExecutable = (*nodeValidateModule)(nil)
|
||||||
|
|
||||||
// GraphNodeEvalable
|
// GraphNodeEvalable
|
||||||
func (n *nodeValidateModule) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *nodeValidateModule) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
_, call := n.Addr.Call()
|
_, call := n.Addr.Call()
|
||||||
expander := ctx.InstanceExpander()
|
expander := evalCtx.InstanceExpander()
|
||||||
|
|
||||||
// Modules all evaluate to single instances during validation, only to
|
// Modules all evaluate to single instances during validation, only to
|
||||||
// create a proper context within which to evaluate. All parent modules
|
// create a proper context within which to evaluate. All parent modules
|
||||||
// will be a single instance, but still get our address in the expected
|
// will be a single instance, but still get our address in the expected
|
||||||
// manner anyway to ensure they've been registered correctly.
|
// manner anyway to ensure they've been registered correctly.
|
||||||
for _, module := range expander.ExpandModule(n.Addr.Parent()) {
|
for _, module := range expander.ExpandModule(n.Addr.Parent()) {
|
||||||
ctx = ctx.WithPath(module)
|
evalCtx = evalCtx.WithPath(module)
|
||||||
|
|
||||||
// Validate our for_each and count expressions at a basic level
|
// Validate our for_each and count expressions at a basic level
|
||||||
// We skip validation on known, because there will be unknown values before
|
// We skip validation on known, because there will be unknown values before
|
||||||
// a full expansion, presuming these errors will be caught in later steps
|
// a full expansion, presuming these errors will be caught in later steps
|
||||||
switch {
|
switch {
|
||||||
case n.ModuleCall.Count != nil:
|
case n.ModuleCall.Count != nil:
|
||||||
_, countDiags := evaluateCountExpressionValue(n.ModuleCall.Count, ctx)
|
_, countDiags := evaluateCountExpressionValue(n.ModuleCall.Count, evalCtx)
|
||||||
diags = diags.Append(countDiags)
|
diags = diags.Append(countDiags)
|
||||||
|
|
||||||
case n.ModuleCall.ForEach != nil:
|
case n.ModuleCall.ForEach != nil:
|
||||||
const unknownsAllowed = true
|
const unknownsAllowed = true
|
||||||
const tupleNotAllowed = false
|
const tupleNotAllowed = false
|
||||||
_, forEachDiags := evaluateForEachExpressionValue(n.ModuleCall.ForEach, ctx, unknownsAllowed, tupleNotAllowed, module)
|
_, forEachDiags := evaluateForEachExpressionValue(n.ModuleCall.ForEach, evalCtx, unknownsAllowed, tupleNotAllowed, module)
|
||||||
diags = diags.Append(forEachDiags)
|
diags = diags.Append(forEachDiags)
|
||||||
}
|
}
|
||||||
|
|
||||||
diags = diags.Append(validateDependsOn(ctx, n.ModuleCall.DependsOn))
|
diags = diags.Append(validateDependsOn(evalCtx, n.ModuleCall.DependsOn))
|
||||||
|
|
||||||
// now set our own mode to single
|
// now set our own mode to single
|
||||||
expander.SetModuleSingle(module, call)
|
expander.SetModuleSingle(module, call)
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNodeExpandModuleExecute(t *testing.T) {
|
func TestNodeExpandModuleExecute(t *testing.T) {
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
InstanceExpanderExpander: instances.NewExpander(),
|
InstanceExpanderExpander: instances.NewExpander(),
|
||||||
}
|
}
|
||||||
ctx.installSimpleEval()
|
evalCtx.installSimpleEval()
|
||||||
|
|
||||||
node := nodeExpandModule{
|
node := nodeExpandModule{
|
||||||
Addr: addrs.Module{"child"},
|
Addr: addrs.Module{"child"},
|
||||||
@@ -29,12 +29,12 @@ func TestNodeExpandModuleExecute(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := node.Execute(ctx, walkApply)
|
err := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.InstanceExpanderCalled {
|
if !evalCtx.InstanceExpanderCalled {
|
||||||
t.Fatal("did not expand")
|
t.Fatal("did not expand")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,11 +43,11 @@ func TestNodeCloseModuleExecute(t *testing.T) {
|
|||||||
t.Run("walkApply", func(t *testing.T) {
|
t.Run("walkApply", func(t *testing.T) {
|
||||||
state := states.NewState()
|
state := states.NewState()
|
||||||
state.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey))
|
state.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey))
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
}
|
}
|
||||||
node := nodeCloseModule{Addr: addrs.Module{"child"}}
|
node := nodeCloseModule{Addr: addrs.Module{"child"}}
|
||||||
diags := node.Execute(ctx, walkApply)
|
diags := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %s", diags.Err())
|
t.Fatalf("unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ func TestNodeCloseModuleExecute(t *testing.T) {
|
|||||||
|
|
||||||
// the root module should do all the module cleanup
|
// the root module should do all the module cleanup
|
||||||
node = nodeCloseModule{Addr: addrs.RootModule}
|
node = nodeCloseModule{Addr: addrs.RootModule}
|
||||||
diags = node.Execute(ctx, walkApply)
|
diags = node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %s", diags.Err())
|
t.Fatalf("unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
@@ -74,12 +74,12 @@ func TestNodeCloseModuleExecute(t *testing.T) {
|
|||||||
t.Run("walkImport", func(t *testing.T) {
|
t.Run("walkImport", func(t *testing.T) {
|
||||||
state := states.NewState()
|
state := states.NewState()
|
||||||
state.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey))
|
state.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey))
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
}
|
}
|
||||||
node := nodeCloseModule{Addr: addrs.Module{"child"}}
|
node := nodeCloseModule{Addr: addrs.Module{"child"}}
|
||||||
|
|
||||||
diags := node.Execute(ctx, walkImport)
|
diags := node.Execute(t.Context(), evalCtx, walkImport)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %s", diags.Err())
|
t.Fatalf("unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
@@ -91,10 +91,10 @@ func TestNodeCloseModuleExecute(t *testing.T) {
|
|||||||
|
|
||||||
func TestNodeValidateModuleExecute(t *testing.T) {
|
func TestNodeValidateModuleExecute(t *testing.T) {
|
||||||
t.Run("success", func(t *testing.T) {
|
t.Run("success", func(t *testing.T) {
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
InstanceExpanderExpander: instances.NewExpander(),
|
InstanceExpanderExpander: instances.NewExpander(),
|
||||||
}
|
}
|
||||||
ctx.installSimpleEval()
|
evalCtx.installSimpleEval()
|
||||||
node := nodeValidateModule{
|
node := nodeValidateModule{
|
||||||
nodeExpandModule{
|
nodeExpandModule{
|
||||||
Addr: addrs.Module{"child"},
|
Addr: addrs.Module{"child"},
|
||||||
@@ -104,17 +104,17 @@ func TestNodeValidateModuleExecute(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
diags := node.Execute(ctx, walkApply)
|
diags := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %v", diags.Err())
|
t.Fatalf("unexpected error: %v", diags.Err())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("invalid count", func(t *testing.T) {
|
t.Run("invalid count", func(t *testing.T) {
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
InstanceExpanderExpander: instances.NewExpander(),
|
InstanceExpanderExpander: instances.NewExpander(),
|
||||||
}
|
}
|
||||||
ctx.installSimpleEval()
|
evalCtx.installSimpleEval()
|
||||||
node := nodeValidateModule{
|
node := nodeValidateModule{
|
||||||
nodeExpandModule{
|
nodeExpandModule{
|
||||||
Addr: addrs.Module{"child"},
|
Addr: addrs.Module{"child"},
|
||||||
@@ -124,7 +124,7 @@ func TestNodeValidateModuleExecute(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := node.Execute(ctx, walkApply)
|
err := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error, got success")
|
t.Fatal("expected error, got success")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -150,10 +151,10 @@ func (n *nodeModuleVariable) ModulePath() addrs.Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *nodeModuleVariable) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *nodeModuleVariable) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
log.Printf("[TRACE] nodeModuleVariable: evaluating %s", n.Addr)
|
log.Printf("[TRACE] nodeModuleVariable: evaluating %s", n.Addr)
|
||||||
|
|
||||||
val, err := n.evalModuleVariable(ctx, op == walkValidate)
|
val, err := n.evalModuleVariable(evalCtx, op == walkValidate)
|
||||||
diags = diags.Append(err)
|
diags = diags.Append(err)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
@@ -162,7 +163,7 @@ func (n *nodeModuleVariable) Execute(ctx EvalContext, op walkOperation) (diags t
|
|||||||
// Set values for arguments of a child module call, for later retrieval
|
// Set values for arguments of a child module call, for later retrieval
|
||||||
// during expression evaluation.
|
// during expression evaluation.
|
||||||
_, call := n.Addr.Module.CallInstance()
|
_, call := n.Addr.Module.CallInstance()
|
||||||
ctx.SetModuleCallArgument(call, n.Addr.Variable, val)
|
evalCtx.SetModuleCallArgument(call, n.Addr.Variable, val)
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -302,13 +303,13 @@ func (n *NodeApplyableOutput) References() []*addrs.Reference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *NodeApplyableOutput) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *NodeApplyableOutput) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
state := ctx.State()
|
state := evalCtx.State()
|
||||||
if state == nil {
|
if state == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
changes := ctx.Changes() // may be nil, if we're not working on a changeset
|
changes := evalCtx.Changes() // may be nil, if we're not working on a changeset
|
||||||
|
|
||||||
val := cty.UnknownVal(cty.DynamicPseudoType)
|
val := cty.UnknownVal(cty.DynamicPseudoType)
|
||||||
changeRecorded := n.Change != nil
|
changeRecorded := n.Change != nil
|
||||||
@@ -332,7 +333,7 @@ func (n *NodeApplyableOutput) Execute(ctx EvalContext, op walkOperation) (diags
|
|||||||
checkDiags := evalCheckRules(
|
checkDiags := evalCheckRules(
|
||||||
addrs.OutputPrecondition,
|
addrs.OutputPrecondition,
|
||||||
n.Config.Preconditions,
|
n.Config.Preconditions,
|
||||||
ctx, n.Addr, EvalDataForNoInstanceKey,
|
evalCtx, n.Addr, EvalDataForNoInstanceKey,
|
||||||
checkRuleSeverity,
|
checkRuleSeverity,
|
||||||
)
|
)
|
||||||
diags = diags.Append(checkDiags)
|
diags = diags.Append(checkDiags)
|
||||||
@@ -350,7 +351,7 @@ func (n *NodeApplyableOutput) Execute(ctx EvalContext, op walkOperation) (diags
|
|||||||
// This has to run before we have a state lock, since evaluation also
|
// This has to run before we have a state lock, since evaluation also
|
||||||
// reads the state
|
// reads the state
|
||||||
var evalDiags tfdiags.Diagnostics
|
var evalDiags tfdiags.Diagnostics
|
||||||
val, evalDiags = ctx.EvaluateExpr(n.Config.Expr, cty.DynamicPseudoType, nil)
|
val, evalDiags = evalCtx.EvaluateExpr(n.Config.Expr, cty.DynamicPseudoType, nil)
|
||||||
diags = diags.Append(evalDiags)
|
diags = diags.Append(evalDiags)
|
||||||
|
|
||||||
// If the module is being overridden and we have a value to use,
|
// If the module is being overridden and we have a value to use,
|
||||||
@@ -367,7 +368,7 @@ func (n *NodeApplyableOutput) Execute(ctx EvalContext, op walkOperation) (diags
|
|||||||
// We'll handle errors below, after we have loaded the module.
|
// We'll handle errors below, after we have loaded the module.
|
||||||
// Outputs don't have a separate mode for validation, so validate
|
// Outputs don't have a separate mode for validation, so validate
|
||||||
// depends_on expressions here too
|
// depends_on expressions here too
|
||||||
diags = diags.Append(validateDependsOn(ctx, n.Config.DependsOn))
|
diags = diags.Append(validateDependsOn(evalCtx, n.Config.DependsOn))
|
||||||
|
|
||||||
// For root module outputs in particular, an output value must be
|
// For root module outputs in particular, an output value must be
|
||||||
// statically declared as sensitive in order to dynamically return
|
// statically declared as sensitive in order to dynamically return
|
||||||
@@ -419,7 +420,7 @@ If you do intend to export this data, annotate the output value as sensitive by
|
|||||||
|
|
||||||
// If we were able to evaluate a new value, we can update that in the
|
// If we were able to evaluate a new value, we can update that in the
|
||||||
// refreshed state as well.
|
// refreshed state as well.
|
||||||
if state = ctx.RefreshState(); state != nil && val.IsWhollyKnown() {
|
if state = evalCtx.RefreshState(); state != nil && val.IsWhollyKnown() {
|
||||||
// we only need to update the state, do not pass in the changes again
|
// we only need to update the state, do not pass in the changes again
|
||||||
n.setValue(state, nil, val)
|
n.setValue(state, nil, val)
|
||||||
}
|
}
|
||||||
@@ -465,8 +466,8 @@ func (n *NodeDestroyableOutput) temporaryValue() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *NodeDestroyableOutput) Execute(ctx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
func (n *NodeDestroyableOutput) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
||||||
state := ctx.State()
|
state := evalCtx.State()
|
||||||
if state == nil {
|
if state == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -488,7 +489,7 @@ func (n *NodeDestroyableOutput) Execute(ctx EvalContext, op walkOperation) tfdia
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
changes := ctx.Changes()
|
changes := evalCtx.Changes()
|
||||||
if changes != nil && n.Planning {
|
if changes != nil && n.Planning {
|
||||||
change := &plans.OutputChange{
|
change := &plans.OutputChange{
|
||||||
Addr: n.Addr,
|
Addr: n.Addr,
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNodeApplyableOutputExecute_knownValue(t *testing.T) {
|
func TestNodeApplyableOutputExecute_knownValue(t *testing.T) {
|
||||||
ctx := new(MockEvalContext)
|
evalCtx := new(MockEvalContext)
|
||||||
ctx.StateState = states.NewState().SyncWrapper()
|
evalCtx.StateState = states.NewState().SyncWrapper()
|
||||||
ctx.RefreshStateState = states.NewState().SyncWrapper()
|
evalCtx.RefreshStateState = states.NewState().SyncWrapper()
|
||||||
ctx.ChecksState = checks.NewState(nil)
|
evalCtx.ChecksState = checks.NewState(nil)
|
||||||
|
|
||||||
config := &configs.Output{Name: "map-output"}
|
config := &configs.Output{Name: "map-output"}
|
||||||
addr := addrs.OutputValue{Name: config.Name}.Absolute(addrs.RootModuleInstance)
|
addr := addrs.OutputValue{Name: config.Name}.Absolute(addrs.RootModuleInstance)
|
||||||
@@ -31,29 +31,29 @@ func TestNodeApplyableOutputExecute_knownValue(t *testing.T) {
|
|||||||
val := cty.MapVal(map[string]cty.Value{
|
val := cty.MapVal(map[string]cty.Value{
|
||||||
"a": cty.StringVal("b"),
|
"a": cty.StringVal("b"),
|
||||||
})
|
})
|
||||||
ctx.EvaluateExprResult = val
|
evalCtx.EvaluateExprResult = val
|
||||||
|
|
||||||
err := node.Execute(ctx, walkApply)
|
err := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected execute error: %s", err)
|
t.Fatalf("unexpected execute error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
outputVal := ctx.StateState.OutputValue(addr)
|
outputVal := evalCtx.StateState.OutputValue(addr)
|
||||||
if got, want := outputVal.Value, val; !got.RawEquals(want) {
|
if got, want := outputVal.Value, val; !got.RawEquals(want) {
|
||||||
t.Errorf("wrong output value in state\n got: %#v\nwant: %#v", got, want)
|
t.Errorf("wrong output value in state\n got: %#v\nwant: %#v", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.RefreshStateCalled {
|
if !evalCtx.RefreshStateCalled {
|
||||||
t.Fatal("should have called RefreshState, but didn't")
|
t.Fatal("should have called RefreshState, but didn't")
|
||||||
}
|
}
|
||||||
refreshOutputVal := ctx.RefreshStateState.OutputValue(addr)
|
refreshOutputVal := evalCtx.RefreshStateState.OutputValue(addr)
|
||||||
if got, want := refreshOutputVal.Value, val; !got.RawEquals(want) {
|
if got, want := refreshOutputVal.Value, val; !got.RawEquals(want) {
|
||||||
t.Fatalf("wrong output value in refresh state\n got: %#v\nwant: %#v", got, want)
|
t.Fatalf("wrong output value in refresh state\n got: %#v\nwant: %#v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNodeApplyableOutputExecute_noState(t *testing.T) {
|
func TestNodeApplyableOutputExecute_noState(t *testing.T) {
|
||||||
ctx := new(MockEvalContext)
|
evalCtx := new(MockEvalContext)
|
||||||
|
|
||||||
config := &configs.Output{Name: "map-output"}
|
config := &configs.Output{Name: "map-output"}
|
||||||
addr := addrs.OutputValue{Name: config.Name}.Absolute(addrs.RootModuleInstance)
|
addr := addrs.OutputValue{Name: config.Name}.Absolute(addrs.RootModuleInstance)
|
||||||
@@ -61,18 +61,18 @@ func TestNodeApplyableOutputExecute_noState(t *testing.T) {
|
|||||||
val := cty.MapVal(map[string]cty.Value{
|
val := cty.MapVal(map[string]cty.Value{
|
||||||
"a": cty.StringVal("b"),
|
"a": cty.StringVal("b"),
|
||||||
})
|
})
|
||||||
ctx.EvaluateExprResult = val
|
evalCtx.EvaluateExprResult = val
|
||||||
|
|
||||||
err := node.Execute(ctx, walkApply)
|
err := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected execute error: %s", err)
|
t.Fatalf("unexpected execute error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNodeApplyableOutputExecute_invalidDependsOn(t *testing.T) {
|
func TestNodeApplyableOutputExecute_invalidDependsOn(t *testing.T) {
|
||||||
ctx := new(MockEvalContext)
|
evalCtx := new(MockEvalContext)
|
||||||
ctx.StateState = states.NewState().SyncWrapper()
|
evalCtx.StateState = states.NewState().SyncWrapper()
|
||||||
ctx.ChecksState = checks.NewState(nil)
|
evalCtx.ChecksState = checks.NewState(nil)
|
||||||
|
|
||||||
config := &configs.Output{
|
config := &configs.Output{
|
||||||
Name: "map-output",
|
Name: "map-output",
|
||||||
@@ -89,9 +89,9 @@ func TestNodeApplyableOutputExecute_invalidDependsOn(t *testing.T) {
|
|||||||
val := cty.MapVal(map[string]cty.Value{
|
val := cty.MapVal(map[string]cty.Value{
|
||||||
"a": cty.StringVal("b"),
|
"a": cty.StringVal("b"),
|
||||||
})
|
})
|
||||||
ctx.EvaluateExprResult = val
|
evalCtx.EvaluateExprResult = val
|
||||||
|
|
||||||
diags := node.Execute(ctx, walkApply)
|
diags := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if !diags.HasErrors() {
|
if !diags.HasErrors() {
|
||||||
t.Fatal("expected execute error, but there was none")
|
t.Fatal("expected execute error, but there was none")
|
||||||
}
|
}
|
||||||
@@ -101,9 +101,9 @@ func TestNodeApplyableOutputExecute_invalidDependsOn(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNodeApplyableOutputExecute_sensitiveValueNotOutput(t *testing.T) {
|
func TestNodeApplyableOutputExecute_sensitiveValueNotOutput(t *testing.T) {
|
||||||
ctx := new(MockEvalContext)
|
evalCtx := new(MockEvalContext)
|
||||||
ctx.StateState = states.NewState().SyncWrapper()
|
evalCtx.StateState = states.NewState().SyncWrapper()
|
||||||
ctx.ChecksState = checks.NewState(nil)
|
evalCtx.ChecksState = checks.NewState(nil)
|
||||||
|
|
||||||
config := &configs.Output{Name: "map-output"}
|
config := &configs.Output{Name: "map-output"}
|
||||||
addr := addrs.OutputValue{Name: config.Name}.Absolute(addrs.RootModuleInstance)
|
addr := addrs.OutputValue{Name: config.Name}.Absolute(addrs.RootModuleInstance)
|
||||||
@@ -111,9 +111,9 @@ func TestNodeApplyableOutputExecute_sensitiveValueNotOutput(t *testing.T) {
|
|||||||
val := cty.MapVal(map[string]cty.Value{
|
val := cty.MapVal(map[string]cty.Value{
|
||||||
"a": cty.StringVal("b").Mark(marks.Sensitive),
|
"a": cty.StringVal("b").Mark(marks.Sensitive),
|
||||||
})
|
})
|
||||||
ctx.EvaluateExprResult = val
|
evalCtx.EvaluateExprResult = val
|
||||||
|
|
||||||
diags := node.Execute(ctx, walkApply)
|
diags := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if !diags.HasErrors() {
|
if !diags.HasErrors() {
|
||||||
t.Fatal("expected execute error, but there was none")
|
t.Fatal("expected execute error, but there was none")
|
||||||
}
|
}
|
||||||
@@ -123,9 +123,9 @@ func TestNodeApplyableOutputExecute_sensitiveValueNotOutput(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNodeApplyableOutputExecute_deprecatedOutput(t *testing.T) {
|
func TestNodeApplyableOutputExecute_deprecatedOutput(t *testing.T) {
|
||||||
ctx := new(MockEvalContext)
|
evalCtx := new(MockEvalContext)
|
||||||
ctx.StateState = states.NewState().SyncWrapper()
|
evalCtx.StateState = states.NewState().SyncWrapper()
|
||||||
ctx.ChecksState = checks.NewState(nil)
|
evalCtx.ChecksState = checks.NewState(nil)
|
||||||
|
|
||||||
config := &configs.Output{Name: "map-output"}
|
config := &configs.Output{Name: "map-output"}
|
||||||
addr := addrs.OutputValue{Name: config.Name}.Absolute(addrs.RootModuleInstance)
|
addr := addrs.OutputValue{Name: config.Name}.Absolute(addrs.RootModuleInstance)
|
||||||
@@ -133,13 +133,13 @@ func TestNodeApplyableOutputExecute_deprecatedOutput(t *testing.T) {
|
|||||||
val := cty.MapVal(map[string]cty.Value{
|
val := cty.MapVal(map[string]cty.Value{
|
||||||
"a": marks.Deprecated(cty.StringVal("b"), marks.DeprecationCause{}),
|
"a": marks.Deprecated(cty.StringVal("b"), marks.DeprecationCause{}),
|
||||||
})
|
})
|
||||||
ctx.EvaluateExprResult = val
|
evalCtx.EvaluateExprResult = val
|
||||||
|
|
||||||
// We set a value with no deprecation marks to check if the marks
|
// We set a value with no deprecation marks to check if the marks
|
||||||
// will be updated in the state.
|
// will be updated in the state.
|
||||||
ctx.StateState.SetOutputValue(addr, marks.RemoveDeepDeprecated(val), false, "")
|
evalCtx.StateState.SetOutputValue(addr, marks.RemoveDeepDeprecated(val), false, "")
|
||||||
|
|
||||||
diags := node.Execute(ctx, walkApply)
|
diags := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("Got unexpected error: %v", diags)
|
t.Fatalf("Got unexpected error: %v", diags)
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ func TestNodeApplyableOutputExecute_deprecatedOutput(t *testing.T) {
|
|||||||
t.Fatalf("Invalid mod addr in test: %v", diags)
|
t.Fatalf("Invalid mod addr in test: %v", diags)
|
||||||
}
|
}
|
||||||
|
|
||||||
stateVal := ctx.StateState.OutputValue(modOutputAddr)
|
stateVal := evalCtx.StateState.OutputValue(modOutputAddr)
|
||||||
|
|
||||||
_, pvms := stateVal.Value.UnmarkDeepWithPaths()
|
_, pvms := stateVal.Value.UnmarkDeepWithPaths()
|
||||||
if len(pvms) != 1 {
|
if len(pvms) != 1 {
|
||||||
@@ -162,9 +162,9 @@ func TestNodeApplyableOutputExecute_deprecatedOutput(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNodeApplyableOutputExecute_alternativelyMarkedValue(t *testing.T) {
|
func TestNodeApplyableOutputExecute_alternativelyMarkedValue(t *testing.T) {
|
||||||
ctx := new(MockEvalContext)
|
evalCtx := new(MockEvalContext)
|
||||||
ctx.StateState = states.NewState().SyncWrapper()
|
evalCtx.StateState = states.NewState().SyncWrapper()
|
||||||
ctx.ChecksState = checks.NewState(nil)
|
evalCtx.ChecksState = checks.NewState(nil)
|
||||||
|
|
||||||
config := &configs.Output{Name: "map-output"}
|
config := &configs.Output{Name: "map-output"}
|
||||||
addr := addrs.OutputValue{Name: config.Name}.Absolute(addrs.RootModuleInstance)
|
addr := addrs.OutputValue{Name: config.Name}.Absolute(addrs.RootModuleInstance)
|
||||||
@@ -172,9 +172,9 @@ func TestNodeApplyableOutputExecute_alternativelyMarkedValue(t *testing.T) {
|
|||||||
val := cty.MapVal(map[string]cty.Value{
|
val := cty.MapVal(map[string]cty.Value{
|
||||||
"a": cty.StringVal("b").Mark("alternative-mark"),
|
"a": cty.StringVal("b").Mark("alternative-mark"),
|
||||||
})
|
})
|
||||||
ctx.EvaluateExprResult = val
|
evalCtx.EvaluateExprResult = val
|
||||||
|
|
||||||
diags := node.Execute(ctx, walkApply)
|
diags := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("Got unexpected error: %v", diags)
|
t.Fatalf("Got unexpected error: %v", diags)
|
||||||
}
|
}
|
||||||
@@ -184,7 +184,7 @@ func TestNodeApplyableOutputExecute_alternativelyMarkedValue(t *testing.T) {
|
|||||||
t.Fatalf("Invalid mod addr in test: %v", diags)
|
t.Fatalf("Invalid mod addr in test: %v", diags)
|
||||||
}
|
}
|
||||||
|
|
||||||
stateVal := ctx.StateState.OutputValue(modOutputAddr)
|
stateVal := evalCtx.StateState.OutputValue(modOutputAddr)
|
||||||
|
|
||||||
_, pvms := stateVal.Value.UnmarkDeepWithPaths()
|
_, pvms := stateVal.Value.UnmarkDeepWithPaths()
|
||||||
if len(pvms) != 1 {
|
if len(pvms) != 1 {
|
||||||
@@ -199,9 +199,9 @@ func TestNodeApplyableOutputExecute_alternativelyMarkedValue(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNodeApplyableOutputExecute_sensitiveValueAndOutput(t *testing.T) {
|
func TestNodeApplyableOutputExecute_sensitiveValueAndOutput(t *testing.T) {
|
||||||
ctx := new(MockEvalContext)
|
evalCtx := new(MockEvalContext)
|
||||||
ctx.StateState = states.NewState().SyncWrapper()
|
evalCtx.StateState = states.NewState().SyncWrapper()
|
||||||
ctx.ChecksState = checks.NewState(nil)
|
evalCtx.ChecksState = checks.NewState(nil)
|
||||||
|
|
||||||
config := &configs.Output{
|
config := &configs.Output{
|
||||||
Name: "map-output",
|
Name: "map-output",
|
||||||
@@ -212,15 +212,15 @@ func TestNodeApplyableOutputExecute_sensitiveValueAndOutput(t *testing.T) {
|
|||||||
val := cty.MapVal(map[string]cty.Value{
|
val := cty.MapVal(map[string]cty.Value{
|
||||||
"a": cty.StringVal("b").Mark(marks.Sensitive),
|
"a": cty.StringVal("b").Mark(marks.Sensitive),
|
||||||
})
|
})
|
||||||
ctx.EvaluateExprResult = val
|
evalCtx.EvaluateExprResult = val
|
||||||
|
|
||||||
err := node.Execute(ctx, walkApply)
|
err := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected execute error: %s", err)
|
t.Fatalf("unexpected execute error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmarked value should be stored in state
|
// Unmarked value should be stored in state
|
||||||
outputVal := ctx.StateState.OutputValue(addr)
|
outputVal := evalCtx.StateState.OutputValue(addr)
|
||||||
want, _ := val.UnmarkDeep()
|
want, _ := val.UnmarkDeep()
|
||||||
if got := outputVal.Value; !got.RawEquals(want) {
|
if got := outputVal.Value; !got.RawEquals(want) {
|
||||||
t.Errorf("wrong output value in state\n got: %#v\nwant: %#v", got, want)
|
t.Errorf("wrong output value in state\n got: %#v\nwant: %#v", got, want)
|
||||||
@@ -234,12 +234,12 @@ func TestNodeDestroyableOutputExecute(t *testing.T) {
|
|||||||
state.Module(addrs.RootModuleInstance).SetOutputValue("foo", cty.StringVal("bar"), false, "")
|
state.Module(addrs.RootModuleInstance).SetOutputValue("foo", cty.StringVal("bar"), false, "")
|
||||||
state.OutputValue(outputAddr)
|
state.OutputValue(outputAddr)
|
||||||
|
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
}
|
}
|
||||||
node := NodeDestroyableOutput{Addr: outputAddr}
|
node := NodeDestroyableOutput{Addr: outputAddr}
|
||||||
|
|
||||||
diags := node.Execute(ctx, walkApply)
|
diags := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("Unexpected error: %s", diags.Err())
|
t.Fatalf("Unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
@@ -253,12 +253,12 @@ func TestNodeDestroyableOutputExecute_notInState(t *testing.T) {
|
|||||||
|
|
||||||
state := states.NewState()
|
state := states.NewState()
|
||||||
|
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
}
|
}
|
||||||
node := NodeDestroyableOutput{Addr: outputAddr}
|
node := NodeDestroyableOutput{Addr: outputAddr}
|
||||||
|
|
||||||
diags := node.Execute(ctx, walkApply)
|
diags := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("Unexpected error: %s", diags.Err())
|
t.Fatalf("Unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -27,11 +28,11 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *NodeApplyableProvider) Execute(ctx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
func (n *NodeApplyableProvider) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
||||||
instances, diags := n.initInstances(ctx, op)
|
instances, diags := n.initInstances(evalCtx, op)
|
||||||
|
|
||||||
for key, provider := range instances {
|
for key, provider := range instances {
|
||||||
diags = diags.Append(n.executeInstance(ctx, op, key, provider))
|
diags = diags.Append(n.executeInstance(evalCtx, op, key, provider))
|
||||||
}
|
}
|
||||||
|
|
||||||
return diags
|
return diags
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
)
|
)
|
||||||
@@ -21,7 +23,7 @@ type NodeEvalableProvider struct {
|
|||||||
var _ GraphNodeExecutable = (*NodeEvalableProvider)(nil)
|
var _ GraphNodeExecutable = (*NodeEvalableProvider)(nil)
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *NodeEvalableProvider) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *NodeEvalableProvider) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
_, err := ctx.InitProvider(n.Addr, addrs.NoKey)
|
_, err := evalCtx.InitProvider(n.Addr, addrs.NoKey)
|
||||||
return diags.Append(err)
|
return diags.Append(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,21 +51,21 @@ func TestNodeApplyableProviderExecute(t *testing.T) {
|
|||||||
Config: config,
|
Config: config,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
ctx := &MockEvalContext{ProviderProvider: provider}
|
evalCtx := &MockEvalContext{ProviderProvider: provider}
|
||||||
ctx.installSimpleEval()
|
evalCtx.installSimpleEval()
|
||||||
ctx.ProviderInputValues = map[string]cty.Value{
|
evalCtx.ProviderInputValues = map[string]cty.Value{
|
||||||
"pw": cty.StringVal("so secret"),
|
"pw": cty.StringVal("so secret"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if diags := n.Execute(ctx, walkApply); diags.HasErrors() {
|
if diags := n.Execute(t.Context(), evalCtx, walkApply); diags.HasErrors() {
|
||||||
t.Fatalf("err: %s", diags.Err())
|
t.Fatalf("err: %s", diags.Err())
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.ConfigureProviderCalled {
|
if !evalCtx.ConfigureProviderCalled {
|
||||||
t.Fatal("should be called")
|
t.Fatal("should be called")
|
||||||
}
|
}
|
||||||
|
|
||||||
gotObj := ctx.ConfigureProviderConfig
|
gotObj := evalCtx.ConfigureProviderConfig
|
||||||
if !gotObj.Type().HasAttribute("user") {
|
if !gotObj.Type().HasAttribute("user") {
|
||||||
t.Fatal("configuration object does not have \"user\" attribute")
|
t.Fatal("configuration object does not have \"user\" attribute")
|
||||||
}
|
}
|
||||||
@@ -98,10 +98,10 @@ func TestNodeApplyableProviderExecute_unknownImport(t *testing.T) {
|
|||||||
Config: config,
|
Config: config,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
ctx := &MockEvalContext{ProviderProvider: provider}
|
evalCtx := &MockEvalContext{ProviderProvider: provider}
|
||||||
ctx.installSimpleEval()
|
evalCtx.installSimpleEval()
|
||||||
|
|
||||||
diags := n.Execute(ctx, walkImport)
|
diags := n.Execute(t.Context(), evalCtx, walkImport)
|
||||||
if !diags.HasErrors() {
|
if !diags.HasErrors() {
|
||||||
t.Fatal("expected error, got success")
|
t.Fatal("expected error, got success")
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,7 @@ func TestNodeApplyableProviderExecute_unknownImport(t *testing.T) {
|
|||||||
t.Errorf("wrong diagnostic detail\n got: %q\nwant: %q", got, want)
|
t.Errorf("wrong diagnostic detail\n got: %q\nwant: %q", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.ConfigureProviderCalled {
|
if evalCtx.ConfigureProviderCalled {
|
||||||
t.Fatal("should not be called")
|
t.Fatal("should not be called")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,18 +132,18 @@ func TestNodeApplyableProviderExecute_unknownApply(t *testing.T) {
|
|||||||
Addr: providerAddr,
|
Addr: providerAddr,
|
||||||
Config: config,
|
Config: config,
|
||||||
}}
|
}}
|
||||||
ctx := &MockEvalContext{ProviderProvider: provider}
|
evalCtx := &MockEvalContext{ProviderProvider: provider}
|
||||||
ctx.installSimpleEval()
|
evalCtx.installSimpleEval()
|
||||||
|
|
||||||
if err := n.Execute(ctx, walkApply); err != nil {
|
if err := n.Execute(t.Context(), evalCtx, walkApply); err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.ConfigureProviderCalled {
|
if !evalCtx.ConfigureProviderCalled {
|
||||||
t.Fatal("should be called")
|
t.Fatal("should be called")
|
||||||
}
|
}
|
||||||
|
|
||||||
gotObj := ctx.ConfigureProviderConfig
|
gotObj := evalCtx.ConfigureProviderConfig
|
||||||
if !gotObj.Type().HasAttribute("test_string") {
|
if !gotObj.Type().HasAttribute("test_string") {
|
||||||
t.Fatal("configuration object does not have \"test_string\" attribute")
|
t.Fatal("configuration object does not have \"test_string\" attribute")
|
||||||
}
|
}
|
||||||
@@ -170,17 +170,17 @@ func TestNodeApplyableProviderExecute_sensitive(t *testing.T) {
|
|||||||
Config: config,
|
Config: config,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
ctx := &MockEvalContext{ProviderProvider: provider}
|
evalCtx := &MockEvalContext{ProviderProvider: provider}
|
||||||
ctx.installSimpleEval()
|
evalCtx.installSimpleEval()
|
||||||
if err := n.Execute(ctx, walkApply); err != nil {
|
if err := n.Execute(t.Context(), evalCtx, walkApply); err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.ConfigureProviderCalled {
|
if !evalCtx.ConfigureProviderCalled {
|
||||||
t.Fatal("should be called")
|
t.Fatal("should be called")
|
||||||
}
|
}
|
||||||
|
|
||||||
gotObj := ctx.ConfigureProviderConfig
|
gotObj := evalCtx.ConfigureProviderConfig
|
||||||
if !gotObj.Type().HasAttribute("test_string") {
|
if !gotObj.Type().HasAttribute("test_string") {
|
||||||
t.Fatal("configuration object does not have \"test_string\" attribute")
|
t.Fatal("configuration object does not have \"test_string\" attribute")
|
||||||
}
|
}
|
||||||
@@ -207,9 +207,9 @@ func TestNodeApplyableProviderExecute_sensitiveValidate(t *testing.T) {
|
|||||||
Config: config,
|
Config: config,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
ctx := &MockEvalContext{ProviderProvider: provider}
|
evalCtx := &MockEvalContext{ProviderProvider: provider}
|
||||||
ctx.installSimpleEval()
|
evalCtx.installSimpleEval()
|
||||||
if err := n.Execute(ctx, walkValidate); err != nil {
|
if err := n.Execute(t.Context(), evalCtx, walkValidate); err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,13 +249,13 @@ func TestNodeApplyableProviderExecute_emptyValidate(t *testing.T) {
|
|||||||
Config: config,
|
Config: config,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
ctx := &MockEvalContext{ProviderProvider: provider}
|
evalCtx := &MockEvalContext{ProviderProvider: provider}
|
||||||
ctx.installSimpleEval()
|
evalCtx.installSimpleEval()
|
||||||
if err := n.Execute(ctx, walkValidate); err != nil {
|
if err := n.Execute(t.Context(), evalCtx, walkValidate); err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.ConfigureProviderCalled {
|
if evalCtx.ConfigureProviderCalled {
|
||||||
t.Fatal("should not be called")
|
t.Fatal("should not be called")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
)
|
)
|
||||||
@@ -19,6 +21,7 @@ type nodeExpandApplyableResource struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
_ GraphNodeExecutable = (*nodeExpandApplyableResource)(nil)
|
||||||
_ GraphNodeReferenceable = (*nodeExpandApplyableResource)(nil)
|
_ GraphNodeReferenceable = (*nodeExpandApplyableResource)(nil)
|
||||||
_ GraphNodeReferencer = (*nodeExpandApplyableResource)(nil)
|
_ GraphNodeReferencer = (*nodeExpandApplyableResource)(nil)
|
||||||
_ GraphNodeConfigResource = (*nodeExpandApplyableResource)(nil)
|
_ GraphNodeConfigResource = (*nodeExpandApplyableResource)(nil)
|
||||||
@@ -48,13 +51,13 @@ func (n *nodeExpandApplyableResource) Name() string {
|
|||||||
return n.NodeAbstractResource.Name() + " (expand)"
|
return n.NodeAbstractResource.Name() + " (expand)"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nodeExpandApplyableResource) Execute(ctx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
func (n *nodeExpandApplyableResource) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
||||||
var diags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
expander := ctx.InstanceExpander()
|
expander := evalCtx.InstanceExpander()
|
||||||
moduleInstances := expander.ExpandModule(n.Addr.Module)
|
moduleInstances := expander.ExpandModule(n.Addr.Module)
|
||||||
for _, module := range moduleInstances {
|
for _, module := range moduleInstances {
|
||||||
ctx = ctx.WithPath(module)
|
evalCtx = evalCtx.WithPath(module)
|
||||||
diags = diags.Append(n.writeResourceState(ctx, n.Addr.Resource.Absolute(module)))
|
diags = diags.Append(n.writeResourceState(evalCtx, n.Addr.Resource.Absolute(module)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return diags
|
return diags
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -116,14 +117,14 @@ func (n *NodeApplyableResourceInstance) AttachDependencies(deps []addrs.ConfigRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *NodeApplyableResourceInstance) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *NodeApplyableResourceInstance) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
addr := n.ResourceInstanceAddr()
|
addr := n.ResourceInstanceAddr()
|
||||||
|
|
||||||
if n.Config == nil {
|
if n.Config == nil {
|
||||||
// If there is no config, and there is no change, then we have nothing
|
// If there is no config, and there is no change, then we have nothing
|
||||||
// to do and the change was left in the plan for informational
|
// to do and the change was left in the plan for informational
|
||||||
// purposes only.
|
// purposes only.
|
||||||
changes := ctx.Changes()
|
changes := evalCtx.Changes()
|
||||||
csrc := changes.GetResourceInstanceChange(n.ResourceInstanceAddr(), states.CurrentGen)
|
csrc := changes.GetResourceInstanceChange(n.ResourceInstanceAddr(), states.CurrentGen)
|
||||||
if csrc == nil || csrc.Action == plans.NoOp {
|
if csrc == nil || csrc.Action == plans.NoOp {
|
||||||
log.Printf("[DEBUG] NodeApplyableResourceInstance: No config or planned change recorded for %s", n.Addr)
|
log.Printf("[DEBUG] NodeApplyableResourceInstance: No config or planned change recorded for %s", n.Addr)
|
||||||
@@ -141,7 +142,7 @@ func (n *NodeApplyableResourceInstance) Execute(ctx EvalContext, op walkOperatio
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
diags = n.resolveProvider(ctx, true, states.NotDeposed)
|
diags = n.resolveProvider(evalCtx, true, states.NotDeposed)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
@@ -149,9 +150,9 @@ func (n *NodeApplyableResourceInstance) Execute(ctx EvalContext, op walkOperatio
|
|||||||
// Eval info is different depending on what kind of resource this is
|
// Eval info is different depending on what kind of resource this is
|
||||||
switch n.Config.Mode {
|
switch n.Config.Mode {
|
||||||
case addrs.ManagedResourceMode:
|
case addrs.ManagedResourceMode:
|
||||||
return n.managedResourceExecute(ctx)
|
return n.managedResourceExecute(evalCtx)
|
||||||
case addrs.DataResourceMode:
|
case addrs.DataResourceMode:
|
||||||
return n.dataResourceExecute(ctx)
|
return n.dataResourceExecute(evalCtx)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
|
panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import (
|
|||||||
func TestNodeExpandApplyableResourceExecute(t *testing.T) {
|
func TestNodeExpandApplyableResourceExecute(t *testing.T) {
|
||||||
state := states.NewState()
|
state := states.NewState()
|
||||||
t.Run("no config", func(t *testing.T) {
|
t.Run("no config", func(t *testing.T) {
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
InstanceExpanderExpander: instances.NewExpander(),
|
InstanceExpanderExpander: instances.NewExpander(),
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ func TestNodeExpandApplyableResourceExecute(t *testing.T) {
|
|||||||
Config: nil,
|
Config: nil,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
diags := node.Execute(ctx, walkApply)
|
diags := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %s", diags.Err())
|
t.Fatalf("unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ func TestNodeExpandApplyableResourceExecute(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("simple", func(t *testing.T) {
|
t.Run("simple", func(t *testing.T) {
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
InstanceExpanderExpander: instances.NewExpander(),
|
InstanceExpanderExpander: instances.NewExpander(),
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ func TestNodeExpandApplyableResourceExecute(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
diags := node.Execute(ctx, walkApply)
|
diags := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %s", diags.Err())
|
t.Fatalf("unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -86,16 +87,16 @@ func (n *NodePlanDeposedResourceInstanceObject) References() []*addrs.Reference
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeEvalable impl.
|
// GraphNodeEvalable impl.
|
||||||
func (n *NodePlanDeposedResourceInstanceObject) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *NodePlanDeposedResourceInstanceObject) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
log.Printf("[TRACE] NodePlanDeposedResourceInstanceObject: planning %s deposed object %s", n.Addr, n.DeposedKey)
|
log.Printf("[TRACE] NodePlanDeposedResourceInstanceObject: planning %s deposed object %s", n.Addr, n.DeposedKey)
|
||||||
|
|
||||||
diags = n.resolveProvider(ctx, false, n.DeposedKey)
|
diags = n.resolveProvider(evalCtx, false, n.DeposedKey)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the state for the deposed resource instance
|
// Read the state for the deposed resource instance
|
||||||
state, err := n.readResourceInstanceStateDeposed(ctx, n.Addr, n.DeposedKey)
|
state, err := n.readResourceInstanceStateDeposed(evalCtx, n.Addr, n.DeposedKey)
|
||||||
diags = diags.Append(err)
|
diags = diags.Append(err)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
@@ -103,13 +104,13 @@ func (n *NodePlanDeposedResourceInstanceObject) Execute(ctx EvalContext, op walk
|
|||||||
|
|
||||||
// Note any upgrades that readResourceInstanceState might've done in the
|
// Note any upgrades that readResourceInstanceState might've done in the
|
||||||
// prevRunState, so that it'll conform to current schema.
|
// prevRunState, so that it'll conform to current schema.
|
||||||
diags = diags.Append(n.writeResourceInstanceStateDeposed(ctx, n.DeposedKey, state, prevRunState))
|
diags = diags.Append(n.writeResourceInstanceStateDeposed(evalCtx, n.DeposedKey, state, prevRunState))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
// Also the refreshState, because that should still reflect schema upgrades
|
// Also the refreshState, because that should still reflect schema upgrades
|
||||||
// even if not refreshing.
|
// even if not refreshing.
|
||||||
diags = diags.Append(n.writeResourceInstanceStateDeposed(ctx, n.DeposedKey, state, refreshState))
|
diags = diags.Append(n.writeResourceInstanceStateDeposed(evalCtx, n.DeposedKey, state, refreshState))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
@@ -127,13 +128,13 @@ func (n *NodePlanDeposedResourceInstanceObject) Execute(ctx EvalContext, op walk
|
|||||||
// resource during Delete correctly. If this is a simple refresh,
|
// resource during Delete correctly. If this is a simple refresh,
|
||||||
// OpenTofu is expected to remove the missing resource from the state
|
// OpenTofu is expected to remove the missing resource from the state
|
||||||
// entirely
|
// entirely
|
||||||
refreshedState, refreshDiags := n.refresh(ctx, n.DeposedKey, state)
|
refreshedState, refreshDiags := n.refresh(evalCtx, n.DeposedKey, state)
|
||||||
diags = diags.Append(refreshDiags)
|
diags = diags.Append(refreshDiags)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
diags = diags.Append(n.writeResourceInstanceStateDeposed(ctx, n.DeposedKey, refreshedState, refreshState))
|
diags = diags.Append(n.writeResourceInstanceStateDeposed(evalCtx, n.DeposedKey, refreshedState, refreshState))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
@@ -159,17 +160,17 @@ func (n *NodePlanDeposedResourceInstanceObject) Execute(ctx EvalContext, op walk
|
|||||||
|
|
||||||
if shouldForget {
|
if shouldForget {
|
||||||
if shouldDestroy {
|
if shouldDestroy {
|
||||||
change, planDiags = n.planDestroy(ctx, state, n.DeposedKey)
|
change, planDiags = n.planDestroy(evalCtx, state, n.DeposedKey)
|
||||||
} else {
|
} else {
|
||||||
diags = diags.Append(&hcl.Diagnostic{
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
Severity: hcl.DiagWarning,
|
Severity: hcl.DiagWarning,
|
||||||
Summary: "Resource going to be removed from the state",
|
Summary: "Resource going to be removed from the state",
|
||||||
Detail: fmt.Sprintf("After this plan gets applied, the resource %s will not be managed anymore by OpenTofu.\n\nIn case you want to manage the resource again, you will have to import it.", n.Addr),
|
Detail: fmt.Sprintf("After this plan gets applied, the resource %s will not be managed anymore by OpenTofu.\n\nIn case you want to manage the resource again, you will have to import it.", n.Addr),
|
||||||
})
|
})
|
||||||
change = n.planForget(ctx, state, n.DeposedKey)
|
change = n.planForget(evalCtx, state, n.DeposedKey)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
change, planDiags = n.planDestroy(ctx, state, n.DeposedKey)
|
change, planDiags = n.planDestroy(evalCtx, state, n.DeposedKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
diags = diags.Append(planDiags)
|
diags = diags.Append(planDiags)
|
||||||
@@ -185,16 +186,16 @@ func (n *NodePlanDeposedResourceInstanceObject) Execute(ctx EvalContext, op walk
|
|||||||
// now just need to get the deposed object destroyed, because there
|
// now just need to get the deposed object destroyed, because there
|
||||||
// should be a new object already serving as its replacement.
|
// should be a new object already serving as its replacement.
|
||||||
|
|
||||||
diags = diags.Append(n.writeChange(ctx, change, n.DeposedKey))
|
diags = diags.Append(n.writeChange(evalCtx, change, n.DeposedKey))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
diags = diags.Append(n.writeResourceInstanceStateDeposed(ctx, n.DeposedKey, nil, workingState))
|
diags = diags.Append(n.writeResourceInstanceStateDeposed(evalCtx, n.DeposedKey, nil, workingState))
|
||||||
} else {
|
} else {
|
||||||
// The working state should at least be updated with the result
|
// The working state should at least be updated with the result
|
||||||
// of upgrading and refreshing from above.
|
// of upgrading and refreshing from above.
|
||||||
diags = diags.Append(n.writeResourceInstanceStateDeposed(ctx, n.DeposedKey, state, workingState))
|
diags = diags.Append(n.writeResourceInstanceStateDeposed(evalCtx, n.DeposedKey, state, workingState))
|
||||||
}
|
}
|
||||||
|
|
||||||
return diags
|
return diags
|
||||||
@@ -267,16 +268,16 @@ func (n *NodeDestroyDeposedResourceInstanceObject) ModifyCreateBeforeDestroy(v b
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable impl.
|
// GraphNodeExecutable impl.
|
||||||
func (n *NodeDestroyDeposedResourceInstanceObject) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *NodeDestroyDeposedResourceInstanceObject) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
var change *plans.ResourceInstanceChange
|
var change *plans.ResourceInstanceChange
|
||||||
|
|
||||||
diags = n.resolveProvider(ctx, false, n.DeposedKey)
|
diags = n.resolveProvider(evalCtx, false, n.DeposedKey)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the state for the deposed resource instance
|
// Read the state for the deposed resource instance
|
||||||
state, err := n.readResourceInstanceStateDeposed(ctx, n.Addr, n.DeposedKey)
|
state, err := n.readResourceInstanceStateDeposed(evalCtx, n.Addr, n.DeposedKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diags.Append(err)
|
return diags.Append(err)
|
||||||
}
|
}
|
||||||
@@ -286,35 +287,35 @@ func (n *NodeDestroyDeposedResourceInstanceObject) Execute(ctx EvalContext, op w
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
change, destroyPlanDiags := n.planDestroy(ctx, state, n.DeposedKey)
|
change, destroyPlanDiags := n.planDestroy(evalCtx, state, n.DeposedKey)
|
||||||
diags = diags.Append(destroyPlanDiags)
|
diags = diags.Append(destroyPlanDiags)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call pre-apply hook
|
// Call pre-apply hook
|
||||||
diags = diags.Append(n.preApplyHook(ctx, change))
|
diags = diags.Append(n.preApplyHook(evalCtx, change))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
// we pass a nil configuration to apply because we are destroying
|
// we pass a nil configuration to apply because we are destroying
|
||||||
state, applyDiags := n.apply(ctx, state, change, nil, instances.RepetitionData{}, false)
|
state, applyDiags := n.apply(evalCtx, state, change, nil, instances.RepetitionData{}, false)
|
||||||
diags = diags.Append(applyDiags)
|
diags = diags.Append(applyDiags)
|
||||||
// don't return immediately on errors, we need to handle the state
|
// don't return immediately on errors, we need to handle the state
|
||||||
|
|
||||||
// Always write the resource back to the state deposed. If it
|
// Always write the resource back to the state deposed. If it
|
||||||
// was successfully destroyed it will be pruned. If it was not, it will
|
// was successfully destroyed it will be pruned. If it was not, it will
|
||||||
// be caught on the next run.
|
// be caught on the next run.
|
||||||
writeDiags := n.writeResourceInstanceState(ctx, state)
|
writeDiags := n.writeResourceInstanceState(evalCtx, state)
|
||||||
diags.Append(writeDiags)
|
diags.Append(writeDiags)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
diags = diags.Append(n.postApplyHook(ctx, state, diags.Err()))
|
diags = diags.Append(n.postApplyHook(evalCtx, state, diags.Err()))
|
||||||
|
|
||||||
return diags.Append(updateStateHook(ctx))
|
return diags.Append(updateStateHook(evalCtx))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeDeposer is an optional interface implemented by graph nodes that
|
// GraphNodeDeposer is an optional interface implemented by graph nodes that
|
||||||
@@ -421,14 +422,14 @@ func (n *NodeForgetDeposedResourceInstanceObject) References() []*addrs.Referenc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable impl.
|
// GraphNodeExecutable impl.
|
||||||
func (n *NodeForgetDeposedResourceInstanceObject) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *NodeForgetDeposedResourceInstanceObject) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
diags = n.resolveProvider(ctx, false, n.DeposedKey)
|
diags = n.resolveProvider(evalCtx, false, n.DeposedKey)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the state for the deposed resource instance
|
// Read the state for the deposed resource instance
|
||||||
state, err := n.readResourceInstanceStateDeposed(ctx, n.Addr, n.DeposedKey)
|
state, err := n.readResourceInstanceStateDeposed(evalCtx, n.Addr, n.DeposedKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diags.Append(err)
|
return diags.Append(err)
|
||||||
}
|
}
|
||||||
@@ -437,8 +438,8 @@ func (n *NodeForgetDeposedResourceInstanceObject) Execute(ctx EvalContext, op wa
|
|||||||
log.Printf("[WARN] NodeForgetDeposedResourceInstanceObject for %s (%s) with no state", n.Addr, n.DeposedKey)
|
log.Printf("[WARN] NodeForgetDeposedResourceInstanceObject for %s (%s) with no state", n.Addr, n.DeposedKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
contextState := ctx.State()
|
contextState := evalCtx.State()
|
||||||
contextState.ForgetResourceInstanceDeposed(n.Addr, n.DeposedKey)
|
contextState.ForgetResourceInstanceDeposed(n.Addr, n.DeposedKey)
|
||||||
|
|
||||||
return diags.Append(updateStateHook(ctx))
|
return diags.Append(updateStateHook(evalCtx))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ func TestNodePlanDeposedResourceInstanceObject_Execute(t *testing.T) {
|
|||||||
deposedKey := states.NewDeposedKey()
|
deposedKey := states.NewDeposedKey()
|
||||||
absResource := mustResourceInstanceAddr(test.nodeAddress)
|
absResource := mustResourceInstanceAddr(test.nodeAddress)
|
||||||
|
|
||||||
ctx, p := initMockEvalContext(test.nodeAddress, deposedKey)
|
evalCtx, p := initMockEvalContext(test.nodeAddress, deposedKey)
|
||||||
|
|
||||||
node := NodePlanDeposedResourceInstanceObject{
|
node := NodePlanDeposedResourceInstanceObject{
|
||||||
NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
|
NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
|
||||||
@@ -208,7 +208,7 @@ func TestNodePlanDeposedResourceInstanceObject_Execute(t *testing.T) {
|
|||||||
RemoveStatements: test.nodeEndpointsToRemove,
|
RemoveStatements: test.nodeEndpointsToRemove,
|
||||||
}
|
}
|
||||||
|
|
||||||
gotDiags := node.Execute(ctx, walkPlan)
|
gotDiags := node.Execute(t.Context(), evalCtx, walkPlan)
|
||||||
assertDiags(t, gotDiags, test.wantDiags)
|
assertDiags(t, gotDiags, test.wantDiags)
|
||||||
|
|
||||||
if !p.UpgradeResourceStateCalled {
|
if !p.UpgradeResourceStateCalled {
|
||||||
@@ -218,7 +218,7 @@ func TestNodePlanDeposedResourceInstanceObject_Execute(t *testing.T) {
|
|||||||
t.Errorf("ReadResource wasn't called; should've been called to refresh the deposed object")
|
t.Errorf("ReadResource wasn't called; should've been called to refresh the deposed object")
|
||||||
}
|
}
|
||||||
|
|
||||||
change := ctx.Changes().GetResourceInstanceChange(absResource, deposedKey)
|
change := evalCtx.Changes().GetResourceInstanceChange(absResource, deposedKey)
|
||||||
if got, want := change.ChangeSrc.Action, test.wantAction; got != want {
|
if got, want := change.ChangeSrc.Action, test.wantAction; got != want {
|
||||||
t.Fatalf("wrong planned action\ngot: %s\nwant: %s", got, want)
|
t.Fatalf("wrong planned action\ngot: %s\nwant: %s", got, want)
|
||||||
}
|
}
|
||||||
@@ -230,7 +230,7 @@ func TestNodeDestroyDeposedResourceInstanceObject_Execute(t *testing.T) {
|
|||||||
deposedKey := states.NewDeposedKey()
|
deposedKey := states.NewDeposedKey()
|
||||||
state := states.NewState()
|
state := states.NewState()
|
||||||
absResourceAddr := "test_instance.foo"
|
absResourceAddr := "test_instance.foo"
|
||||||
ctx, _ := initMockEvalContext(absResourceAddr, deposedKey)
|
evalCtx, _ := initMockEvalContext(absResourceAddr, deposedKey)
|
||||||
|
|
||||||
absResource := mustResourceInstanceAddr(absResourceAddr)
|
absResource := mustResourceInstanceAddr(absResourceAddr)
|
||||||
node := NodeDestroyDeposedResourceInstanceObject{
|
node := NodeDestroyDeposedResourceInstanceObject{
|
||||||
@@ -242,7 +242,7 @@ func TestNodeDestroyDeposedResourceInstanceObject_Execute(t *testing.T) {
|
|||||||
},
|
},
|
||||||
DeposedKey: deposedKey,
|
DeposedKey: deposedKey,
|
||||||
}
|
}
|
||||||
err := node.Execute(ctx, walkApply)
|
err := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
@@ -299,7 +299,7 @@ aws_instance.foo: (1 deposed)
|
|||||||
|
|
||||||
func TestNodeDestroyDeposedResourceInstanceObject_ExecuteMissingState(t *testing.T) {
|
func TestNodeDestroyDeposedResourceInstanceObject_ExecuteMissingState(t *testing.T) {
|
||||||
p := simpleMockProvider()
|
p := simpleMockProvider()
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: states.NewState().SyncWrapper(),
|
StateState: states.NewState().SyncWrapper(),
|
||||||
ProviderProvider: simpleMockProvider(),
|
ProviderProvider: simpleMockProvider(),
|
||||||
ProviderSchemaSchema: p.GetProviderSchema(),
|
ProviderSchemaSchema: p.GetProviderSchema(),
|
||||||
@@ -315,7 +315,7 @@ func TestNodeDestroyDeposedResourceInstanceObject_ExecuteMissingState(t *testing
|
|||||||
},
|
},
|
||||||
DeposedKey: states.NewDeposedKey(),
|
DeposedKey: states.NewDeposedKey(),
|
||||||
}
|
}
|
||||||
err := node.Execute(ctx, walkApply)
|
err := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error")
|
t.Fatal("expected error")
|
||||||
@@ -326,7 +326,7 @@ func TestNodeForgetDeposedResourceInstanceObject_Execute(t *testing.T) {
|
|||||||
deposedKey := states.NewDeposedKey()
|
deposedKey := states.NewDeposedKey()
|
||||||
state := states.NewState()
|
state := states.NewState()
|
||||||
absResourceAddr := "test_instance.foo"
|
absResourceAddr := "test_instance.foo"
|
||||||
ctx, _ := initMockEvalContext(absResourceAddr, deposedKey)
|
evalCtx, _ := initMockEvalContext(absResourceAddr, deposedKey)
|
||||||
|
|
||||||
absResource := mustResourceInstanceAddr(absResourceAddr)
|
absResource := mustResourceInstanceAddr(absResourceAddr)
|
||||||
node := NodeForgetDeposedResourceInstanceObject{
|
node := NodeForgetDeposedResourceInstanceObject{
|
||||||
@@ -338,7 +338,7 @@ func TestNodeForgetDeposedResourceInstanceObject_Execute(t *testing.T) {
|
|||||||
},
|
},
|
||||||
DeposedKey: deposedKey,
|
DeposedKey: deposedKey,
|
||||||
}
|
}
|
||||||
err := node.Execute(ctx, walkApply)
|
err := node.Execute(t.Context(), evalCtx, walkApply)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -137,19 +138,19 @@ func (n *NodeDestroyResourceInstance) References() []*addrs.Reference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *NodeDestroyResourceInstance) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *NodeDestroyResourceInstance) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
addr := n.ResourceInstanceAddr()
|
addr := n.ResourceInstanceAddr()
|
||||||
|
|
||||||
// Eval info is different depending on what kind of resource this is
|
// Eval info is different depending on what kind of resource this is
|
||||||
switch addr.Resource.Resource.Mode {
|
switch addr.Resource.Resource.Mode {
|
||||||
case addrs.ManagedResourceMode:
|
case addrs.ManagedResourceMode:
|
||||||
diags = n.resolveProvider(ctx, false, states.NotDeposed)
|
diags = n.resolveProvider(evalCtx, false, states.NotDeposed)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
return n.managedResourceExecute(ctx)
|
return n.managedResourceExecute(evalCtx)
|
||||||
case addrs.DataResourceMode:
|
case addrs.DataResourceMode:
|
||||||
return n.dataResourceExecute(ctx)
|
return n.dataResourceExecute(evalCtx)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
|
panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@ func (n *NodeForgetResourceInstance) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *NodeForgetResourceInstance) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *NodeForgetResourceInstance) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
addr := n.ResourceInstanceAddr()
|
addr := n.ResourceInstanceAddr()
|
||||||
|
|
||||||
// Get our state
|
// Get our state
|
||||||
@@ -53,14 +54,14 @@ func (n *NodeForgetResourceInstance) Execute(ctx EvalContext, op walkOperation)
|
|||||||
log.Printf("[WARN] NodeForgetResourceInstance for %s with no state", addr)
|
log.Printf("[WARN] NodeForgetResourceInstance for %s with no state", addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
diags = n.resolveProvider(ctx, false, states.NotDeposed)
|
diags = n.resolveProvider(evalCtx, false, states.NotDeposed)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
var state *states.ResourceInstanceObject
|
var state *states.ResourceInstanceObject
|
||||||
|
|
||||||
state, readDiags := n.readResourceInstanceState(ctx, addr)
|
state, readDiags := n.readResourceInstanceState(evalCtx, addr)
|
||||||
diags = diags.Append(readDiags)
|
diags = diags.Append(readDiags)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
@@ -71,10 +72,10 @@ func (n *NodeForgetResourceInstance) Execute(ctx EvalContext, op walkOperation)
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
contextState := ctx.State()
|
contextState := evalCtx.State()
|
||||||
contextState.ForgetResourceInstanceAll(n.Addr)
|
contextState.ForgetResourceInstanceAll(n.Addr)
|
||||||
|
|
||||||
diags = diags.Append(updateStateHook(ctx))
|
diags = diags.Append(updateStateHook(evalCtx))
|
||||||
|
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ func (n *graphNodeImportState) ModulePath() addrs.Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable impl.
|
// GraphNodeExecutable impl.
|
||||||
func (n *graphNodeImportState) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *graphNodeImportState) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
// Reset our states
|
// Reset our states
|
||||||
n.states = nil
|
n.states = nil
|
||||||
|
|
||||||
@@ -92,24 +93,24 @@ func (n *graphNodeImportState) Execute(ctx EvalContext, op walkOperation) (diags
|
|||||||
ResolvedProvider: n.ResolvedProvider,
|
ResolvedProvider: n.ResolvedProvider,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
diags = diags.Append(asAbsNode.resolveProvider(ctx, true, states.NotDeposed))
|
diags = diags.Append(asAbsNode.resolveProvider(evalCtx, true, states.NotDeposed))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
n.ResolvedProviderKey = asAbsNode.ResolvedProviderKey
|
n.ResolvedProviderKey = asAbsNode.ResolvedProviderKey
|
||||||
log.Printf("[TRACE] graphNodeImportState: importing using %s", n.ResolvedProvider.ProviderConfig.InstanceString(n.ResolvedProviderKey))
|
log.Printf("[TRACE] graphNodeImportState: importing using %s", n.ResolvedProvider.ProviderConfig.InstanceString(n.ResolvedProviderKey))
|
||||||
|
|
||||||
provider, _, err := getProvider(ctx, n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)
|
provider, _, err := getProvider(evalCtx, n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)
|
||||||
diags = diags.Append(err)
|
diags = diags.Append(err)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
// import state
|
// import state
|
||||||
absAddr := n.Addr.Resource.Absolute(ctx.Path())
|
absAddr := n.Addr.Resource.Absolute(evalCtx.Path())
|
||||||
|
|
||||||
// Call pre-import hook
|
// Call pre-import hook
|
||||||
diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) {
|
diags = diags.Append(evalCtx.Hook(func(h Hook) (HookAction, error) {
|
||||||
return h.PreImportState(absAddr, n.ID)
|
return h.PreImportState(absAddr, n.ID)
|
||||||
}))
|
}))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
@@ -132,7 +133,7 @@ func (n *graphNodeImportState) Execute(ctx EvalContext, op walkOperation) (diags
|
|||||||
n.states = imported
|
n.states = imported
|
||||||
|
|
||||||
// Call post-import hook
|
// Call post-import hook
|
||||||
diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) {
|
diags = diags.Append(evalCtx.Hook(func(h Hook) (HookAction, error) {
|
||||||
return h.PostImportState(absAddr, imported)
|
return h.PostImportState(absAddr, imported)
|
||||||
}))
|
}))
|
||||||
return diags
|
return diags
|
||||||
@@ -243,7 +244,7 @@ func (n *graphNodeImportStateSub) Path() addrs.ModuleInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable impl.
|
// GraphNodeExecutable impl.
|
||||||
func (n *graphNodeImportStateSub) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *graphNodeImportStateSub) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
// If the Ephemeral type isn't set, then it is an error
|
// If the Ephemeral type isn't set, then it is an error
|
||||||
if n.State.TypeName == "" {
|
if n.State.TypeName == "" {
|
||||||
diags = diags.Append(fmt.Errorf("import of %s didn't set type", n.TargetAddr.String()))
|
diags = diags.Append(fmt.Errorf("import of %s didn't set type", n.TargetAddr.String()))
|
||||||
@@ -260,7 +261,7 @@ func (n *graphNodeImportStateSub) Execute(ctx EvalContext, op walkOperation) (di
|
|||||||
},
|
},
|
||||||
ResolvedProviderKey: n.ResolvedProviderKey,
|
ResolvedProviderKey: n.ResolvedProviderKey,
|
||||||
}
|
}
|
||||||
state, refreshDiags := riNode.refresh(ctx, states.NotDeposed, state)
|
state, refreshDiags := riNode.refresh(evalCtx, states.NotDeposed, state)
|
||||||
diags = diags.Append(refreshDiags)
|
diags = diags.Append(refreshDiags)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
@@ -288,7 +289,7 @@ func (n *graphNodeImportStateSub) Execute(ctx EvalContext, op walkOperation) (di
|
|||||||
// Insert marks from configuration
|
// Insert marks from configuration
|
||||||
if n.Config != nil {
|
if n.Config != nil {
|
||||||
// Since the import command allow import resource with incomplete configuration, we ignore diagnostics here
|
// Since the import command allow import resource with incomplete configuration, we ignore diagnostics here
|
||||||
valueWithConfigurationSchemaMarks, _, _ := ctx.EvaluateBlock(n.Config.Config, n.Schema, nil, EvalDataForNoInstanceKey)
|
valueWithConfigurationSchemaMarks, _, _ := evalCtx.EvaluateBlock(n.Config.Config, n.Schema, nil, EvalDataForNoInstanceKey)
|
||||||
|
|
||||||
_, stateValueMarks := state.Value.UnmarkDeepWithPaths()
|
_, stateValueMarks := state.Value.UnmarkDeepWithPaths()
|
||||||
_, valueWithConfigurationSchemaMarksPaths := valueWithConfigurationSchemaMarks.UnmarkDeepWithPaths()
|
_, valueWithConfigurationSchemaMarksPaths := valueWithConfigurationSchemaMarks.UnmarkDeepWithPaths()
|
||||||
@@ -296,6 +297,6 @@ func (n *graphNodeImportStateSub) Execute(ctx EvalContext, op walkOperation) (di
|
|||||||
state.Value = state.Value.MarkWithPaths(combined)
|
state.Value = state.Value.MarkWithPaths(combined)
|
||||||
}
|
}
|
||||||
|
|
||||||
diags = diags.Append(riNode.writeResourceInstanceState(ctx, state, workingState))
|
diags = diags.Append(riNode.writeResourceInstanceState(evalCtx, state, workingState))
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
@@ -44,19 +45,19 @@ func (n *NodePlanDestroyableResourceInstance) DestroyAddr() *addrs.AbsResourceIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeEvalable
|
// GraphNodeEvalable
|
||||||
func (n *NodePlanDestroyableResourceInstance) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *NodePlanDestroyableResourceInstance) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
addr := n.ResourceInstanceAddr()
|
addr := n.ResourceInstanceAddr()
|
||||||
|
|
||||||
diags = diags.Append(n.resolveProvider(ctx, false, states.NotDeposed))
|
diags = diags.Append(n.resolveProvider(evalCtx, false, states.NotDeposed))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
switch addr.Resource.Resource.Mode {
|
switch addr.Resource.Resource.Mode {
|
||||||
case addrs.ManagedResourceMode:
|
case addrs.ManagedResourceMode:
|
||||||
return n.managedResourceExecute(ctx, op)
|
return n.managedResourceExecute(evalCtx, op)
|
||||||
case addrs.DataResourceMode:
|
case addrs.DataResourceMode:
|
||||||
return n.dataResourceExecute(ctx, op)
|
return n.dataResourceExecute(evalCtx, op)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
|
panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -83,10 +84,10 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// GraphNodeEvalable
|
// GraphNodeEvalable
|
||||||
func (n *NodePlannableResourceInstance) Execute(ctx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
func (n *NodePlannableResourceInstance) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
||||||
addr := n.ResourceInstanceAddr()
|
addr := n.ResourceInstanceAddr()
|
||||||
|
|
||||||
diags := n.resolveProvider(ctx, true, states.NotDeposed)
|
diags := n.resolveProvider(evalCtx, true, states.NotDeposed)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
@@ -94,9 +95,9 @@ func (n *NodePlannableResourceInstance) Execute(ctx EvalContext, op walkOperatio
|
|||||||
// Eval info is different depending on what kind of resource this is
|
// Eval info is different depending on what kind of resource this is
|
||||||
switch addr.Resource.Resource.Mode {
|
switch addr.Resource.Resource.Mode {
|
||||||
case addrs.ManagedResourceMode:
|
case addrs.ManagedResourceMode:
|
||||||
return n.managedResourceExecute(ctx)
|
return n.managedResourceExecute(evalCtx)
|
||||||
case addrs.DataResourceMode:
|
case addrs.DataResourceMode:
|
||||||
return n.dataResourceExecute(ctx)
|
return n.dataResourceExecute(evalCtx)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
|
panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -53,19 +54,19 @@ func (n *NodePlannableResourceInstanceOrphan) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *NodePlannableResourceInstanceOrphan) Execute(ctx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
func (n *NodePlannableResourceInstanceOrphan) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
||||||
addr := n.ResourceInstanceAddr()
|
addr := n.ResourceInstanceAddr()
|
||||||
|
|
||||||
// Eval info is different depending on what kind of resource this is
|
// Eval info is different depending on what kind of resource this is
|
||||||
switch addr.Resource.Resource.Mode {
|
switch addr.Resource.Resource.Mode {
|
||||||
case addrs.ManagedResourceMode:
|
case addrs.ManagedResourceMode:
|
||||||
diags := n.resolveProvider(ctx, true, states.NotDeposed)
|
diags := n.resolveProvider(evalCtx, true, states.NotDeposed)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
return n.managedResourceExecute(ctx)
|
return n.managedResourceExecute(evalCtx)
|
||||||
case addrs.DataResourceMode:
|
case addrs.DataResourceMode:
|
||||||
return n.dataResourceExecute(ctx)
|
return n.dataResourceExecute(evalCtx)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
|
panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ func TestNodeResourcePlanOrphan_Execute(t *testing.T) {
|
|||||||
p.ConfigureProvider(providers.ConfigureProviderRequest{})
|
p.ConfigureProvider(providers.ConfigureProviderRequest{})
|
||||||
p.GetProviderSchemaResponse = &schema
|
p.GetProviderSchemaResponse = &schema
|
||||||
|
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
RefreshStateState: state.DeepCopy().SyncWrapper(),
|
RefreshStateState: state.DeepCopy().SyncWrapper(),
|
||||||
PrevRunStateState: state.DeepCopy().SyncWrapper(),
|
PrevRunStateState: state.DeepCopy().SyncWrapper(),
|
||||||
@@ -241,10 +241,10 @@ func TestNodeResourcePlanOrphan_Execute(t *testing.T) {
|
|||||||
RemoveStatements: test.nodeEndpointsToRemove,
|
RemoveStatements: test.nodeEndpointsToRemove,
|
||||||
}
|
}
|
||||||
|
|
||||||
gotDiags := node.Execute(ctx, walkPlan)
|
gotDiags := node.Execute(t.Context(), evalCtx, walkPlan)
|
||||||
assertDiags(t, gotDiags, test.wantDiags)
|
assertDiags(t, gotDiags, test.wantDiags)
|
||||||
|
|
||||||
change := ctx.Changes().GetResourceInstanceChange(absResource, states.NotDeposed)
|
change := evalCtx.Changes().GetResourceInstanceChange(absResource, states.NotDeposed)
|
||||||
if got, want := change.ChangeSrc.Action, test.wantAction; got != want {
|
if got, want := change.ChangeSrc.Action, test.wantAction; got != want {
|
||||||
t.Fatalf("wrong planned action\ngot: %s\nwant: %s", got, want)
|
t.Fatalf("wrong planned action\ngot: %s\nwant: %s", got, want)
|
||||||
}
|
}
|
||||||
@@ -287,7 +287,7 @@ func TestNodeResourcePlanOrphanExecute_alreadyDeleted(t *testing.T) {
|
|||||||
p.ReadResourceResponse = &providers.ReadResourceResponse{
|
p.ReadResourceResponse = &providers.ReadResourceResponse{
|
||||||
NewState: cty.NullVal(p.GetProviderSchemaResponse.ResourceTypes["test_string"].Block.ImpliedType()),
|
NewState: cty.NullVal(p.GetProviderSchemaResponse.ResourceTypes["test_string"].Block.ImpliedType()),
|
||||||
}
|
}
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
RefreshStateState: refreshState.SyncWrapper(),
|
RefreshStateState: refreshState.SyncWrapper(),
|
||||||
PrevRunStateState: prevRunState.SyncWrapper(),
|
PrevRunStateState: prevRunState.SyncWrapper(),
|
||||||
@@ -314,7 +314,7 @@ func TestNodeResourcePlanOrphanExecute_alreadyDeleted(t *testing.T) {
|
|||||||
Addr: mustResourceInstanceAddr("test_object.foo"),
|
Addr: mustResourceInstanceAddr("test_object.foo"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
diags := node.Execute(ctx, walkPlan)
|
diags := node.Execute(t.Context(), evalCtx, walkPlan)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %s", diags.Err())
|
t.Fatalf("unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
@@ -370,7 +370,7 @@ func TestNodeResourcePlanOrphanExecute_deposed(t *testing.T) {
|
|||||||
p.ReadResourceResponse = &providers.ReadResourceResponse{
|
p.ReadResourceResponse = &providers.ReadResourceResponse{
|
||||||
NewState: cty.NullVal(p.GetProviderSchemaResponse.ResourceTypes["test_string"].Block.ImpliedType()),
|
NewState: cty.NullVal(p.GetProviderSchemaResponse.ResourceTypes["test_string"].Block.ImpliedType()),
|
||||||
}
|
}
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
RefreshStateState: refreshState.SyncWrapper(),
|
RefreshStateState: refreshState.SyncWrapper(),
|
||||||
PrevRunStateState: prevRunState.SyncWrapper(),
|
PrevRunStateState: prevRunState.SyncWrapper(),
|
||||||
@@ -397,7 +397,7 @@ func TestNodeResourcePlanOrphanExecute_deposed(t *testing.T) {
|
|||||||
Addr: mustResourceInstanceAddr("test_object.foo"),
|
Addr: mustResourceInstanceAddr("test_object.foo"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
diags := node.Execute(ctx, walkPlan)
|
diags := node.Execute(t.Context(), evalCtx, walkPlan)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %s", diags.Err())
|
t.Fatalf("unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -46,14 +47,14 @@ func (n *NodeValidatableResource) Path() addrs.ModuleInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeEvalable
|
// GraphNodeEvalable
|
||||||
func (n *NodeValidatableResource) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *NodeValidatableResource) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
if n.Config == nil {
|
if n.Config == nil {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
diags = diags.Append(n.validateResource(ctx))
|
diags = diags.Append(n.validateResource(evalCtx))
|
||||||
|
|
||||||
diags = diags.Append(n.validateCheckRules(ctx, n.Config))
|
diags = diags.Append(n.validateCheckRules(evalCtx, n.Config))
|
||||||
|
|
||||||
if managed := n.Config.Managed; managed != nil {
|
if managed := n.Config.Managed; managed != nil {
|
||||||
// Validate all the provisioners
|
// Validate all the provisioners
|
||||||
@@ -74,7 +75,7 @@ func (n *NodeValidatableResource) Execute(ctx EvalContext, op walkOperation) (di
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate Provisioner Config
|
// Validate Provisioner Config
|
||||||
diags = diags.Append(n.validateProvisioner(ctx, &provisioner))
|
diags = diags.Append(n.validateProvisioner(evalCtx, &provisioner))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
@@ -54,7 +55,7 @@ func (n *NodeRootVariable) ReferenceableAddrs() []addrs.Referenceable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *NodeRootVariable) Execute(ctx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
func (n *NodeRootVariable) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
||||||
// Root module variables are special in that they are provided directly
|
// Root module variables are special in that they are provided directly
|
||||||
// by the caller (usually, the CLI layer) and so we don't really need to
|
// by the caller (usually, the CLI layer) and so we don't really need to
|
||||||
// evaluate them in the usual sense, but we do need to process the raw
|
// evaluate them in the usual sense, but we do need to process the raw
|
||||||
@@ -98,7 +99,7 @@ func (n *NodeRootVariable) Execute(ctx EvalContext, op walkOperation) tfdiags.Di
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.SetRootModuleArgument(addr.Variable, finalVal)
|
evalCtx.SetRootModuleArgument(addr.Variable, finalVal)
|
||||||
|
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import (
|
|||||||
|
|
||||||
func TestNodeRootVariableExecute(t *testing.T) {
|
func TestNodeRootVariableExecute(t *testing.T) {
|
||||||
t.Run("type conversion", func(t *testing.T) {
|
t.Run("type conversion", func(t *testing.T) {
|
||||||
ctx := new(MockEvalContext)
|
evalCtx := new(MockEvalContext)
|
||||||
|
|
||||||
n := &NodeRootVariable{
|
n := &NodeRootVariable{
|
||||||
Addr: addrs.InputVariable{Name: "foo"},
|
Addr: addrs.InputVariable{Name: "foo"},
|
||||||
@@ -35,7 +35,7 @@ func TestNodeRootVariableExecute(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.ChecksState = checks.NewState(&configs.Config{
|
evalCtx.ChecksState = checks.NewState(&configs.Config{
|
||||||
Module: &configs.Module{
|
Module: &configs.Module{
|
||||||
Variables: map[string]*configs.Variable{
|
Variables: map[string]*configs.Variable{
|
||||||
"foo": n.Config,
|
"foo": n.Config,
|
||||||
@@ -43,18 +43,18 @@ func TestNodeRootVariableExecute(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
diags := n.Execute(ctx, walkApply)
|
diags := n.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %s", diags.Err())
|
t.Fatalf("unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.SetRootModuleArgumentCalled {
|
if !evalCtx.SetRootModuleArgumentCalled {
|
||||||
t.Fatalf("ctx.SetRootModuleArgument wasn't called")
|
t.Fatalf("ctx.SetRootModuleArgument wasn't called")
|
||||||
}
|
}
|
||||||
if got, want := ctx.SetRootModuleArgumentAddr.String(), "var.foo"; got != want {
|
if got, want := evalCtx.SetRootModuleArgumentAddr.String(), "var.foo"; got != want {
|
||||||
t.Errorf("wrong address for ctx.SetRootModuleArgument\ngot: %s\nwant: %s", got, want)
|
t.Errorf("wrong address for ctx.SetRootModuleArgument\ngot: %s\nwant: %s", got, want)
|
||||||
}
|
}
|
||||||
if got, want := ctx.SetRootModuleArgumentValue, cty.StringVal("true"); !want.RawEquals(got) {
|
if got, want := evalCtx.SetRootModuleArgumentValue, cty.StringVal("true"); !want.RawEquals(got) {
|
||||||
// NOTE: The given value was cty.Bool but the type constraint was
|
// NOTE: The given value was cty.Bool but the type constraint was
|
||||||
// cty.String, so it was NodeRootVariable's responsibility to convert
|
// cty.String, so it was NodeRootVariable's responsibility to convert
|
||||||
// as part of preparing the "final value".
|
// as part of preparing the "final value".
|
||||||
@@ -62,25 +62,25 @@ func TestNodeRootVariableExecute(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("validation", func(t *testing.T) {
|
t.Run("validation", func(t *testing.T) {
|
||||||
ctx := new(MockEvalContext)
|
evalCtx := new(MockEvalContext)
|
||||||
|
|
||||||
// The variable validation function gets called with OpenTofu's
|
// The variable validation function gets called with OpenTofu's
|
||||||
// built-in functions available, so we need a minimal scope just for
|
// built-in functions available, so we need a minimal scope just for
|
||||||
// it to get the functions from.
|
// it to get the functions from.
|
||||||
ctx.EvaluationScopeScope = &lang.Scope{}
|
evalCtx.EvaluationScopeScope = &lang.Scope{}
|
||||||
|
|
||||||
// We need to reimplement a _little_ bit of EvalContextBuiltin logic
|
// We need to reimplement a _little_ bit of EvalContextBuiltin logic
|
||||||
// here to get a similar effect with EvalContextMock just to get the
|
// here to get a similar effect with EvalContextMock just to get the
|
||||||
// value to flow through here in a realistic way that'll make this test
|
// value to flow through here in a realistic way that'll make this test
|
||||||
// useful.
|
// useful.
|
||||||
var finalVal cty.Value
|
var finalVal cty.Value
|
||||||
ctx.SetRootModuleArgumentFunc = func(addr addrs.InputVariable, v cty.Value) {
|
evalCtx.SetRootModuleArgumentFunc = func(addr addrs.InputVariable, v cty.Value) {
|
||||||
if addr.Name == "foo" {
|
if addr.Name == "foo" {
|
||||||
t.Logf("set %s to %#v", addr.String(), v)
|
t.Logf("set %s to %#v", addr.String(), v)
|
||||||
finalVal = v
|
finalVal = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.GetVariableValueFunc = func(addr addrs.AbsInputVariableInstance) cty.Value {
|
evalCtx.GetVariableValueFunc = func(addr addrs.AbsInputVariableInstance) cty.Value {
|
||||||
if addr.String() != "var.foo" {
|
if addr.String() != "var.foo" {
|
||||||
return cty.NilVal
|
return cty.NilVal
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ func TestNodeRootVariableExecute(t *testing.T) {
|
|||||||
Config: n.Config,
|
Config: n.Config,
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.ChecksState = checks.NewState(&configs.Config{
|
evalCtx.ChecksState = checks.NewState(&configs.Config{
|
||||||
Module: &configs.Module{
|
Module: &configs.Module{
|
||||||
Variables: map[string]*configs.Variable{
|
Variables: map[string]*configs.Variable{
|
||||||
"foo": n.Config,
|
"foo": n.Config,
|
||||||
@@ -141,38 +141,38 @@ func TestNodeRootVariableExecute(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
diags := n.Execute(ctx, walkApply)
|
diags := n.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %s", diags.Err())
|
t.Fatalf("unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
|
|
||||||
g, err := ref.DynamicExpand(ctx)
|
g, err := ref.DynamicExpand(evalCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range g.Vertices() {
|
for _, v := range g.Vertices() {
|
||||||
if ev, ok := v.(GraphNodeExecutable); ok {
|
if ev, ok := v.(GraphNodeExecutable); ok {
|
||||||
diags = ev.Execute(ctx, walkApply)
|
diags = ev.Execute(t.Context(), evalCtx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %s", diags.Err())
|
t.Fatalf("unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.SetRootModuleArgumentCalled {
|
if !evalCtx.SetRootModuleArgumentCalled {
|
||||||
t.Fatalf("ctx.SetRootModuleArgument wasn't called")
|
t.Fatalf("ctx.SetRootModuleArgument wasn't called")
|
||||||
}
|
}
|
||||||
if got, want := ctx.SetRootModuleArgumentAddr.String(), "var.foo"; got != want {
|
if got, want := evalCtx.SetRootModuleArgumentAddr.String(), "var.foo"; got != want {
|
||||||
t.Errorf("wrong address for ctx.SetRootModuleArgument\ngot: %s\nwant: %s", got, want)
|
t.Errorf("wrong address for ctx.SetRootModuleArgument\ngot: %s\nwant: %s", got, want)
|
||||||
}
|
}
|
||||||
if got, want := ctx.SetRootModuleArgumentValue, cty.NumberIntVal(5); !want.RawEquals(got) {
|
if got, want := evalCtx.SetRootModuleArgumentValue, cty.NumberIntVal(5); !want.RawEquals(got) {
|
||||||
// NOTE: The given value was cty.Bool but the type constraint was
|
// NOTE: The given value was cty.Bool but the type constraint was
|
||||||
// cty.String, so it was NodeRootVariable's responsibility to convert
|
// cty.String, so it was NodeRootVariable's responsibility to convert
|
||||||
// as part of preparing the "final value".
|
// as part of preparing the "final value".
|
||||||
t.Errorf("wrong value for ctx.SetRootModuleArgument\ngot: %#v\nwant: %#v", got, want)
|
t.Errorf("wrong value for ctx.SetRootModuleArgument\ngot: %#v\nwant: %#v", got, want)
|
||||||
}
|
}
|
||||||
if status := ctx.Checks().ObjectCheckStatus(n.Addr.Absolute(addrs.RootModuleInstance)); status != checks.StatusPass {
|
if status := evalCtx.Checks().ObjectCheckStatus(n.Addr.Absolute(addrs.RootModuleInstance)); status != checks.StatusPass {
|
||||||
t.Errorf("expected checks to pass but go %s instead", status)
|
t.Errorf("expected checks to pass but go %s instead", status)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -143,10 +144,10 @@ func (n *nodeVariableReferenceInstance) ModulePath() addrs.Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable
|
// GraphNodeExecutable
|
||||||
func (n *nodeVariableReferenceInstance) Execute(ctx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
func (n *nodeVariableReferenceInstance) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
||||||
log.Printf("[TRACE] nodeVariableReferenceInstance: evaluating %s", n.Addr)
|
log.Printf("[TRACE] nodeVariableReferenceInstance: evaluating %s", n.Addr)
|
||||||
diags := evalVariableValidations(n.Addr, n.Config, n.Expr, ctx)
|
diags := evalVariableValidations(n.Addr, n.Config, n.Expr, evalCtx)
|
||||||
diags = diags.Append(evalVariableDeprecation(n.Addr, n.Config, n.Expr, ctx))
|
diags = diags.Append(evalVariableDeprecation(n.Addr, n.Config, n.Expr, evalCtx))
|
||||||
|
|
||||||
if op == walkValidate {
|
if op == walkValidate {
|
||||||
var filtered tfdiags.Diagnostics
|
var filtered tfdiags.Diagnostics
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ func TestGraphNodeImportStateExecute(t *testing.T) {
|
|||||||
}
|
}
|
||||||
provider.ConfigureProvider(providers.ConfigureProviderRequest{})
|
provider.ConfigureProvider(providers.ConfigureProviderRequest{})
|
||||||
|
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
ProviderProvider: provider,
|
ProviderProvider: provider,
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ func TestGraphNodeImportStateExecute(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
diags := node.Execute(ctx, walkImport)
|
diags := node.Execute(t.Context(), evalCtx, walkImport)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("Unexpected error: %s", diags.Err())
|
t.Fatalf("Unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ func TestGraphNodeImportStateSubExecute(t *testing.T) {
|
|||||||
state := states.NewState()
|
state := states.NewState()
|
||||||
provider := testProvider("aws")
|
provider := testProvider("aws")
|
||||||
provider.ConfigureProvider(providers.ConfigureProviderRequest{})
|
provider.ConfigureProvider(providers.ConfigureProviderRequest{})
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
ProviderProvider: provider,
|
ProviderProvider: provider,
|
||||||
ProviderSchemaSchema: providers.ProviderSchema{
|
ProviderSchemaSchema: providers.ProviderSchema{
|
||||||
@@ -107,7 +107,7 @@ func TestGraphNodeImportStateSubExecute(t *testing.T) {
|
|||||||
Module: addrs.RootModule,
|
Module: addrs.RootModule,
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
diags := node.Execute(ctx, walkImport)
|
diags := node.Execute(t.Context(), evalCtx, walkImport)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("Unexpected error: %s", diags.Err())
|
t.Fatalf("Unexpected error: %s", diags.Err())
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ func TestGraphNodeImportStateSubExecuteNull(t *testing.T) {
|
|||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := &MockEvalContext{
|
evalCtx := &MockEvalContext{
|
||||||
StateState: state.SyncWrapper(),
|
StateState: state.SyncWrapper(),
|
||||||
ProviderProvider: provider,
|
ProviderProvider: provider,
|
||||||
ProviderSchemaSchema: providers.ProviderSchema{
|
ProviderSchemaSchema: providers.ProviderSchema{
|
||||||
@@ -169,7 +169,7 @@ func TestGraphNodeImportStateSubExecuteNull(t *testing.T) {
|
|||||||
Module: addrs.RootModule,
|
Module: addrs.RootModule,
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
diags := node.Execute(ctx, walkImport)
|
diags := node.Execute(t.Context(), evalCtx, walkImport)
|
||||||
if !diags.HasErrors() {
|
if !diags.HasErrors() {
|
||||||
t.Fatal("expected error for non-existent resource")
|
t.Fatal("expected error for non-existent resource")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package tofu
|
package tofu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -593,8 +594,8 @@ func (n *graphNodeCloseProvider) ModulePath() addrs.Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeExecutable impl.
|
// GraphNodeExecutable impl.
|
||||||
func (n *graphNodeCloseProvider) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *graphNodeCloseProvider) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
return diags.Append(ctx.CloseProvider(n.Addr))
|
return diags.Append(evalCtx.CloseProvider(n.Addr))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *graphNodeCloseProvider) CloseProviderAddr() addrs.AbsProviderConfig {
|
func (n *graphNodeCloseProvider) CloseProviderAddr() addrs.AbsProviderConfig {
|
||||||
|
|||||||
Reference in New Issue
Block a user