diff --git a/internal/engine/internal/execgraph/builder.go b/internal/engine/internal/execgraph/builder.go index a03ec7cc52..977b4c1578 100644 --- a/internal/engine/internal/execgraph/builder.go +++ b/internal/engine/internal/execgraph/builder.go @@ -38,7 +38,7 @@ type Builder struct { // we throw these away after building is complete because the graph // becomes immutable at that point. desiredStateRefs addrs.Map[addrs.AbsResourceInstance, ResultRef[*eval.DesiredResourceInstance]] - priorStateRefs addrs.Map[addrs.AbsResourceInstance, ResultRef[*states.ResourceInstanceObject]] + priorStateRefs addrs.Map[addrs.AbsResourceInstance, ResultRef[*states.ResourceInstanceObjectFull]] providerAddrRefs map[addrs.Provider]ResultRef[addrs.Provider] providerInstConfigRefs addrs.Map[addrs.AbsProviderInstanceCorrect, ResultRef[cty.Value]] openProviderRefs addrs.Map[addrs.AbsProviderInstanceCorrect, resultWithCloseBlockers[providers.Configured]] @@ -48,10 +48,10 @@ type Builder struct { func NewBuilder() *Builder { return &Builder{ graph: &Graph{ - resourceInstanceResults: addrs.MakeMap[addrs.AbsResourceInstance, ResultRef[*states.ResourceInstanceObject]](), + resourceInstanceResults: addrs.MakeMap[addrs.AbsResourceInstance, ResultRef[*states.ResourceInstanceObjectFull]](), }, desiredStateRefs: addrs.MakeMap[addrs.AbsResourceInstance, ResultRef[*eval.DesiredResourceInstance]](), - priorStateRefs: addrs.MakeMap[addrs.AbsResourceInstance, ResultRef[*states.ResourceInstanceObject]](), + priorStateRefs: addrs.MakeMap[addrs.AbsResourceInstance, ResultRef[*states.ResourceInstanceObjectFull]](), providerAddrRefs: make(map[addrs.Provider]ResultRef[addrs.Provider]), providerInstConfigRefs: addrs.MakeMap[addrs.AbsProviderInstanceCorrect, ResultRef[cty.Value]](), openProviderRefs: addrs.MakeMap[addrs.AbsProviderInstanceCorrect, resultWithCloseBlockers[providers.Configured]](), @@ -122,7 +122,7 @@ func (b *Builder) DesiredResourceInstance(addr addrs.AbsResourceInstance) Result // state model, but a real implementation of this might benefit from a slightly // different model tailored to be used in isolation, without the rest of the // state tree it came from. -func (b *Builder) ResourceInstancePriorState(addr addrs.AbsResourceInstance) ResultRef[*states.ResourceInstanceObject] { +func (b *Builder) ResourceInstancePriorState(addr addrs.AbsResourceInstance) ResultRef[*states.ResourceInstanceObjectFull] { b.mu.Lock() defer b.mu.Unlock() @@ -148,7 +148,7 @@ func (b *Builder) ResourceInstancePriorState(addr addrs.AbsResourceInstance) Res // codepath attempting to register the chain of nodes for any deposed object, // and no resource instance should depend on the result of applying changes // to a deposed object. -func (b *Builder) ResourceDeposedObjectState(instAddr addrs.AbsResourceInstance, deposedKey states.DeposedKey) ResultRef[*states.ResourceInstanceObject] { +func (b *Builder) ResourceDeposedObjectState(instAddr addrs.AbsResourceInstance, deposedKey states.DeposedKey) ResultRef[*states.ResourceInstanceObjectFull] { b.mu.Lock() defer b.mu.Unlock() @@ -288,7 +288,7 @@ func (b *Builder) CloseProviderClient(clientResult ResultRef[providers.Configure // resource-instance-graph dependencies have had their changes applied. func (b *Builder) ManagedResourceObjectFinalPlan( desiredInst ResultRef[*eval.DesiredResourceInstance], - priorState ResultRef[*states.ResourceInstanceObject], + priorState ResultRef[*states.ResourceInstanceObjectFull], plannedVal ResultRef[cty.Value], providerClient ResultRef[providers.Configured], waitFor AnyResultRef, @@ -312,11 +312,11 @@ func (b *Builder) ManagedResourceObjectFinalPlan( func (b *Builder) ApplyManagedResourceObjectChanges( finalPlan ResultRef[*ManagedResourceObjectFinalPlan], providerClient ResultRef[providers.Configured], -) ResultRef[*states.ResourceInstanceObject] { +) ResultRef[*states.ResourceInstanceObjectFull] { b.mu.Lock() defer b.mu.Unlock() - return operationRef[*states.ResourceInstanceObject](b, operationDesc{ + return operationRef[*states.ResourceInstanceObjectFull](b, operationDesc{ opCode: opManagedApplyChanges, operands: []AnyResultRef{finalPlan, providerClient}, }) @@ -326,12 +326,12 @@ func (b *Builder) DataRead( desiredInst ResultRef[*eval.DesiredResourceInstance], providerClient ResultRef[providers.Configured], waitFor AnyResultRef, -) ResultRef[*states.ResourceInstanceObject] { +) ResultRef[*states.ResourceInstanceObjectFull] { b.mu.Lock() defer b.mu.Unlock() waiter := b.ensureWaiterRef(waitFor) - return operationRef[*states.ResourceInstanceObject](b, operationDesc{ + return operationRef[*states.ResourceInstanceObjectFull](b, operationDesc{ opCode: opDataRead, operands: []AnyResultRef{desiredInst, providerClient, waiter}, }) @@ -345,7 +345,7 @@ func (b *Builder) DataRead( // Only one call is allowed per distinct [addrs.AbsResourceInstance] value. If // two callers try to register for the same address then the second call will // panic. -func (b *Builder) SetResourceInstanceFinalStateResult(addr addrs.AbsResourceInstance, result ResultRef[*states.ResourceInstanceObject]) { +func (b *Builder) SetResourceInstanceFinalStateResult(addr addrs.AbsResourceInstance, result ResultRef[*states.ResourceInstanceObjectFull]) { b.mu.Lock() defer b.mu.Unlock() diff --git a/internal/engine/internal/execgraph/compiler.go b/internal/engine/internal/execgraph/compiler.go index 6aa4aa8581..4d512bd031 100644 --- a/internal/engine/internal/execgraph/compiler.go +++ b/internal/engine/internal/execgraph/compiler.go @@ -176,7 +176,7 @@ func (c *compiler) Compile() (*CompiledGraph, tfdiags.Diagnostics) { if !ok { return cty.DynamicVal } - finalStateObj := rawResult.(*states.ResourceInstanceObject) + finalStateObj := rawResult.(*states.ResourceInstanceObjectFull) return finalStateObj.Value }) } diff --git a/internal/engine/internal/execgraph/compiler_ops.go b/internal/engine/internal/execgraph/compiler_ops.go index 5857519624..b0bb68a78b 100644 --- a/internal/engine/internal/execgraph/compiler_ops.go +++ b/internal/engine/internal/execgraph/compiler_ops.go @@ -21,7 +21,7 @@ import ( func (c *compiler) compileOpManagedFinalPlan(operands *compilerOperands) nodeExecuteRaw { getDesired := nextOperand[*eval.DesiredResourceInstance](operands) - getPrior := nextOperand[*states.ResourceInstanceObject](operands) + getPrior := nextOperand[*states.ResourceInstanceObjectFull](operands) getInitialPlanned := nextOperand[cty.Value](operands) getProviderClient := nextOperand[providers.Configured](operands) waitForDeps := operands.OperandWaiter() @@ -178,10 +178,15 @@ func (c *compiler) compileOpManagedApplyChanges(operands *compilerOperands) node // directly, which is annoying since it would be nice if that were all // encapsulated away somewhere. - ret := &states.ResourceInstanceObject{ + ret := &states.ResourceInstanceObjectFull{ Value: resp.NewState, Private: resp.Private, Status: states.ObjectReady, + // TODO: ProviderInstanceAddr, which we don't currently have here + // because we're just holding an already-open client for that + // provider. Should we extend [providers.Interface] with a method + // to find which provider instance the client is acting on behalf of? + ResourceType: finalPlan.ResourceType, // TODO: Dependencies ... they come from the "desired" object // so maybe we should send that whole thing over here instead of // just the ConfigVal? diff --git a/internal/engine/internal/execgraph/compiler_test.go b/internal/engine/internal/execgraph/compiler_test.go index a515cedcc7..e4a9298700 100644 --- a/internal/engine/internal/execgraph/compiler_test.go +++ b/internal/engine/internal/execgraph/compiler_test.go @@ -81,12 +81,20 @@ func TestCompiler_resourceInstanceBasics(t *testing.T) { ProviderInstance: &providerInstAddr, } }, - ResourceInstancePriorStateFunc: func(ctx context.Context, addr addrs.AbsResourceInstance, deposedKey states.DeposedKey) *states.ResourceInstanceObject { - return &states.ResourceInstanceObject{ + ResourceInstancePriorStateFunc: func(ctx context.Context, addr addrs.AbsResourceInstance, deposedKey states.DeposedKey) *states.ResourceInstanceObjectFull { + 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"), + }, + }, + }, + ResourceType: addr.Resource.Resource.Type, } }, ProviderInstanceConfigFunc: func(ctx context.Context, addr addrs.AbsProviderInstanceCorrect) cty.Value { @@ -185,11 +193,19 @@ func TestCompiler_resourceInstanceBasics(t *testing.T) { { MethodName: "ResourceInstancePriorState", Args: []any{resourceInstAddr, states.NotDeposed}, - Result: &states.ResourceInstanceObject{ + 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"), + }, + }, + }, + ResourceType: "bar_thing", }, }, { diff --git a/internal/engine/internal/execgraph/exec_context.go b/internal/engine/internal/execgraph/exec_context.go index 7bd9450975..1bb145c40f 100644 --- a/internal/engine/internal/execgraph/exec_context.go +++ b/internal/engine/internal/execgraph/exec_context.go @@ -48,7 +48,7 @@ type ExecContext interface { // the planning engine, because it should only generate requests for // prior state objects that were present and valid in the refreshed state // during the planning step. - ResourceInstancePriorState(ctx context.Context, addr addrs.AbsResourceInstance, deposedKey states.DeposedKey) *states.ResourceInstanceObject + ResourceInstancePriorState(ctx context.Context, addr addrs.AbsResourceInstance, deposedKey states.DeposedKey) *states.ResourceInstanceObjectFull // ProviderInstanceConfig returns the value that should be sent when // configuring the specified provider instance, or [cty.NilVal] if diff --git a/internal/engine/internal/execgraph/exec_context_test.go b/internal/engine/internal/execgraph/exec_context_test.go index ab214ce808..e475931e64 100644 --- a/internal/engine/internal/execgraph/exec_context_test.go +++ b/internal/engine/internal/execgraph/exec_context_test.go @@ -25,7 +25,7 @@ type MockExecContext struct { DesiredResourceInstanceFunc func(ctx context.Context, addr addrs.AbsResourceInstance) *eval.DesiredResourceInstance NewProviderClientFunc func(ctx context.Context, addr addrs.Provider, configVal cty.Value) (providers.Configured, tfdiags.Diagnostics) ProviderInstanceConfigFunc func(ctx context.Context, addr addrs.AbsProviderInstanceCorrect) cty.Value - ResourceInstancePriorStateFunc func(ctx context.Context, addr addrs.AbsResourceInstance, deposedKey states.DeposedKey) *states.ResourceInstanceObject + ResourceInstancePriorStateFunc func(ctx context.Context, addr addrs.AbsResourceInstance, deposedKey states.DeposedKey) *states.ResourceInstanceObjectFull mu sync.Mutex } @@ -64,8 +64,8 @@ func (m *MockExecContext) ProviderInstanceConfig(ctx context.Context, addr addrs } // ResourceInstancePriorState implements ExecContext. -func (m *MockExecContext) ResourceInstancePriorState(ctx context.Context, addr addrs.AbsResourceInstance, deposedKey states.DeposedKey) *states.ResourceInstanceObject { - var result *states.ResourceInstanceObject +func (m *MockExecContext) ResourceInstancePriorState(ctx context.Context, addr addrs.AbsResourceInstance, deposedKey states.DeposedKey) *states.ResourceInstanceObjectFull { + var result *states.ResourceInstanceObjectFull if m.ResourceInstancePriorStateFunc != nil { result = m.ResourceInstancePriorStateFunc(ctx, addr, deposedKey) } diff --git a/internal/engine/internal/execgraph/graph.go b/internal/engine/internal/execgraph/graph.go index c1799bc543..2e864ec3fe 100644 --- a/internal/engine/internal/execgraph/graph.go +++ b/internal/engine/internal/execgraph/graph.go @@ -95,7 +95,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.ResourceInstanceObject]] + resourceInstanceResults addrs.Map[addrs.AbsResourceInstance, ResultRef[*states.ResourceInstanceObjectFull]] } // 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 a48dcb7fef..6289352227 100644 --- a/internal/engine/internal/execgraph/graph_marshal.go +++ b/internal/engine/internal/execgraph/graph_marshal.go @@ -63,7 +63,7 @@ func (m *graphMarshaler) EnsureOperationPresent(idx int) uint64 { return m.ensureRefTarget(erasedRef) } -func (m *graphMarshaler) EnsureResourceInstanceResultsPresent(results addrs.Map[addrs.AbsResourceInstance, ResultRef[*states.ResourceInstanceObject]]) { +func (m *graphMarshaler) EnsureResourceInstanceResultsPresent(results addrs.Map[addrs.AbsResourceInstance, ResultRef[*states.ResourceInstanceObjectFull]]) { m.resourceInstanceResults = make(map[string]uint64) for _, mapElem := range results.Elems { instAddr := mapElem.Key diff --git a/internal/engine/internal/execgraph/graph_unmarshal.go b/internal/engine/internal/execgraph/graph_unmarshal.go index 6d147f9972..ecee171575 100644 --- a/internal/engine/internal/execgraph/graph_unmarshal.go +++ b/internal/engine/internal/execgraph/graph_unmarshal.go @@ -116,7 +116,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.ResourceInstanceObject](results, resultIdx) + resultRef, err := unmarshalGetPrevResultOf[*states.ResourceInstanceObjectFull](results, resultIdx) if err != nil { return nil, fmt.Errorf("invalid result element for %s: %w", instAddr, err) } @@ -156,7 +156,7 @@ func unmarshalOpManagedFinalPlan(rawOperands []uint64, prevResults []AnyResultRe if err != nil { return nil, fmt.Errorf("invalid opManagedFinalPlan desiredInst: %w", err) } - priorState, err := unmarshalGetPrevResultOf[*states.ResourceInstanceObject](prevResults, rawOperands[1]) + priorState, err := unmarshalGetPrevResultOf[*states.ResourceInstanceObjectFull](prevResults, rawOperands[1]) if err != nil { return nil, fmt.Errorf("invalid opManagedFinalPlan priorState: %w", err) } diff --git a/internal/engine/internal/execgraph/result.go b/internal/engine/internal/execgraph/result.go index 0212078ca8..57351acab2 100644 --- a/internal/engine/internal/execgraph/result.go +++ b/internal/engine/internal/execgraph/result.go @@ -75,13 +75,14 @@ type resourceInstancePriorStateResultRef struct { index int } -var _ ResultRef[*states.ResourceInstanceObject] = resourceInstancePriorStateResultRef{} +var _ ResultRef[*states.ResourceInstanceObjectFull] = resourceInstancePriorStateResultRef{} // anyResultPlaceholderSigil implements ResultRef. func (r resourceInstancePriorStateResultRef) anyResultPlaceholderSigil() {} // resultPlaceholderSigil implements ResultRef. -func (r resourceInstancePriorStateResultRef) resultPlaceholderSigil(*states.ResourceInstanceObject) {} +func (r resourceInstancePriorStateResultRef) resultPlaceholderSigil(*states.ResourceInstanceObjectFull) { +} // providerInstanceConfigResultRef is a [ResultRef] referring to an item in a // graph's table of provider instance configuration requests.