add a way to selectively write to RefreshState

All resources use EvalWriteState to store their state, so we need a way
to switch the states when the resource is refreshing vs when it is
planning. (this will likely change once we factor out the EvalNode pattern)
This commit is contained in:
James Bardin 2020-09-04 15:59:44 -04:00
parent ad22e137e6
commit 7b178b1788
2 changed files with 31 additions and 11 deletions

View File

@ -13,6 +13,13 @@ import (
"github.com/hashicorp/terraform/tfdiags" "github.com/hashicorp/terraform/tfdiags"
) )
type phaseState int
const (
workingState phaseState = iota
refreshState
)
// EvalReadState is an EvalNode implementation that reads the // EvalReadState is an EvalNode implementation that reads the
// current object for a specific instance in the state. // current object for a specific instance in the state.
type EvalReadState struct { type EvalReadState struct {
@ -220,6 +227,10 @@ type EvalWriteState struct {
// Dependencies are the inter-resource dependencies to be stored in the // Dependencies are the inter-resource dependencies to be stored in the
// state. // state.
Dependencies *[]addrs.ConfigResource Dependencies *[]addrs.ConfigResource
// targetState determines which context state we're writing to during plan.
// The default is the global working state.
targetState phaseState
} }
func (n *EvalWriteState) Eval(ctx EvalContext) (interface{}, error) { func (n *EvalWriteState) Eval(ctx EvalContext) (interface{}, error) {
@ -230,7 +241,15 @@ func (n *EvalWriteState) Eval(ctx EvalContext) (interface{}, error) {
} }
absAddr := n.Addr.Absolute(ctx.Path()) absAddr := n.Addr.Absolute(ctx.Path())
state := ctx.State()
var state *states.SyncState
switch n.targetState {
case refreshState:
log.Printf("[TRACE] EvalWriteState: using RefreshState for %s", absAddr)
state = ctx.RefreshState()
default:
state = ctx.State()
}
if n.ProviderAddr.Provider.Type == "" { if n.ProviderAddr.Provider.Type == "" {
return nil, fmt.Errorf("failed to write state for %s: missing provider type", absAddr) return nil, fmt.Errorf("failed to write state for %s: missing provider type", absAddr)

View File

@ -107,8 +107,8 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
var provider providers.Interface var provider providers.Interface
var providerSchema *ProviderSchema var providerSchema *ProviderSchema
var change *plans.ResourceInstanceChange var change *plans.ResourceInstanceChange
var refreshState *states.ResourceInstanceObject var instanceRefreshState *states.ResourceInstanceObject
var planState *states.ResourceInstanceObject var instancePlanState *states.ResourceInstanceObject
return &EvalSequence{ return &EvalSequence{
Nodes: []EvalNode{ Nodes: []EvalNode{
@ -129,10 +129,10 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
Addr: addr.Resource, Addr: addr.Resource,
Provider: &provider, Provider: &provider,
ProviderSchema: &providerSchema, ProviderSchema: &providerSchema,
Output: &refreshState, Output: &instanceRefreshState,
}, },
&EvalRefreshDependencies{ &EvalRefreshDependencies{
State: &refreshState, State: &instanceRefreshState,
Dependencies: &n.Dependencies, Dependencies: &n.Dependencies,
}, },
&EvalRefresh{ &EvalRefresh{
@ -141,14 +141,15 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
Provider: &provider, Provider: &provider,
ProviderMetas: n.ProviderMetas, ProviderMetas: n.ProviderMetas,
ProviderSchema: &providerSchema, ProviderSchema: &providerSchema,
State: &refreshState, State: &instanceRefreshState,
Output: &refreshState, Output: &instanceRefreshState,
}, },
&EvalWriteState{ &EvalWriteState{
Addr: addr.Resource, Addr: addr.Resource,
ProviderAddr: n.ResolvedProvider, ProviderAddr: n.ResolvedProvider,
State: &refreshState, State: &instanceRefreshState,
ProviderSchema: &providerSchema, ProviderSchema: &providerSchema,
targetState: refreshState,
}, },
// Plan the instance // Plan the instance
@ -160,9 +161,9 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
ProviderAddr: n.ResolvedProvider, ProviderAddr: n.ResolvedProvider,
ProviderMetas: n.ProviderMetas, ProviderMetas: n.ProviderMetas,
ProviderSchema: &providerSchema, ProviderSchema: &providerSchema,
State: &refreshState, State: &instanceRefreshState,
OutputChange: &change, OutputChange: &change,
OutputState: &planState, OutputState: &instancePlanState,
}, },
&EvalCheckPreventDestroy{ &EvalCheckPreventDestroy{
Addr: addr.Resource, Addr: addr.Resource,
@ -172,7 +173,7 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
&EvalWriteState{ &EvalWriteState{
Addr: addr.Resource, Addr: addr.Resource,
ProviderAddr: n.ResolvedProvider, ProviderAddr: n.ResolvedProvider,
State: &planState, State: &instancePlanState,
ProviderSchema: &providerSchema, ProviderSchema: &providerSchema,
}, },
&EvalWriteDiff{ &EvalWriteDiff{