mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
Merge pull request #26495 from hashicorp/jbardin/evaluate-walks
Audit some graph building and GraphNodeExecutable
This commit is contained in:
commit
496cf629cb
@ -38,7 +38,7 @@ func TestContextEval(t *testing.T) {
|
||||
},
|
||||
{
|
||||
`module.child.result`,
|
||||
cty.UnknownVal(cty.Number),
|
||||
cty.NumberIntVal(6),
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
@ -87,6 +87,12 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer {
|
||||
Config: b.Config,
|
||||
},
|
||||
|
||||
// Add dynamic values
|
||||
&RootVariableTransformer{Config: b.Config},
|
||||
&ModuleVariableTransformer{Config: b.Config},
|
||||
&LocalTransformer{Config: b.Config},
|
||||
&OutputTransformer{Config: b.Config},
|
||||
|
||||
// Creates all the resource instances represented in the diff, along
|
||||
// with dependency edges against the whole-resource nodes added by
|
||||
// ConfigTransformer above.
|
||||
@ -96,31 +102,19 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer {
|
||||
Changes: b.Changes,
|
||||
},
|
||||
|
||||
// Attach the state
|
||||
&AttachStateTransformer{State: b.State},
|
||||
|
||||
// Create orphan output nodes
|
||||
&OrphanOutputTransformer{Config: b.Config, State: b.State},
|
||||
|
||||
// Attach the configuration to any resources
|
||||
&AttachResourceConfigTransformer{Config: b.Config},
|
||||
|
||||
// Attach the state
|
||||
&AttachStateTransformer{State: b.State},
|
||||
|
||||
// Provisioner-related transformations
|
||||
&MissingProvisionerTransformer{Provisioners: b.Components.ResourceProvisioners()},
|
||||
&ProvisionerTransformer{},
|
||||
|
||||
// Add root variables
|
||||
&RootVariableTransformer{Config: b.Config},
|
||||
|
||||
// Add the local values
|
||||
&LocalTransformer{Config: b.Config},
|
||||
|
||||
// Add the outputs
|
||||
&OutputTransformer{Config: b.Config},
|
||||
|
||||
// Add module variables
|
||||
&ModuleVariableTransformer{Config: b.Config},
|
||||
|
||||
// add providers
|
||||
TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config),
|
||||
|
||||
@ -150,7 +144,6 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer {
|
||||
State: b.State,
|
||||
Schemas: b.Schemas,
|
||||
},
|
||||
|
||||
&CBDEdgeTransformer{
|
||||
Config: b.Config,
|
||||
State: b.State,
|
||||
|
@ -92,8 +92,13 @@ func (b *DestroyPlanGraphBuilder) Steps() []GraphTransformer {
|
||||
// created proper destroy ordering.
|
||||
&TargetsTransformer{Targets: b.Targets},
|
||||
|
||||
// Close opened plugin connections
|
||||
&CloseProviderTransformer{},
|
||||
|
||||
// Close the root module
|
||||
&CloseRootModuleTransformer{},
|
||||
|
||||
&TransitiveReductionTransformer{},
|
||||
}
|
||||
|
||||
return steps
|
||||
|
@ -60,28 +60,20 @@ func (b *EvalGraphBuilder) Steps() []GraphTransformer {
|
||||
// Creates all the data resources that aren't in the state. This will also
|
||||
// add any orphans from scaling in as destroy nodes.
|
||||
&ConfigTransformer{
|
||||
Concrete: nil, // just use the abstract type
|
||||
Config: b.Config,
|
||||
Unique: true,
|
||||
Config: b.Config,
|
||||
},
|
||||
|
||||
// Attach the state
|
||||
&AttachStateTransformer{State: b.State},
|
||||
// Add dynamic values
|
||||
&RootVariableTransformer{Config: b.Config},
|
||||
&ModuleVariableTransformer{Config: b.Config},
|
||||
&LocalTransformer{Config: b.Config},
|
||||
&OutputTransformer{Config: b.Config},
|
||||
|
||||
// Attach the configuration to any resources
|
||||
&AttachResourceConfigTransformer{Config: b.Config},
|
||||
|
||||
// Add root variables
|
||||
&RootVariableTransformer{Config: b.Config},
|
||||
|
||||
// Add the local values
|
||||
&LocalTransformer{Config: b.Config},
|
||||
|
||||
// Add the outputs
|
||||
&OutputTransformer{Config: b.Config},
|
||||
|
||||
// Add module variables
|
||||
&ModuleVariableTransformer{Config: b.Config},
|
||||
// Attach the state
|
||||
&AttachStateTransformer{State: b.State},
|
||||
|
||||
TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config),
|
||||
|
||||
@ -92,9 +84,7 @@ func (b *EvalGraphBuilder) Steps() []GraphTransformer {
|
||||
// Create expansion nodes for all of the module calls. This must
|
||||
// come after all other transformers that create nodes representing
|
||||
// objects that can belong to modules.
|
||||
&ModuleExpansionTransformer{
|
||||
Config: b.Config,
|
||||
},
|
||||
&ModuleExpansionTransformer{Config: b.Config},
|
||||
|
||||
// Connect so that the references are ready for targeting. We'll
|
||||
// have to connect again later for providers and so on.
|
||||
|
@ -55,26 +55,20 @@ func (b *ImportGraphBuilder) Steps() []GraphTransformer {
|
||||
// Create all our resources from the configuration and state
|
||||
&ConfigTransformer{Config: config},
|
||||
|
||||
// Add dynamic values
|
||||
&RootVariableTransformer{Config: b.Config},
|
||||
&ModuleVariableTransformer{Config: b.Config},
|
||||
&LocalTransformer{Config: b.Config},
|
||||
&OutputTransformer{Config: b.Config},
|
||||
|
||||
// Attach the configuration to any resources
|
||||
&AttachResourceConfigTransformer{Config: b.Config},
|
||||
|
||||
// Add the import steps
|
||||
&ImportStateTransformer{Targets: b.ImportTargets, Config: b.Config},
|
||||
|
||||
// Add root variables
|
||||
&RootVariableTransformer{Config: b.Config},
|
||||
|
||||
TransformProviders(b.Components.ResourceProviders(), concreteProvider, config),
|
||||
|
||||
// Add the local values
|
||||
&LocalTransformer{Config: b.Config},
|
||||
|
||||
// Add the outputs
|
||||
&OutputTransformer{Config: b.Config},
|
||||
|
||||
// Add module variables
|
||||
&ModuleVariableTransformer{Config: b.Config},
|
||||
|
||||
// Must attach schemas before ReferenceTransformer so that we can
|
||||
// analyze the configuration to find references.
|
||||
&AttachSchemaTransformer{Schemas: b.Schemas, Config: b.Config},
|
||||
@ -82,9 +76,7 @@ func (b *ImportGraphBuilder) Steps() []GraphTransformer {
|
||||
// Create expansion nodes for all of the module calls. This must
|
||||
// come after all other transformers that create nodes representing
|
||||
// objects that can belong to modules.
|
||||
&ModuleExpansionTransformer{
|
||||
Config: b.Config,
|
||||
},
|
||||
&ModuleExpansionTransformer{Config: b.Config},
|
||||
|
||||
// Connect so that the references are ready for targeting. We'll
|
||||
// have to connect again later for providers and so on.
|
||||
|
@ -84,10 +84,10 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
|
||||
Config: b.Config,
|
||||
},
|
||||
|
||||
// Add the local values
|
||||
// Add dynamic values
|
||||
&RootVariableTransformer{Config: b.Config},
|
||||
&ModuleVariableTransformer{Config: b.Config},
|
||||
&LocalTransformer{Config: b.Config},
|
||||
|
||||
// Add the outputs
|
||||
&OutputTransformer{Config: b.Config},
|
||||
|
||||
// Add orphan resources
|
||||
@ -106,29 +106,20 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
|
||||
State: b.State,
|
||||
},
|
||||
|
||||
// Attach the state
|
||||
&AttachStateTransformer{State: b.State},
|
||||
|
||||
// Create orphan output nodes
|
||||
&OrphanOutputTransformer{
|
||||
Config: b.Config,
|
||||
State: b.State,
|
||||
},
|
||||
&OrphanOutputTransformer{Config: b.Config, State: b.State},
|
||||
|
||||
// Attach the configuration to any resources
|
||||
&AttachResourceConfigTransformer{Config: b.Config},
|
||||
|
||||
// Attach the state
|
||||
&AttachStateTransformer{State: b.State},
|
||||
|
||||
// Add root variables
|
||||
&RootVariableTransformer{Config: b.Config},
|
||||
|
||||
// Provisioner-related transformations
|
||||
&MissingProvisionerTransformer{Provisioners: b.Components.ResourceProvisioners()},
|
||||
&ProvisionerTransformer{},
|
||||
|
||||
// Add module variables
|
||||
&ModuleVariableTransformer{
|
||||
Config: b.Config,
|
||||
},
|
||||
|
||||
// add providers
|
||||
TransformProviders(b.Components.ResourceProviders(), b.ConcreteProvider, b.Config),
|
||||
|
||||
// Remove modules no longer present in the config
|
||||
@ -141,10 +132,7 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
|
||||
// Create expansion nodes for all of the module calls. This must
|
||||
// come after all other transformers that create nodes representing
|
||||
// objects that can belong to modules.
|
||||
&ModuleExpansionTransformer{
|
||||
Concrete: b.ConcreteModule,
|
||||
Config: b.Config,
|
||||
},
|
||||
&ModuleExpansionTransformer{Concrete: b.ConcreteModule, Config: b.Config},
|
||||
|
||||
// Connect so that the references are ready for targeting. We'll
|
||||
// have to connect again later for providers and so on.
|
||||
@ -156,9 +144,7 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
|
||||
&attachDataResourceDependenciesTransformer{},
|
||||
|
||||
// Target
|
||||
&TargetsTransformer{
|
||||
Targets: b.Targets,
|
||||
},
|
||||
&TargetsTransformer{Targets: b.Targets},
|
||||
|
||||
// Detect when create_before_destroy must be forced on for a particular
|
||||
// node due to dependency edges, to avoid graph cycles during apply.
|
||||
@ -171,7 +157,6 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
|
||||
|
||||
// Close opened plugin connections
|
||||
&CloseProviderTransformer{},
|
||||
&CloseProvisionerTransformer{},
|
||||
|
||||
// Close the root module
|
||||
&CloseRootModuleTransformer{},
|
||||
|
@ -153,13 +153,13 @@ func (n *nodeModuleVariable) Execute(ctx EvalContext, op walkOperation) error {
|
||||
var err error
|
||||
|
||||
switch op {
|
||||
case walkPlan, walkApply, walkDestroy:
|
||||
vals, err = n.EvalModuleCallArgument(ctx, false)
|
||||
case walkValidate:
|
||||
vals, err = n.EvalModuleCallArgument(ctx, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case walkValidate:
|
||||
vals, err = n.EvalModuleCallArgument(ctx, true)
|
||||
default:
|
||||
vals, err = n.EvalModuleCallArgument(ctx, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -199,61 +199,55 @@ func (n *NodeApplyableOutput) References() []*addrs.Reference {
|
||||
|
||||
// GraphNodeExecutable
|
||||
func (n *NodeApplyableOutput) Execute(ctx EvalContext, op walkOperation) error {
|
||||
switch op {
|
||||
// Everything except walkImport
|
||||
case walkEval, walkPlan, walkApply, walkValidate, walkDestroy, walkPlanDestroy:
|
||||
// This has to run before we have a state lock, since evaluation also
|
||||
// reads the state
|
||||
val, diags := ctx.EvaluateExpr(n.Config.Expr, cty.DynamicPseudoType, nil)
|
||||
// We'll handle errors below, after we have loaded the module.
|
||||
// This has to run before we have a state lock, since evaluation also
|
||||
// reads the state
|
||||
val, diags := ctx.EvaluateExpr(n.Config.Expr, cty.DynamicPseudoType, nil)
|
||||
// We'll handle errors below, after we have loaded the module.
|
||||
|
||||
// Outputs don't have a separate mode for validation, so validate
|
||||
// depends_on expressions here too
|
||||
diags = diags.Append(validateDependsOn(ctx, n.Config.DependsOn))
|
||||
// Outputs don't have a separate mode for validation, so validate
|
||||
// depends_on expressions here too
|
||||
diags = diags.Append(validateDependsOn(ctx, n.Config.DependsOn))
|
||||
|
||||
// Ensure that non-sensitive outputs don't include sensitive values
|
||||
_, marks := val.UnmarkDeep()
|
||||
_, hasSensitive := marks["sensitive"]
|
||||
if !n.Config.Sensitive && hasSensitive {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Output refers to sensitive values",
|
||||
Detail: "Expressions used in outputs can only refer to sensitive values if the sensitive attribute is true.",
|
||||
Subject: n.Config.DeclRange.Ptr(),
|
||||
})
|
||||
}
|
||||
// Ensure that non-sensitive outputs don't include sensitive values
|
||||
_, marks := val.UnmarkDeep()
|
||||
_, hasSensitive := marks["sensitive"]
|
||||
if !n.Config.Sensitive && hasSensitive {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Output refers to sensitive values",
|
||||
Detail: "Expressions used in outputs can only refer to sensitive values if the sensitive attribute is true.",
|
||||
Subject: n.Config.DeclRange.Ptr(),
|
||||
})
|
||||
}
|
||||
|
||||
state := ctx.State()
|
||||
if state == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
changes := ctx.Changes() // may be nil, if we're not working on a changeset
|
||||
|
||||
// handling the interpolation error
|
||||
if diags.HasErrors() {
|
||||
if flagWarnOutputErrors {
|
||||
log.Printf("[ERROR] Output interpolation %q failed: %s", n.Addr, diags.Err())
|
||||
// if we're continuing, make sure the output is included, and
|
||||
// marked as unknown. If the evaluator was able to find a type
|
||||
// for the value in spite of the error then we'll use it.
|
||||
n.setValue(state, changes, cty.UnknownVal(val.Type()))
|
||||
return EvalEarlyExitError{}
|
||||
}
|
||||
return diags.Err()
|
||||
}
|
||||
n.setValue(state, changes, val)
|
||||
|
||||
// If we were able to evaluate a new value, we can update that in the
|
||||
// refreshed state as well.
|
||||
if state = ctx.RefreshState(); state != nil && val.IsWhollyKnown() {
|
||||
n.setValue(state, changes, val)
|
||||
}
|
||||
|
||||
return nil
|
||||
default:
|
||||
state := ctx.State()
|
||||
if state == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
changes := ctx.Changes() // may be nil, if we're not working on a changeset
|
||||
|
||||
// handling the interpolation error
|
||||
if diags.HasErrors() {
|
||||
if flagWarnOutputErrors {
|
||||
log.Printf("[ERROR] Output interpolation %q failed: %s", n.Addr, diags.Err())
|
||||
// if we're continuing, make sure the output is included, and
|
||||
// marked as unknown. If the evaluator was able to find a type
|
||||
// for the value in spite of the error then we'll use it.
|
||||
n.setValue(state, changes, cty.UnknownVal(val.Type()))
|
||||
return EvalEarlyExitError{}
|
||||
}
|
||||
return diags.Err()
|
||||
}
|
||||
n.setValue(state, changes, val)
|
||||
|
||||
// If we were able to evaluate a new value, we can update that in the
|
||||
// refreshed state as well.
|
||||
if state = ctx.RefreshState(); state != nil && val.IsWhollyKnown() {
|
||||
n.setValue(state, changes, val)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// dag.GraphNodeDotter impl.
|
||||
|
@ -136,133 +136,130 @@ func (n *NodeDestroyResourceInstance) Execute(ctx EvalContext, op walkOperation)
|
||||
var state *states.ResourceInstanceObject
|
||||
var provisionerErr error
|
||||
|
||||
switch op {
|
||||
case walkApply, walkDestroy:
|
||||
provider, providerSchema, err := GetProvider(ctx, n.ResolvedProvider)
|
||||
provider, providerSchema, err := GetProvider(ctx, n.ResolvedProvider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
changeApply, err = n.readDiff(ctx, providerSchema)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
evalReduceDiff := &EvalReduceDiff{
|
||||
Addr: addr.Resource,
|
||||
InChange: &changeApply,
|
||||
Destroy: true,
|
||||
OutChange: &changeApply,
|
||||
}
|
||||
_, err = evalReduceDiff.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// EvalReduceDiff may have simplified our planned change
|
||||
// into a NoOp if it does not require destroying.
|
||||
if changeApply == nil || changeApply.Action == plans.NoOp {
|
||||
return EvalEarlyExitError{}
|
||||
}
|
||||
|
||||
state, err = n.ReadResourceInstanceState(ctx, addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Exit early if the state object is null after reading the state
|
||||
if state == nil || state.Value.IsNull() {
|
||||
return EvalEarlyExitError{}
|
||||
}
|
||||
|
||||
evalApplyPre := &EvalApplyPre{
|
||||
Addr: addr.Resource,
|
||||
State: &state,
|
||||
Change: &changeApply,
|
||||
}
|
||||
_, err = evalApplyPre.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Run destroy provisioners if not tainted
|
||||
if state != nil && state.Status != states.ObjectTainted {
|
||||
evalApplyProvisioners := &EvalApplyProvisioners{
|
||||
Addr: addr.Resource,
|
||||
State: &state,
|
||||
ResourceConfig: n.Config,
|
||||
Error: &provisionerErr,
|
||||
When: configs.ProvisionerWhenDestroy,
|
||||
}
|
||||
_, err := evalApplyProvisioners.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
changeApply, err = n.readDiff(ctx, providerSchema)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
evalReduceDiff := &EvalReduceDiff{
|
||||
Addr: addr.Resource,
|
||||
InChange: &changeApply,
|
||||
Destroy: true,
|
||||
OutChange: &changeApply,
|
||||
}
|
||||
_, err = evalReduceDiff.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// EvalReduceDiff may have simplified our planned change
|
||||
// into a NoOp if it does not require destroying.
|
||||
if changeApply == nil || changeApply.Action == plans.NoOp {
|
||||
return EvalEarlyExitError{}
|
||||
}
|
||||
|
||||
state, err = n.ReadResourceInstanceState(ctx, addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Exit early if the state object is null after reading the state
|
||||
if state == nil || state.Value.IsNull() {
|
||||
return EvalEarlyExitError{}
|
||||
}
|
||||
|
||||
evalApplyPre := &EvalApplyPre{
|
||||
Addr: addr.Resource,
|
||||
State: &state,
|
||||
Change: &changeApply,
|
||||
}
|
||||
_, err = evalApplyPre.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Run destroy provisioners if not tainted
|
||||
if state != nil && state.Status != states.ObjectTainted {
|
||||
evalApplyProvisioners := &EvalApplyProvisioners{
|
||||
Addr: addr.Resource,
|
||||
State: &state,
|
||||
ResourceConfig: n.Config,
|
||||
Error: &provisionerErr,
|
||||
When: configs.ProvisionerWhenDestroy,
|
||||
if provisionerErr != nil {
|
||||
// If we have a provisioning error, then we just call
|
||||
// the post-apply hook now.
|
||||
evalApplyPost := &EvalApplyPost{
|
||||
Addr: addr.Resource,
|
||||
State: &state,
|
||||
Error: &provisionerErr,
|
||||
}
|
||||
_, err := evalApplyProvisioners.Eval(ctx)
|
||||
_, err = evalApplyPost.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if provisionerErr != nil {
|
||||
// If we have a provisioning error, then we just call
|
||||
// the post-apply hook now.
|
||||
evalApplyPost := &EvalApplyPost{
|
||||
Addr: addr.Resource,
|
||||
State: &state,
|
||||
Error: &provisionerErr,
|
||||
}
|
||||
_, err = evalApplyPost.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Managed resources need to be destroyed, while data sources
|
||||
// are only removed from state.
|
||||
if addr.Resource.Resource.Mode == addrs.ManagedResourceMode {
|
||||
evalApply := &EvalApply{
|
||||
Addr: addr.Resource,
|
||||
Config: nil, // No configuration because we are destroying
|
||||
State: &state,
|
||||
Change: &changeApply,
|
||||
Provider: &provider,
|
||||
ProviderAddr: n.ResolvedProvider,
|
||||
ProviderMetas: n.ProviderMetas,
|
||||
ProviderSchema: &providerSchema,
|
||||
Output: &state,
|
||||
Error: &provisionerErr,
|
||||
}
|
||||
_, err = evalApply.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
evalWriteState := &EvalWriteState{
|
||||
Addr: addr.Resource,
|
||||
ProviderAddr: n.ResolvedProvider,
|
||||
ProviderSchema: &providerSchema,
|
||||
State: &state,
|
||||
}
|
||||
_, err = evalWriteState.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
log.Printf("[TRACE] NodeDestroyResourceInstance: removing state object for %s", n.Addr)
|
||||
state := ctx.State()
|
||||
state.SetResourceInstanceCurrent(n.Addr, nil, n.ResolvedProvider)
|
||||
// Managed resources need to be destroyed, while data sources
|
||||
// are only removed from state.
|
||||
if addr.Resource.Resource.Mode == addrs.ManagedResourceMode {
|
||||
evalApply := &EvalApply{
|
||||
Addr: addr.Resource,
|
||||
Config: nil, // No configuration because we are destroying
|
||||
State: &state,
|
||||
Change: &changeApply,
|
||||
Provider: &provider,
|
||||
ProviderAddr: n.ResolvedProvider,
|
||||
ProviderMetas: n.ProviderMetas,
|
||||
ProviderSchema: &providerSchema,
|
||||
Output: &state,
|
||||
Error: &provisionerErr,
|
||||
}
|
||||
|
||||
evalApplyPost := &EvalApplyPost{
|
||||
Addr: addr.Resource,
|
||||
State: &state,
|
||||
Error: &provisionerErr,
|
||||
}
|
||||
_, err = evalApplyPost.Eval(ctx)
|
||||
_, err = evalApply.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = UpdateStateHook(ctx)
|
||||
evalWriteState := &EvalWriteState{
|
||||
Addr: addr.Resource,
|
||||
ProviderAddr: n.ResolvedProvider,
|
||||
ProviderSchema: &providerSchema,
|
||||
State: &state,
|
||||
}
|
||||
_, err = evalWriteState.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
log.Printf("[TRACE] NodeDestroyResourceInstance: removing state object for %s", n.Addr)
|
||||
state := ctx.State()
|
||||
state.SetResourceInstanceCurrent(n.Addr, nil, n.ResolvedProvider)
|
||||
}
|
||||
|
||||
evalApplyPost := &EvalApplyPost{
|
||||
Addr: addr.Resource,
|
||||
State: &state,
|
||||
Error: &provisionerErr,
|
||||
}
|
||||
_, err = evalApplyPost.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = UpdateStateHook(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -76,44 +76,41 @@ func (n *NodePlanDeposedResourceInstanceObject) Execute(ctx EvalContext, op walk
|
||||
var change *plans.ResourceInstanceChange
|
||||
var state *states.ResourceInstanceObject
|
||||
|
||||
switch op {
|
||||
case walkPlan, walkPlanDestroy:
|
||||
|
||||
readStateDeposed := &EvalReadStateDeposed{
|
||||
Addr: addr.Resource,
|
||||
Output: &state,
|
||||
Key: n.DeposedKey,
|
||||
Provider: &provider,
|
||||
ProviderSchema: &providerSchema,
|
||||
}
|
||||
_, err = readStateDeposed.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
diffDestroy := &EvalDiffDestroy{
|
||||
Addr: addr.Resource,
|
||||
ProviderAddr: n.ResolvedProvider,
|
||||
DeposedKey: n.DeposedKey,
|
||||
State: &state,
|
||||
Output: &change,
|
||||
}
|
||||
_, err = diffDestroy.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
writeDiff := &EvalWriteDiff{
|
||||
Addr: addr.Resource,
|
||||
DeposedKey: n.DeposedKey,
|
||||
ProviderSchema: &providerSchema,
|
||||
Change: &change,
|
||||
}
|
||||
_, err = writeDiff.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readStateDeposed := &EvalReadStateDeposed{
|
||||
Addr: addr.Resource,
|
||||
Output: &state,
|
||||
Key: n.DeposedKey,
|
||||
Provider: &provider,
|
||||
ProviderSchema: &providerSchema,
|
||||
}
|
||||
_, err = readStateDeposed.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
diffDestroy := &EvalDiffDestroy{
|
||||
Addr: addr.Resource,
|
||||
ProviderAddr: n.ResolvedProvider,
|
||||
DeposedKey: n.DeposedKey,
|
||||
State: &state,
|
||||
Output: &change,
|
||||
}
|
||||
_, err = diffDestroy.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
writeDiff := &EvalWriteDiff{
|
||||
Addr: addr.Resource,
|
||||
DeposedKey: n.DeposedKey,
|
||||
ProviderSchema: &providerSchema,
|
||||
Change: &change,
|
||||
}
|
||||
_, err = writeDiff.Eval(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,6 @@ type ConfigTransformer struct {
|
||||
// Module is the module to add resources from.
|
||||
Config *configs.Config
|
||||
|
||||
// Unique will only add resources that aren't already present in the graph.
|
||||
Unique bool
|
||||
|
||||
// Mode will only add resources that match the given mode
|
||||
ModeFilter bool
|
||||
Mode addrs.ResourceMode
|
||||
|
@ -301,7 +301,7 @@ func (m ReferenceMap) References(v dag.Vertex) []dag.Vertex {
|
||||
case addrs.ModuleCallInstance:
|
||||
subject = ri.Call
|
||||
default:
|
||||
log.Printf("[WARN] ReferenceTransformer: reference not found: %q", subject)
|
||||
log.Printf("[INFO] ReferenceTransformer: reference not found: %q", subject)
|
||||
continue
|
||||
}
|
||||
key = m.referenceMapKey(v, subject)
|
||||
|
Loading…
Reference in New Issue
Block a user