From c1690a0ccf15523846dcf162b01d0d4a83cea6c4 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Tue, 20 Jan 2026 11:56:08 -0800 Subject: [PATCH] exec: ResourceInstanceObject represents an object and its address During execution graph processing we need to carry addressing information along with objects so that we can model changes of address as data flow rather than as modifications to global mutable state. In previous commits we arranged for other relevant types to track this information, but the representation of a resource instance object was not included because that was a messier change to wire in. This commit deals with that mess: it introduces exec.ResourceInstanceObject to associate a resource instance object with addressing information, and then adopts that as the canonical representation of a "resource instance object result" throughout all of the execution graph operations. Signed-off-by: Martin Atkins --- .../engine/applying/operations_resource.go | 23 ++-- .../applying/operations_resource_data.go | 3 +- .../applying/operations_resource_ephemeral.go | 5 +- .../applying/operations_resource_managed.go | 30 +++-- internal/engine/internal/exec/operations.go | 20 ++-- .../exec/{managed_resource.go => resource.go} | 71 +++++++++++- internal/engine/internal/execgraph/builder.go | 24 ++-- .../engine/internal/execgraph/builder_test.go | 4 +- .../engine/internal/execgraph/compiler.go | 5 +- .../engine/internal/execgraph/compiler_ops.go | 6 +- .../internal/execgraph/compiler_test.go | 107 ++++++++++-------- internal/engine/internal/execgraph/graph.go | 3 +- .../internal/execgraph/graph_marshal.go | 3 +- .../engine/internal/execgraph/graph_test.go | 4 +- .../internal/execgraph/graph_unmarshal.go | 9 +- .../internal/execgraph/operations_test.go | 48 ++++---- internal/engine/internal/execgraph/result.go | 4 +- internal/engine/planning/plan_managed.go | 3 +- 18 files changed, 236 insertions(+), 136 deletions(-) rename internal/engine/internal/exec/{managed_resource.go => resource.go} (52%) diff --git a/internal/engine/applying/operations_resource.go b/internal/engine/applying/operations_resource.go index 7adbbe78e8..88b5795eef 100644 --- a/internal/engine/applying/operations_resource.go +++ b/internal/engine/applying/operations_resource.go @@ -11,6 +11,7 @@ import ( "log" "github.com/opentofu/opentofu/internal/addrs" + "github.com/opentofu/opentofu/internal/engine/internal/exec" "github.com/opentofu/opentofu/internal/lang/eval" "github.com/opentofu/opentofu/internal/states" "github.com/opentofu/opentofu/internal/tfdiags" @@ -29,15 +30,15 @@ func (ops *execOperations) ResourceInstanceDesired( func (ops *execOperations) ResourceInstancePrior( ctx context.Context, instAddr addrs.AbsResourceInstance, -) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { log.Printf("[TRACE] applying: ResourceInstancePrior %s", instAddr) - return ops.resourceInstancePriorStateObject(ctx, instAddr, states.NotDeposed) + return ops.resourceInstanceStateObject(ctx, ops.priorState, instAddr, states.NotDeposed) } // ResourceInstancePostconditions implements [exec.Operations]. func (ops *execOperations) ResourceInstancePostconditions( ctx context.Context, - result *states.ResourceInstanceObjectFull, + result *exec.ResourceInstanceObject, ) tfdiags.Diagnostics { log.Printf("[TRACE] applying: ResourceInstancePostconditions (currently just a noop!)") // TODO: Implement this by delegating to a special "run resource instance @@ -46,11 +47,12 @@ func (ops *execOperations) ResourceInstancePostconditions( } // ResourceInstancePrior implements [exec.Operations]. -func (ops *execOperations) resourceInstancePriorStateObject( +func (ops *execOperations) resourceInstanceStateObject( ctx context.Context, + fromState *states.SyncState, instAddr addrs.AbsResourceInstance, deposedKey states.DeposedKey, -) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics src := ops.priorState.ResourceInstanceObjectFull(instAddr, deposedKey) if src == nil { @@ -69,7 +71,7 @@ func (ops *execOperations) resourceInstancePriorStateObject( if moreDiags.HasErrors() { return nil, diags } - ret, err := states.DecodeResourceInstanceObjectFull(src, schema.Block.ImpliedType()) + state, err := states.DecodeResourceInstanceObjectFull(src, schema.Block.ImpliedType()) if err != nil { nounPhrase := "a current object" if deposedKey != states.NotDeposed { @@ -85,5 +87,12 @@ func (ops *execOperations) resourceInstancePriorStateObject( )) return nil, diags } - return ret, diags + if state == nil { + return nil, diags + } + return &exec.ResourceInstanceObject{ + InstanceAddr: instAddr, + DeposedKey: deposedKey, + State: state, + }, diags } diff --git a/internal/engine/applying/operations_resource_data.go b/internal/engine/applying/operations_resource_data.go index 91c5f7e091..c36fe7a7ec 100644 --- a/internal/engine/applying/operations_resource_data.go +++ b/internal/engine/applying/operations_resource_data.go @@ -13,7 +13,6 @@ import ( "github.com/opentofu/opentofu/internal/engine/internal/exec" "github.com/opentofu/opentofu/internal/lang/eval" - "github.com/opentofu/opentofu/internal/states" "github.com/opentofu/opentofu/internal/tfdiags" ) @@ -23,7 +22,7 @@ func (ops *execOperations) DataRead( desired *eval.DesiredResourceInstance, plannedVal cty.Value, providerClient *exec.ProviderClient, -) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { log.Printf("[TRACE] applying: DataRead %s", desired.Addr) panic("unimplemented") } diff --git a/internal/engine/applying/operations_resource_ephemeral.go b/internal/engine/applying/operations_resource_ephemeral.go index 165bf995aa..b844fd50c0 100644 --- a/internal/engine/applying/operations_resource_ephemeral.go +++ b/internal/engine/applying/operations_resource_ephemeral.go @@ -11,14 +11,13 @@ import ( "github.com/opentofu/opentofu/internal/engine/internal/exec" "github.com/opentofu/opentofu/internal/lang/eval" - "github.com/opentofu/opentofu/internal/states" "github.com/opentofu/opentofu/internal/tfdiags" ) // EphemeralClose implements [exec.Operations]. func (ops *execOperations) EphemeralClose( ctx context.Context, - object *states.ResourceInstanceObjectFull, + object *exec.ResourceInstanceObject, providerClient *exec.ProviderClient, ) tfdiags.Diagnostics { // FIXME: Track instance address on resource instance objects @@ -31,7 +30,7 @@ func (ops *execOperations) EphemeralOpen( ctx context.Context, desired *eval.DesiredResourceInstance, providerClient *exec.ProviderClient, -) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { log.Printf("[TRACE] applying: EphemeralOpen %s", desired.Addr) panic("unimplemented") } diff --git a/internal/engine/applying/operations_resource_managed.go b/internal/engine/applying/operations_resource_managed.go index 2936928201..225d198510 100644 --- a/internal/engine/applying/operations_resource_managed.go +++ b/internal/engine/applying/operations_resource_managed.go @@ -22,7 +22,7 @@ import ( func (ops *execOperations) ManagedFinalPlan( ctx context.Context, desired *eval.DesiredResourceInstance, - prior *states.ResourceInstanceObjectFull, + prior *exec.ResourceInstanceObject, plannedVal cty.Value, providerClient *exec.ProviderClient, ) (*exec.ManagedResourceObjectFinalPlan, tfdiags.Diagnostics) { @@ -35,15 +35,15 @@ func (ops *execOperations) ManagedFinalPlan( // change, so we'll arbitrarily choose to prefer the desired address // whenever both are set. instAddr = desired.Addr + // (deposed objects are never "desired") } else if prior != nil { - // FIXME: ResourceInstanceObjectFull must carry identity with it so - // we can know what we're working with when we're planning destroy. - //instAddr = prior.Addr - //deposedKey = prior.DeposedKey + instAddr = prior.InstanceAddr + deposedKey = prior.DeposedKey } else { // Both should not be nil but if they are then we'll treat it the same // way as if we dynamically discover that no change is actually // required, by returning a nil final plan to represent "noop". + log.Printf("[TRACE] applying: ManagedFinalPlan without either desired or prior state, so no change is needed") return nil, nil } if deposedKey == states.NotDeposed { @@ -58,9 +58,9 @@ func (ops *execOperations) ManagedFinalPlan( func (ops *execOperations) ManagedApply( ctx context.Context, plan *exec.ManagedResourceObjectFinalPlan, - fallback *states.ResourceInstanceObjectFull, + fallback *exec.ResourceInstanceObject, providerClient *exec.ProviderClient, -) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { if plan == nil { // TODO: if "fallback" is set then we should set it as current here to // honor the overall contract. In practice we currently never construct @@ -93,9 +93,17 @@ func (ops *execOperations) ManagedApply( func (ops *execOperations) ManagedDepose( ctx context.Context, instAddr addrs.AbsResourceInstance, -) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { log.Printf("[TRACE] applying: ManagedDepose %s", instAddr) - panic("unimplemented") + var diags tfdiags.Diagnostics + + deposedKey := ops.workingState.DeposeResourceInstanceObject(instAddr) + if deposedKey == states.NotDeposed { + // This means that there was no "current" object to depose, and + // so we'll return nil to represent that there's nothing here. + return nil, diags + } + return ops.resourceInstanceStateObject(ctx, ops.workingState, instAddr, deposedKey) } // ManagedAlreadyDeposed implements [exec.Operations]. @@ -103,10 +111,10 @@ func (ops *execOperations) ManagedAlreadyDeposed( ctx context.Context, instAddr addrs.AbsResourceInstance, deposedKey states.DeposedKey, -) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { log.Printf("[TRACE] applying: ManagedAlreadyDeposed %s deposed object %s", instAddr, deposedKey) // This is essentially the same as ResourceInstancePrior, but for deposed // objects rather than "current" objects. Therefore we'll share most of the // implementation between these two. - return ops.resourceInstancePriorStateObject(ctx, instAddr, deposedKey) + return ops.resourceInstanceStateObject(ctx, ops.priorState, instAddr, deposedKey) } diff --git a/internal/engine/internal/exec/operations.go b/internal/engine/internal/exec/operations.go index ac14d12874..cf6c7e5fa6 100644 --- a/internal/engine/internal/exec/operations.go +++ b/internal/engine/internal/exec/operations.go @@ -113,7 +113,7 @@ type Operations interface { ResourceInstancePrior( ctx context.Context, instAddr addrs.AbsResourceInstance, - ) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) + ) (*ResourceInstanceObject, tfdiags.Diagnostics) // ResourceInstancePostconditions tests whether the given object passes // any postconditions that were declared for it. @@ -125,7 +125,7 @@ type Operations interface { // handled consistently for all resource modes. ResourceInstancePostconditions( ctx context.Context, - result *states.ResourceInstanceObjectFull, + result *ResourceInstanceObject, ) tfdiags.Diagnostics ////////////////////////////////////////////////////////////////////////////// @@ -148,7 +148,7 @@ type Operations interface { ManagedFinalPlan( ctx context.Context, desired *eval.DesiredResourceInstance, - prior *states.ResourceInstanceObjectFull, + prior *ResourceInstanceObject, plannedVal cty.Value, providerClient *ProviderClient, ) (*ManagedResourceObjectFinalPlan, tfdiags.Diagnostics) @@ -187,9 +187,9 @@ type Operations interface { ManagedApply( ctx context.Context, plan *ManagedResourceObjectFinalPlan, - fallback *states.ResourceInstanceObjectFull, + fallback *ResourceInstanceObject, providerClient *ProviderClient, - ) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) + ) (*ResourceInstanceObject, tfdiags.Diagnostics) // ManagedDepose transforms the "current" object associated with the given // resource instance address into a "deposed" object for the same resource @@ -206,7 +206,7 @@ type Operations interface { ManagedDepose( ctx context.Context, instAddr addrs.AbsResourceInstance, - ) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) + ) (*ResourceInstanceObject, tfdiags.Diagnostics) // ManagedAlreadyDeposed returns a deposed object from the prior state, // nor nil if there is no such object. @@ -225,7 +225,7 @@ type Operations interface { ctx context.Context, instAddr addrs.AbsResourceInstance, deposedKey states.DeposedKey, - ) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) + ) (*ResourceInstanceObject, tfdiags.Diagnostics) ////////////////////////////////////////////////////////////////////////////// /// Resource-related operations that are relevant only for data resources. @@ -253,7 +253,7 @@ type Operations interface { desired *eval.DesiredResourceInstance, plannedVal cty.Value, providerClient *ProviderClient, - ) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) + ) (*ResourceInstanceObject, tfdiags.Diagnostics) ////////////////////////////////////////////////////////////////////////////// /// Resource-related operations that are relevant only for ephemeral resources. @@ -280,7 +280,7 @@ type Operations interface { ctx context.Context, desired *eval.DesiredResourceInstance, providerClient *ProviderClient, - ) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) + ) (*ResourceInstanceObject, tfdiags.Diagnostics) // EphemeralClose uses the given provider client to "close" the given // ephemeral object. @@ -292,7 +292,7 @@ type Operations interface { // after this method returns. EphemeralClose( ctx context.Context, - object *states.ResourceInstanceObjectFull, + object *ResourceInstanceObject, providerClient *ProviderClient, ) tfdiags.Diagnostics } diff --git a/internal/engine/internal/exec/managed_resource.go b/internal/engine/internal/exec/resource.go similarity index 52% rename from internal/engine/internal/exec/managed_resource.go rename to internal/engine/internal/exec/resource.go index bd705eee00..fbdee4407d 100644 --- a/internal/engine/internal/exec/managed_resource.go +++ b/internal/engine/internal/exec/resource.go @@ -6,9 +6,10 @@ package exec import ( + "github.com/zclconf/go-cty/cty" + "github.com/opentofu/opentofu/internal/addrs" "github.com/opentofu/opentofu/internal/states" - "github.com/zclconf/go-cty/cty" ) // ManagedResourceObjectFinalPlan represents a final plan -- ready to actually @@ -64,3 +65,71 @@ type ManagedResourceObjectFinalPlan struct { // TODO: Anything else we'd need to populate an "ApplyResourceChanges" // request to the associated provider. } + +// ResourceInstanceObject associates a [states.ResourceInstanceObjectFull] with +// a resource instance address and optional deposed key. +// +// Objects of this type should be treated as immutable. Use the methods of this +// type to derive new objects when modelling changes. +// +// This is intended to model the idea that an object can move between different +// tracking addresses without being modified: an instance of this type +// represents the object existing at a particular address, with the intention +// that a caller would create a new object of this type whenever an object +// moves between addresses but should not need to change the underlying object +// itself. +// +// If an operation _does_ cause an object to move to a new tracking address then +// it should be designed to take an object of this type as an argument +// representing the starting location and then to return a newly-constructed +// separate object of this type representing the new location, so that the +// change of address is modelled in the data flow between operations rather than +// as global mutable state. +type ResourceInstanceObject struct { + InstanceAddr addrs.AbsResourceInstance + DeposedKey states.DeposedKey + + // State is the object currently associated with the given address. + State *states.ResourceInstanceObjectFull +} + +// IntoCurrent returns a new [ResourceInstanceObject] that has the same +// State as the receiver but has DeposedKey set to [states.NotDeposed]. +func (o *ResourceInstanceObject) IntoCurrent() *ResourceInstanceObject { + return &ResourceInstanceObject{ + InstanceAddr: o.InstanceAddr, + DeposedKey: states.NotDeposed, + State: o.State, + } +} + +// IntoCurrent returns a new [ResourceInstanceObject] that has the same +// State as the receiver but has DeposedKey set the given value. +// +// This function does not (and cannot) verify that the chosen deposed key is +// unique for the resource instance. It's the caller's responsibility to +// allocate a unique deposed key to use. +func (o *ResourceInstanceObject) IntoDeposed(key states.DeposedKey) *ResourceInstanceObject { + return &ResourceInstanceObject{ + InstanceAddr: o.InstanceAddr, + DeposedKey: key, + State: o.State, + } +} + +// IntoCurrent returns a new [ResourceInstanceObject] that has the same +// address information as the receiver but has State set to the given object. +// +// If the given state object is nil then the result is also nil, to represent +// the absense of an object. [ResourceInstanceObject] instances should only +// represent objects that actually exist. +func (o *ResourceInstanceObject) WithNewState(newState *states.ResourceInstanceObjectFull) *ResourceInstanceObject { + if newState == nil { + return nil + } + return &ResourceInstanceObject{ + InstanceAddr: o.InstanceAddr, + DeposedKey: o.DeposedKey, + State: newState, + } +} diff --git a/internal/engine/internal/execgraph/builder.go b/internal/engine/internal/execgraph/builder.go index c0b4249c52..8d9ca66bb9 100644 --- a/internal/engine/internal/execgraph/builder.go +++ b/internal/engine/internal/execgraph/builder.go @@ -14,7 +14,6 @@ import ( "github.com/opentofu/opentofu/internal/addrs" "github.com/opentofu/opentofu/internal/engine/internal/exec" "github.com/opentofu/opentofu/internal/lang/eval" - "github.com/opentofu/opentofu/internal/states" ) // Builder is a helper for multiple codepaths to collaborate to build an @@ -46,7 +45,7 @@ type Builder struct { func NewBuilder() *Builder { return &Builder{ graph: &Graph{ - resourceInstanceResults: addrs.MakeMap[addrs.AbsResourceInstance, ResultRef[*states.ResourceInstanceObjectFull]](), + resourceInstanceResults: addrs.MakeMap[addrs.AbsResourceInstance, ResourceInstanceResultRef](), }, resourceInstAddrRefs: addrs.MakeMap[addrs.AbsResourceInstance, ResultRef[addrs.AbsResourceInstance]](), providerInstAddrRefs: addrs.MakeMap[addrs.AbsProviderInstanceCorrect, ResultRef[addrs.AbsProviderInstanceCorrect]](), @@ -239,7 +238,7 @@ func (b *Builder) ResourceInstancePrior( b.mu.Lock() defer b.mu.Unlock() - return operationRef[*states.ResourceInstanceObjectFull](b, operationDesc{ + return operationRef[*exec.ResourceInstanceObject](b, operationDesc{ opCode: opResourceInstancePrior, operands: []AnyResultRef{addr}, }) @@ -263,7 +262,7 @@ func (b *Builder) ResourceInstancePrior( // both be set when handling an in-place update. func (b *Builder) ManagedFinalPlan( desiredInst ResultRef[*eval.DesiredResourceInstance], - priorState ResultRef[*states.ResourceInstanceObjectFull], + priorState ResourceInstanceResultRef, plannedVal ResultRef[cty.Value], providerClient ResultRef[*exec.ProviderClient], ) ResultRef[*exec.ManagedResourceObjectFinalPlan] { @@ -281,15 +280,20 @@ func (b *Builder) ManagedFinalPlan( // // The finalPlan argument should typically be something returned by a previous // call to [Builder.ManagedFinalPlan] with the same provider client. +// +// fallbackObj is usually a [NilResultRef], but should be set for the "create" +// leg of a "create then destroy" replace operation to be the result of a +// call to [Builder.ManagedDepose] so that the deposed object can be restored +// to current if the create call completely fails to create a new object. func (b *Builder) ManagedApply( finalPlan ResultRef[*exec.ManagedResourceObjectFinalPlan], - fallbackObj ResultRef[*states.ResourceInstanceObjectFull], + fallbackObj ResourceInstanceResultRef, providerClient ResultRef[*exec.ProviderClient], ) ResourceInstanceResultRef { b.mu.Lock() defer b.mu.Unlock() - return operationRef[*states.ResourceInstanceObjectFull](b, operationDesc{ + return operationRef[*exec.ResourceInstanceObject](b, operationDesc{ opCode: opManagedApply, operands: []AnyResultRef{finalPlan, fallbackObj, providerClient}, }) @@ -301,7 +305,7 @@ func (b *Builder) ManagedDepose( b.mu.Lock() defer b.mu.Unlock() - return operationRef[*states.ResourceInstanceObjectFull](b, operationDesc{ + return operationRef[*exec.ResourceInstanceObject](b, operationDesc{ opCode: opManagedDepose, operands: []AnyResultRef{instAddr}, }) @@ -313,7 +317,7 @@ func (b *Builder) ManagedAlreadyDeposed( b.mu.Lock() defer b.mu.Unlock() - return operationRef[*states.ResourceInstanceObjectFull](b, operationDesc{ + return operationRef[*exec.ResourceInstanceObject](b, operationDesc{ opCode: opManagedAlreadyDeposed, operands: []AnyResultRef{instAddr}, }) @@ -327,7 +331,7 @@ func (b *Builder) DataRead( b.mu.Lock() defer b.mu.Unlock() - return operationRef[*states.ResourceInstanceObjectFull](b, operationDesc{ + return operationRef[*exec.ResourceInstanceObject](b, operationDesc{ opCode: opDataRead, operands: []AnyResultRef{desiredInst, plannedVal, providerClient}, }) @@ -340,7 +344,7 @@ func (b *Builder) EphemeralOpen( b.mu.Lock() defer b.mu.Unlock() - return operationRef[*states.ResourceInstanceObjectFull](b, operationDesc{ + return operationRef[*exec.ResourceInstanceObject](b, operationDesc{ opCode: opEphemeralOpen, operands: []AnyResultRef{desiredInst, providerClient}, }) diff --git a/internal/engine/internal/execgraph/builder_test.go b/internal/engine/internal/execgraph/builder_test.go index 380699642a..bf0f72b439 100644 --- a/internal/engine/internal/execgraph/builder_test.go +++ b/internal/engine/internal/execgraph/builder_test.go @@ -11,7 +11,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/opentofu/opentofu/internal/addrs" - "github.com/opentofu/opentofu/internal/states" + "github.com/opentofu/opentofu/internal/engine/internal/exec" "github.com/zclconf/go-cty/cty" ) @@ -47,7 +47,7 @@ func TestBuilder_basics(t *testing.T) { providerClient, ) newState := builder.ManagedApply( - finalPlan, NilResultRef[*states.ResourceInstanceObjectFull](), providerClient, + finalPlan, NilResultRef[*exec.ResourceInstanceObject](), providerClient, ) addProviderUser(newState) builder.SetResourceInstanceFinalStateResult(resourceInstAddr, newState) diff --git a/internal/engine/internal/execgraph/compiler.go b/internal/engine/internal/execgraph/compiler.go index 4a2ce64637..4974bfd011 100644 --- a/internal/engine/internal/execgraph/compiler.go +++ b/internal/engine/internal/execgraph/compiler.go @@ -17,7 +17,6 @@ import ( "github.com/opentofu/opentofu/internal/addrs" "github.com/opentofu/opentofu/internal/engine/internal/exec" "github.com/opentofu/opentofu/internal/lang/grapheval" - "github.com/opentofu/opentofu/internal/states" "github.com/opentofu/opentofu/internal/tfdiags" ) @@ -177,11 +176,11 @@ func (c *compiler) Compile() (*CompiledGraph, tfdiags.Diagnostics) { if !ok { return cty.DynamicVal } - finalStateObj := rawResult.(*states.ResourceInstanceObjectFull) + finalStateObj := rawResult.(*exec.ResourceInstanceObject) if finalStateObj == nil { return cty.NullVal(cty.DynamicPseudoType) } - return finalStateObj.Value + return finalStateObj.State.Value }) } diff --git a/internal/engine/internal/execgraph/compiler_ops.go b/internal/engine/internal/execgraph/compiler_ops.go index f855824f32..c7d2c17c9d 100644 --- a/internal/engine/internal/execgraph/compiler_ops.go +++ b/internal/engine/internal/execgraph/compiler_ops.go @@ -175,7 +175,7 @@ func (c *compiler) compileOpResourceInstancePrior(operands *compilerOperands) no func (c *compiler) compileOpManagedFinalPlan(operands *compilerOperands) nodeExecuteRaw { getDesired := nextOperand[*eval.DesiredResourceInstance](operands) - getPrior := nextOperand[*states.ResourceInstanceObjectFull](operands) + getPrior := nextOperand[*exec.ResourceInstanceObject](operands) getInitialPlanned := nextOperand[cty.Value](operands) getProviderClient := nextOperand[*exec.ProviderClient](operands) diags := operands.Finish() @@ -224,7 +224,7 @@ func (c *compiler) compileOpManagedFinalPlan(operands *compilerOperands) nodeExe func (c *compiler) compileOpManagedApply(operands *compilerOperands) nodeExecuteRaw { getFinalPlan := nextOperand[*exec.ManagedResourceObjectFinalPlan](operands) - getFallback := nextOperand[*states.ResourceInstanceObjectFull](operands) + getFallback := nextOperand[*exec.ResourceInstanceObject](operands) getProviderClient := nextOperand[*exec.ProviderClient](operands) diags := operands.Finish() c.diags = c.diags.Append(diags) @@ -405,7 +405,7 @@ func (c *compiler) compileOpEphemeralOpen(operands *compilerOperands) nodeExecut } func (c *compiler) compileOpEphemeralClose(operands *compilerOperands) nodeExecuteRaw { - getObject := nextOperand[*states.ResourceInstanceObjectFull](operands) + getObject := nextOperand[*exec.ResourceInstanceObject](operands) getProviderClient := nextOperand[*exec.ProviderClient](operands) diags := operands.Finish() c.diags = c.diags.Append(diags) diff --git a/internal/engine/internal/execgraph/compiler_test.go b/internal/engine/internal/execgraph/compiler_test.go index 1e1da8ab20..fb26b0bf75 100644 --- a/internal/engine/internal/execgraph/compiler_test.go +++ b/internal/engine/internal/execgraph/compiler_test.go @@ -64,7 +64,7 @@ func TestCompiler_resourceInstanceBasics(t *testing.T) { providerClient, ) newState := builder.ManagedApply( - finalPlan, NilResultRef[*states.ResourceInstanceObjectFull](), providerClient, + finalPlan, NilResultRef[*exec.ResourceInstanceObject](), providerClient, ) addProviderUser(newState) builder.SetResourceInstanceFinalStateResult(resourceInstAddr, newState) @@ -92,37 +92,43 @@ func TestCompiler_resourceInstanceBasics(t *testing.T) { ResourceType: addr.Resource.Resource.Type, }, nil }, - ResourceInstancePriorFunc: func(ctx context.Context, addr addrs.AbsResourceInstance) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { - return &states.ResourceInstanceObjectFull{ - Status: states.ObjectReady, - Value: cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prior"), - }), - ProviderInstanceAddr: addrs.AbsProviderInstanceCorrect{ - Config: addrs.AbsProviderConfigCorrect{ - Config: addrs.ProviderConfigCorrect{ - Provider: addrs.NewBuiltInProvider("test"), + ResourceInstancePriorFunc: func(ctx context.Context, addr addrs.AbsResourceInstance) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { + return &exec.ResourceInstanceObject{ + InstanceAddr: addr, + State: &states.ResourceInstanceObjectFull{ + Status: states.ObjectReady, + Value: cty.ObjectVal(map[string]cty.Value{ + "name": cty.StringVal("prior"), + }), + ProviderInstanceAddr: addrs.AbsProviderInstanceCorrect{ + Config: addrs.AbsProviderConfigCorrect{ + Config: addrs.ProviderConfigCorrect{ + Provider: addrs.NewBuiltInProvider("test"), + }, }, }, + ResourceType: addr.Resource.Resource.Type, }, - ResourceType: addr.Resource.Resource.Type, }, nil }, - ManagedFinalPlanFunc: func(ctx context.Context, desired *eval.DesiredResourceInstance, prior *states.ResourceInstanceObjectFull, plannedVal cty.Value, providerClient *exec.ProviderClient) (*exec.ManagedResourceObjectFinalPlan, tfdiags.Diagnostics) { + ManagedFinalPlanFunc: func(ctx context.Context, desired *eval.DesiredResourceInstance, prior *exec.ResourceInstanceObject, plannedVal cty.Value, providerClient *exec.ProviderClient) (*exec.ManagedResourceObjectFinalPlan, tfdiags.Diagnostics) { return &exec.ManagedResourceObjectFinalPlan{ InstanceAddr: desired.Addr, ResourceType: desired.ResourceType, ConfigVal: desired.ConfigVal, - PriorStateVal: prior.Value, + PriorStateVal: prior.State.Value, PlannedVal: plannedVal, }, nil }, - ManagedApplyFunc: func(ctx context.Context, plan *exec.ManagedResourceObjectFinalPlan, fallback *states.ResourceInstanceObjectFull, providerClient *exec.ProviderClient) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { - return &states.ResourceInstanceObjectFull{ - Status: states.ObjectReady, - Value: plan.PlannedVal, - ResourceType: plan.ResourceType, - ProviderInstanceAddr: providerClient.InstanceAddr, + ManagedApplyFunc: func(ctx context.Context, plan *exec.ManagedResourceObjectFinalPlan, fallback *exec.ResourceInstanceObject, providerClient *exec.ProviderClient) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { + return &exec.ResourceInstanceObject{ + InstanceAddr: plan.InstanceAddr, + State: &states.ResourceInstanceObjectFull{ + Status: states.ObjectReady, + Value: plan.PlannedVal, + ResourceType: plan.ResourceType, + ProviderInstanceAddr: providerClient.InstanceAddr, + }, }, nil }, ProviderInstanceConfigFunc: func(ctx context.Context, addr addrs.AbsProviderInstanceCorrect) (*exec.ProviderInstanceConfig, tfdiags.Diagnostics) { @@ -214,14 +220,17 @@ func TestCompiler_resourceInstanceBasics(t *testing.T) { "name": cty.StringVal("prior"), }), }, - (*states.ResourceInstanceObjectFull)(nil), + (*exec.ResourceInstanceObject)(nil), providerInstAddr, }, - Result: &states.ResourceInstanceObjectFull{ - Status: states.ObjectReady, - Value: wantValue, - ProviderInstanceAddr: providerInstAddr, - ResourceType: resourceInstAddr.Resource.Resource.Type, + Result: &exec.ResourceInstanceObject{ + InstanceAddr: resourceInstAddr, + State: &states.ResourceInstanceObjectFull{ + Status: states.ObjectReady, + Value: wantValue, + ProviderInstanceAddr: providerInstAddr, + ResourceType: resourceInstAddr.Resource.Resource.Type, + }, }, }, { @@ -235,19 +244,22 @@ func TestCompiler_resourceInstanceBasics(t *testing.T) { ResourceMode: addrs.ManagedResourceMode, ResourceType: resourceInstAddr.Resource.Resource.Type, }, - &states.ResourceInstanceObjectFull{ - Status: states.ObjectReady, - Value: cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prior"), - }), - ProviderInstanceAddr: addrs.AbsProviderInstanceCorrect{ - Config: addrs.AbsProviderConfigCorrect{ - Config: addrs.ProviderConfigCorrect{ - Provider: addrs.NewBuiltInProvider("test"), + &exec.ResourceInstanceObject{ + InstanceAddr: resourceInstAddr, + State: &states.ResourceInstanceObjectFull{ + Status: states.ObjectReady, + Value: cty.ObjectVal(map[string]cty.Value{ + "name": cty.StringVal("prior"), + }), + ProviderInstanceAddr: addrs.AbsProviderInstanceCorrect{ + Config: addrs.AbsProviderConfigCorrect{ + Config: addrs.ProviderConfigCorrect{ + Provider: addrs.NewBuiltInProvider("test"), + }, }, }, + ResourceType: resourceInstAddr.Resource.Resource.Type, }, - ResourceType: resourceInstAddr.Resource.Resource.Type, }, wantValue, providerInstAddr, @@ -312,19 +324,22 @@ func TestCompiler_resourceInstanceBasics(t *testing.T) { Args: []any{ resourceInstAddr, }, - Result: &states.ResourceInstanceObjectFull{ - Status: states.ObjectReady, - Value: cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prior"), - }), - ProviderInstanceAddr: addrs.AbsProviderInstanceCorrect{ - Config: addrs.AbsProviderConfigCorrect{ - Config: addrs.ProviderConfigCorrect{ - Provider: addrs.NewBuiltInProvider("test"), + Result: &exec.ResourceInstanceObject{ + InstanceAddr: resourceInstAddr, + State: &states.ResourceInstanceObjectFull{ + Status: states.ObjectReady, + Value: cty.ObjectVal(map[string]cty.Value{ + "name": cty.StringVal("prior"), + }), + ProviderInstanceAddr: addrs.AbsProviderInstanceCorrect{ + Config: addrs.AbsProviderConfigCorrect{ + Config: addrs.ProviderConfigCorrect{ + Provider: addrs.NewBuiltInProvider("test"), + }, }, }, + ResourceType: resourceInstAddr.Resource.Resource.Type, }, - ResourceType: resourceInstAddr.Resource.Resource.Type, }, }, } diff --git a/internal/engine/internal/execgraph/graph.go b/internal/engine/internal/execgraph/graph.go index a865d5eb2d..0842d26213 100644 --- a/internal/engine/internal/execgraph/graph.go +++ b/internal/engine/internal/execgraph/graph.go @@ -15,7 +15,6 @@ import ( "github.com/zclconf/go-cty/cty" "github.com/opentofu/opentofu/internal/addrs" - "github.com/opentofu/opentofu/internal/states" ) type Graph struct { @@ -79,7 +78,7 @@ type Graph struct { // operation for each resource instance should also directly depend on // the results of any resource instances that were identified as // resource-instance-graph dependencies during the planning process. - resourceInstanceResults addrs.Map[addrs.AbsResourceInstance, ResultRef[*states.ResourceInstanceObjectFull]] + resourceInstanceResults addrs.Map[addrs.AbsResourceInstance, ResourceInstanceResultRef] } // DebugRepr returns a relatively-concise string representation of the diff --git a/internal/engine/internal/execgraph/graph_marshal.go b/internal/engine/internal/execgraph/graph_marshal.go index ea755811af..6036e75d40 100644 --- a/internal/engine/internal/execgraph/graph_marshal.go +++ b/internal/engine/internal/execgraph/graph_marshal.go @@ -14,7 +14,6 @@ import ( "github.com/opentofu/opentofu/internal/addrs" "github.com/opentofu/opentofu/internal/engine/internal/execgraph/execgraphproto" - "github.com/opentofu/opentofu/internal/states" ) // Marshal produces an opaque byte slice representing the given graph, @@ -63,7 +62,7 @@ func (m *graphMarshaler) EnsureOperationPresent(idx int) uint64 { return m.ensureRefTarget(erasedRef) } -func (m *graphMarshaler) EnsureResourceInstanceResultsPresent(results addrs.Map[addrs.AbsResourceInstance, ResultRef[*states.ResourceInstanceObjectFull]]) { +func (m *graphMarshaler) EnsureResourceInstanceResultsPresent(results addrs.Map[addrs.AbsResourceInstance, ResourceInstanceResultRef]) { m.resourceInstanceResults = make(map[string]uint64) for _, mapElem := range results.Elems { instAddr := mapElem.Key diff --git a/internal/engine/internal/execgraph/graph_test.go b/internal/engine/internal/execgraph/graph_test.go index 0bfeb9a110..d724ecd3f9 100644 --- a/internal/engine/internal/execgraph/graph_test.go +++ b/internal/engine/internal/execgraph/graph_test.go @@ -17,8 +17,8 @@ import ( "google.golang.org/protobuf/proto" "github.com/opentofu/opentofu/internal/addrs" + "github.com/opentofu/opentofu/internal/engine/internal/exec" "github.com/opentofu/opentofu/internal/engine/internal/execgraph/execgraphproto" - "github.com/opentofu/opentofu/internal/states" ) func TestGraphMarshalUnmarshalValid(t *testing.T) { @@ -84,7 +84,7 @@ func TestGraphMarshalUnmarshalValid(t *testing.T) { nil, ) finalPlan := builder.ManagedFinalPlan(desiredInst, priorState, plannedVal, providerClient) - newState := builder.ManagedApply(finalPlan, NilResultRef[*states.ResourceInstanceObjectFull](), providerClient) + newState := builder.ManagedApply(finalPlan, NilResultRef[*exec.ResourceInstanceObject](), providerClient) registerUser(newState) builder.SetResourceInstanceFinalStateResult(instAddr, newState) return builder.Finish() diff --git a/internal/engine/internal/execgraph/graph_unmarshal.go b/internal/engine/internal/execgraph/graph_unmarshal.go index 8ae2d3b823..4c204acfc8 100644 --- a/internal/engine/internal/execgraph/graph_unmarshal.go +++ b/internal/engine/internal/execgraph/graph_unmarshal.go @@ -17,7 +17,6 @@ import ( "github.com/opentofu/opentofu/internal/engine/internal/exec" "github.com/opentofu/opentofu/internal/engine/internal/execgraph/execgraphproto" "github.com/opentofu/opentofu/internal/lang/eval" - "github.com/opentofu/opentofu/internal/states" ) // UnmarshalGraph takes some bytes previously returned by [Graph.Marshal] and @@ -102,7 +101,7 @@ func UnmarshalGraph(src []byte) (*Graph, error) { if diags.HasErrors() { return nil, fmt.Errorf("invalid resource instance address %q: %w", instAddrStr, diags.Err()) } - resultRef, err := unmarshalGetPrevResultOf[*states.ResourceInstanceObjectFull](results, resultIdx) + resultRef, err := unmarshalGetPrevResultOf[*exec.ResourceInstanceObject](results, resultIdx) if err != nil { return nil, fmt.Errorf("invalid result element for %s: %w", instAddr, err) } @@ -221,7 +220,7 @@ func unmarshalOpManagedFinalPlan(rawOperands []uint64, prevResults []AnyResultRe if err != nil { return nil, fmt.Errorf("invalid opManagedFinalPlan desiredInst: %w", err) } - priorState, err := unmarshalGetPrevResultOf[*states.ResourceInstanceObjectFull](prevResults, rawOperands[1]) + priorState, err := unmarshalGetPrevResultOf[*exec.ResourceInstanceObject](prevResults, rawOperands[1]) if err != nil { return nil, fmt.Errorf("invalid opManagedFinalPlan priorState: %w", err) } @@ -244,7 +243,7 @@ func unmarshalOpManagedApply(rawOperands []uint64, prevResults []AnyResultRef, b if err != nil { return nil, fmt.Errorf("invalid opManagedApplyChanges finalPlan: %w", err) } - fallbackObj, err := unmarshalGetPrevResultOf[*states.ResourceInstanceObjectFull](prevResults, rawOperands[1]) + fallbackObj, err := unmarshalGetPrevResultOf[*exec.ResourceInstanceObject](prevResults, rawOperands[1]) if err != nil { return nil, fmt.Errorf("invalid opManagedApplyChanges fallbackObj: %w", err) } @@ -315,7 +314,7 @@ func unmarshalOpEphemeralClose(rawOperands []uint64, prevResults []AnyResultRef, if len(rawOperands) != 3 { return nil, fmt.Errorf("wrong number of operands (%d) for opDataRead", len(rawOperands)) } - obj, err := unmarshalGetPrevResultOf[*states.ResourceInstanceObjectFull](prevResults, rawOperands[0]) + obj, err := unmarshalGetPrevResultOf[*exec.ResourceInstanceObject](prevResults, rawOperands[0]) if err != nil { return nil, fmt.Errorf("invalid opDataRead desiredInst: %w", err) } diff --git a/internal/engine/internal/execgraph/operations_test.go b/internal/engine/internal/execgraph/operations_test.go index e15b8af431..d37b64e0c4 100644 --- a/internal/engine/internal/execgraph/operations_test.go +++ b/internal/engine/internal/execgraph/operations_test.go @@ -22,19 +22,19 @@ import ( type mockOperations struct { Calls []mockOperationsCall - DataReadFunc func(ctx context.Context, desired *eval.DesiredResourceInstance, plannedVal cty.Value, providerClient *exec.ProviderClient) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) - EphemeralCloseFunc func(ctx context.Context, object *states.ResourceInstanceObjectFull, providerClient *exec.ProviderClient) tfdiags.Diagnostics - EphemeralOpenFunc func(ctx context.Context, desired *eval.DesiredResourceInstance, providerClient *exec.ProviderClient) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) - ManagedAlreadyDeposedFunc func(ctx context.Context, instAddr addrs.AbsResourceInstance, deposedKey states.DeposedKey) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) - ManagedApplyFunc func(ctx context.Context, plan *exec.ManagedResourceObjectFinalPlan, fallback *states.ResourceInstanceObjectFull, providerClient *exec.ProviderClient) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) - ManagedDeposeFunc func(ctx context.Context, instAddr addrs.AbsResourceInstance) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) - ManagedFinalPlanFunc func(ctx context.Context, desired *eval.DesiredResourceInstance, prior *states.ResourceInstanceObjectFull, plannedVal cty.Value, providerClient *exec.ProviderClient) (*exec.ManagedResourceObjectFinalPlan, tfdiags.Diagnostics) + DataReadFunc func(ctx context.Context, desired *eval.DesiredResourceInstance, plannedVal cty.Value, providerClient *exec.ProviderClient) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) + EphemeralCloseFunc func(ctx context.Context, object *exec.ResourceInstanceObject, providerClient *exec.ProviderClient) tfdiags.Diagnostics + EphemeralOpenFunc func(ctx context.Context, desired *eval.DesiredResourceInstance, providerClient *exec.ProviderClient) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) + ManagedAlreadyDeposedFunc func(ctx context.Context, instAddr addrs.AbsResourceInstance, deposedKey states.DeposedKey) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) + ManagedApplyFunc func(ctx context.Context, plan *exec.ManagedResourceObjectFinalPlan, fallback *exec.ResourceInstanceObject, providerClient *exec.ProviderClient) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) + ManagedDeposeFunc func(ctx context.Context, instAddr addrs.AbsResourceInstance) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) + ManagedFinalPlanFunc func(ctx context.Context, desired *eval.DesiredResourceInstance, prior *exec.ResourceInstanceObject, plannedVal cty.Value, providerClient *exec.ProviderClient) (*exec.ManagedResourceObjectFinalPlan, tfdiags.Diagnostics) ProviderInstanceCloseFunc func(ctx context.Context, client *exec.ProviderClient) tfdiags.Diagnostics ProviderInstanceConfigFunc func(ctx context.Context, instAddr addrs.AbsProviderInstanceCorrect) (*exec.ProviderInstanceConfig, tfdiags.Diagnostics) ProviderInstanceOpenFunc func(ctx context.Context, config *exec.ProviderInstanceConfig) (*exec.ProviderClient, tfdiags.Diagnostics) ResourceInstanceDesiredFunc func(ctx context.Context, instAddr addrs.AbsResourceInstance) (*eval.DesiredResourceInstance, tfdiags.Diagnostics) - ResourceInstancePostconditionsFunc func(ctx context.Context, result *states.ResourceInstanceObjectFull) tfdiags.Diagnostics - ResourceInstancePriorFunc func(ctx context.Context, instAddr addrs.AbsResourceInstance) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) + ResourceInstancePostconditionsFunc func(ctx context.Context, result *exec.ResourceInstanceObject) tfdiags.Diagnostics + ResourceInstancePriorFunc func(ctx context.Context, instAddr addrs.AbsResourceInstance) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) mu sync.Mutex } @@ -42,9 +42,9 @@ type mockOperations struct { var _ exec.Operations = (*mockOperations)(nil) // DataRead implements [exec.Operations]. -func (m *mockOperations) DataRead(ctx context.Context, desired *eval.DesiredResourceInstance, plannedVal cty.Value, providerClient *exec.ProviderClient) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +func (m *mockOperations) DataRead(ctx context.Context, desired *eval.DesiredResourceInstance, plannedVal cty.Value, providerClient *exec.ProviderClient) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics - var result *states.ResourceInstanceObjectFull + var result *exec.ResourceInstanceObject if m.DataReadFunc != nil { result, diags = m.DataReadFunc(ctx, desired, plannedVal, providerClient) } @@ -53,7 +53,7 @@ func (m *mockOperations) DataRead(ctx context.Context, desired *eval.DesiredReso } // EphemeralClose implements [exec.Operations]. -func (m *mockOperations) EphemeralClose(ctx context.Context, object *states.ResourceInstanceObjectFull, providerClient *exec.ProviderClient) tfdiags.Diagnostics { +func (m *mockOperations) EphemeralClose(ctx context.Context, object *exec.ResourceInstanceObject, providerClient *exec.ProviderClient) tfdiags.Diagnostics { var diags tfdiags.Diagnostics if m.EphemeralCloseFunc != nil { diags = m.EphemeralCloseFunc(ctx, object, providerClient) @@ -63,9 +63,9 @@ func (m *mockOperations) EphemeralClose(ctx context.Context, object *states.Reso } // EphemeralOpen implements [exec.Operations]. -func (m *mockOperations) EphemeralOpen(ctx context.Context, desired *eval.DesiredResourceInstance, providerClient *exec.ProviderClient) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +func (m *mockOperations) EphemeralOpen(ctx context.Context, desired *eval.DesiredResourceInstance, providerClient *exec.ProviderClient) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics - var result *states.ResourceInstanceObjectFull + var result *exec.ResourceInstanceObject if m.EphemeralOpenFunc != nil { result, diags = m.EphemeralOpenFunc(ctx, desired, providerClient) } @@ -74,9 +74,9 @@ func (m *mockOperations) EphemeralOpen(ctx context.Context, desired *eval.Desire } // ManagedAlreadyDeposed implements [exec.Operations]. -func (m *mockOperations) ManagedAlreadyDeposed(ctx context.Context, instAddr addrs.AbsResourceInstance, deposedKey states.DeposedKey) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +func (m *mockOperations) ManagedAlreadyDeposed(ctx context.Context, instAddr addrs.AbsResourceInstance, deposedKey states.DeposedKey) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics - var result *states.ResourceInstanceObjectFull + var result *exec.ResourceInstanceObject if m.ManagedAlreadyDeposedFunc != nil { result, diags = m.ManagedAlreadyDeposedFunc(ctx, instAddr, deposedKey) } @@ -85,9 +85,9 @@ func (m *mockOperations) ManagedAlreadyDeposed(ctx context.Context, instAddr add } // ManagedApply implements [exec.Operations]. -func (m *mockOperations) ManagedApply(ctx context.Context, plan *exec.ManagedResourceObjectFinalPlan, fallback *states.ResourceInstanceObjectFull, providerClient *exec.ProviderClient) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +func (m *mockOperations) ManagedApply(ctx context.Context, plan *exec.ManagedResourceObjectFinalPlan, fallback *exec.ResourceInstanceObject, providerClient *exec.ProviderClient) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics - var result *states.ResourceInstanceObjectFull + var result *exec.ResourceInstanceObject if m.ManagedApplyFunc != nil { result, diags = m.ManagedApplyFunc(ctx, plan, fallback, providerClient) } @@ -96,9 +96,9 @@ func (m *mockOperations) ManagedApply(ctx context.Context, plan *exec.ManagedRes } // ManagedDepose implements [exec.Operations]. -func (m *mockOperations) ManagedDepose(ctx context.Context, instAddr addrs.AbsResourceInstance) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +func (m *mockOperations) ManagedDepose(ctx context.Context, instAddr addrs.AbsResourceInstance) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics - var result *states.ResourceInstanceObjectFull + var result *exec.ResourceInstanceObject if m.ManagedDeposeFunc != nil { result, diags = m.ManagedDeposeFunc(ctx, instAddr) } @@ -107,7 +107,7 @@ func (m *mockOperations) ManagedDepose(ctx context.Context, instAddr addrs.AbsRe } // ManagedFinalPlan implements [exec.Operations]. -func (m *mockOperations) ManagedFinalPlan(ctx context.Context, desired *eval.DesiredResourceInstance, prior *states.ResourceInstanceObjectFull, plannedVal cty.Value, providerClient *exec.ProviderClient) (*exec.ManagedResourceObjectFinalPlan, tfdiags.Diagnostics) { +func (m *mockOperations) ManagedFinalPlan(ctx context.Context, desired *eval.DesiredResourceInstance, prior *exec.ResourceInstanceObject, plannedVal cty.Value, providerClient *exec.ProviderClient) (*exec.ManagedResourceObjectFinalPlan, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics var result *exec.ManagedResourceObjectFinalPlan if m.ManagedFinalPlanFunc != nil { @@ -161,7 +161,7 @@ func (m *mockOperations) ResourceInstanceDesired(ctx context.Context, instAddr a } // ResourceInstancePostconditions implements [exec.Operations]. -func (m *mockOperations) ResourceInstancePostconditions(ctx context.Context, result *states.ResourceInstanceObjectFull) tfdiags.Diagnostics { +func (m *mockOperations) ResourceInstancePostconditions(ctx context.Context, result *exec.ResourceInstanceObject) tfdiags.Diagnostics { var diags tfdiags.Diagnostics if m.ResourceInstancePostconditionsFunc != nil { diags = m.ResourceInstancePostconditionsFunc(ctx, result) @@ -171,9 +171,9 @@ func (m *mockOperations) ResourceInstancePostconditions(ctx context.Context, res } // ResourceInstancePrior implements [exec.Operations]. -func (m *mockOperations) ResourceInstancePrior(ctx context.Context, instAddr addrs.AbsResourceInstance) (*states.ResourceInstanceObjectFull, tfdiags.Diagnostics) { +func (m *mockOperations) ResourceInstancePrior(ctx context.Context, instAddr addrs.AbsResourceInstance) (*exec.ResourceInstanceObject, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics - var result *states.ResourceInstanceObjectFull + var result *exec.ResourceInstanceObject if m.ResourceInstancePriorFunc != nil { result, diags = m.ResourceInstancePriorFunc(ctx, instAddr) } diff --git a/internal/engine/internal/execgraph/result.go b/internal/engine/internal/execgraph/result.go index 4cc0e24270..77a7f04c27 100644 --- a/internal/engine/internal/execgraph/result.go +++ b/internal/engine/internal/execgraph/result.go @@ -9,7 +9,7 @@ import ( "github.com/zclconf/go-cty/cty" "github.com/opentofu/opentofu/internal/addrs" - "github.com/opentofu/opentofu/internal/states" + "github.com/opentofu/opentofu/internal/engine/internal/exec" ) // ResultRef represents a result of type T that will be produced by @@ -26,7 +26,7 @@ type ResultRef[T any] interface { // We give this its own name just because this particular result type tends // to be named in function signatures elsewhere in the system and the // simple name is (subjectively) easier to read than the generic name. -type ResourceInstanceResultRef = ResultRef[*states.ResourceInstanceObjectFull] +type ResourceInstanceResultRef = ResultRef[*exec.ResourceInstanceObject] // AnyResultRef is a type-erased [ResultRef], for data // structures that only need to represent the relationships between results diff --git a/internal/engine/planning/plan_managed.go b/internal/engine/planning/plan_managed.go index 426aef191a..ab653f7367 100644 --- a/internal/engine/planning/plan_managed.go +++ b/internal/engine/planning/plan_managed.go @@ -13,6 +13,7 @@ import ( "github.com/zclconf/go-cty/cty" "github.com/opentofu/opentofu/internal/addrs" + "github.com/opentofu/opentofu/internal/engine/internal/exec" "github.com/opentofu/opentofu/internal/engine/internal/execgraph" "github.com/opentofu/opentofu/internal/lang/eval" "github.com/opentofu/opentofu/internal/plans" @@ -279,7 +280,7 @@ func (p *planGlue) planDesiredManagedResourceInstance(ctx context.Context, inst ) finalResultRef := egb.ManagedApply( finalPlanRef, - execgraph.NilResultRef[*states.ResourceInstanceObjectFull](), + execgraph.NilResultRef[*exec.ResourceInstanceObject](), providerClientRef, ) closeProviderAfter(finalResultRef)