core: Re-implement EvalReadDiff for the new plan types
This also includes passing in the provider schema to a few more EvalNodes that were expecting it but not getting it, in order to be able to successfully test the implementation of EvalReadDiff here.
This commit is contained in:
parent
03e6771536
commit
3d86dc51e0
|
@ -1,7 +1,11 @@
|
||||||
package plans
|
package plans
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/addrs"
|
||||||
|
"github.com/hashicorp/terraform/states"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ChangesSync is a wrapper around a Changes that provides a concurrency-safe
|
// ChangesSync is a wrapper around a Changes that provides a concurrency-safe
|
||||||
|
@ -33,3 +37,27 @@ func (cs *ChangesSync) AppendResourceInstanceChange(changeSrc *ResourceInstanceC
|
||||||
s := changeSrc.DeepCopy()
|
s := changeSrc.DeepCopy()
|
||||||
cs.changes.Resources = append(cs.changes.Resources, s)
|
cs.changes.Resources = append(cs.changes.Resources, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetResourceInstanceChange searches the set of resource instance changes for
|
||||||
|
// one matching the given address and generation, returning it if it exists.
|
||||||
|
//
|
||||||
|
// If no such change exists, nil is returned.
|
||||||
|
//
|
||||||
|
// The returned object is a deep copy of the change recorded in the plan, so
|
||||||
|
// callers may mutate it although it's generally better (less confusing) to
|
||||||
|
// treat planned changes as immutable after they've been initially constructed.
|
||||||
|
func (cs *ChangesSync) GetResourceInstanceChange(addr addrs.AbsResourceInstance, gen states.Generation) *ResourceInstanceChangeSrc {
|
||||||
|
if cs == nil {
|
||||||
|
panic("GetResourceInstanceChange on nil ChangesSync")
|
||||||
|
}
|
||||||
|
cs.lock.Lock()
|
||||||
|
defer cs.lock.Unlock()
|
||||||
|
|
||||||
|
if gen == states.CurrentGen {
|
||||||
|
return cs.changes.ResourceInstance(addr)
|
||||||
|
}
|
||||||
|
if dk, ok := gen.(states.DeposedKey); ok {
|
||||||
|
return cs.changes.ResourceInstanceDeposed(addr, dk)
|
||||||
|
}
|
||||||
|
panic(fmt.Sprintf("unsupported generation value %#v", gen))
|
||||||
|
}
|
||||||
|
|
|
@ -705,28 +705,42 @@ func (n *EvalDiffDestroyModule) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
type EvalReadDiff struct {
|
type EvalReadDiff struct {
|
||||||
Addr addrs.ResourceInstance
|
Addr addrs.ResourceInstance
|
||||||
DeposedKey states.DeposedKey
|
DeposedKey states.DeposedKey
|
||||||
|
ProviderSchema **ProviderSchema
|
||||||
Change **plans.ResourceInstanceChange
|
Change **plans.ResourceInstanceChange
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *EvalReadDiff) Eval(ctx EvalContext) (interface{}, error) {
|
func (n *EvalReadDiff) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
return nil, fmt.Errorf("EvalReadDiff not yet updated for new plan types")
|
providerSchema := *n.ProviderSchema
|
||||||
/*
|
changes := ctx.Changes()
|
||||||
diff, lock := ctx.Diff()
|
addr := n.Addr.Absolute(ctx.Path())
|
||||||
|
|
||||||
// Acquire the lock so that we can do this safely concurrently
|
schema := providerSchema.ResourceTypes[n.Addr.Resource.Type]
|
||||||
lock.Lock()
|
if schema == nil {
|
||||||
defer lock.Unlock()
|
// Should be caught during validation, so we don't bother with a pretty error here
|
||||||
|
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
||||||
|
}
|
||||||
|
|
||||||
// Write the diff
|
gen := states.CurrentGen
|
||||||
modDiff := diff.ModuleByPath(ctx.Path())
|
if n.DeposedKey != states.NotDeposed {
|
||||||
if modDiff == nil {
|
gen = n.DeposedKey
|
||||||
|
}
|
||||||
|
csrc := changes.GetResourceInstanceChange(addr, gen)
|
||||||
|
if csrc == nil {
|
||||||
|
log.Printf("[TRACE] EvalReadDiff: No planned change recorded for %s", addr)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
*n.Diff = modDiff.Resources[n.Name]
|
change, err := csrc.Decode(schema.ImpliedType())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode planned changes for %s: %s", addr, err)
|
||||||
|
}
|
||||||
|
if n.Change != nil {
|
||||||
|
*n.Change = change
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[TRACE] EvalReadDiff: Read %s change from plan for %s", change.Action, addr)
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EvalWriteDiff is an EvalNode implementation that saves a planned change
|
// EvalWriteDiff is an EvalNode implementation that saves a planned change
|
||||||
|
@ -742,6 +756,7 @@ type EvalWriteDiff struct {
|
||||||
func (n *EvalWriteDiff) Eval(ctx EvalContext) (interface{}, error) {
|
func (n *EvalWriteDiff) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
providerSchema := *n.ProviderSchema
|
providerSchema := *n.ProviderSchema
|
||||||
change := *n.Change
|
change := *n.Change
|
||||||
|
addr := n.Addr.Absolute(ctx.Path())
|
||||||
|
|
||||||
if change.Addr.String() != n.Addr.String() || change.DeposedKey != n.DeposedKey {
|
if change.Addr.String() != n.Addr.String() || change.DeposedKey != n.DeposedKey {
|
||||||
// Should never happen, and indicates a bug in the caller.
|
// Should never happen, and indicates a bug in the caller.
|
||||||
|
@ -756,15 +771,15 @@ func (n *EvalWriteDiff) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
|
|
||||||
csrc, err := change.Encode(schema.ImpliedType())
|
csrc, err := change.Encode(schema.ImpliedType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to encode planned changes for %s: %s", n.Addr, err)
|
return nil, fmt.Errorf("failed to encode planned changes for %s: %s", addr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
changes := ctx.Changes()
|
changes := ctx.Changes()
|
||||||
changes.AppendResourceInstanceChange(csrc)
|
changes.AppendResourceInstanceChange(csrc)
|
||||||
if n.DeposedKey == states.NotDeposed {
|
if n.DeposedKey == states.NotDeposed {
|
||||||
log.Printf("[TRACE] EvalWriteDiff: recorded %s change for %s", change.Action, n.Addr)
|
log.Printf("[TRACE] EvalWriteDiff: recorded %s change for %s", change.Action, addr)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[TRACE] EvalWriteDiff: recorded %s change for %s deposed object %s", change.Action, n.Addr, n.DeposedKey)
|
log.Printf("[TRACE] EvalWriteDiff: recorded %s change for %s deposed object %s", change.Action, addr, n.DeposedKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
|
@ -129,9 +129,16 @@ func (n *NodeApplyableResourceInstance) evalTreeDataResource(addr addrs.AbsResou
|
||||||
|
|
||||||
return &EvalSequence{
|
return &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
|
&EvalGetProvider{
|
||||||
|
Addr: n.ResolvedProvider,
|
||||||
|
Output: &provider,
|
||||||
|
Schema: &providerSchema,
|
||||||
|
},
|
||||||
|
|
||||||
// Get the saved diff for apply
|
// Get the saved diff for apply
|
||||||
&EvalReadDiff{
|
&EvalReadDiff{
|
||||||
Addr: addr.Resource,
|
Addr: addr.Resource,
|
||||||
|
ProviderSchema: &providerSchema,
|
||||||
Change: &change,
|
Change: &change,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -146,12 +153,6 @@ func (n *NodeApplyableResourceInstance) evalTreeDataResource(addr addrs.AbsResou
|
||||||
Then: EvalNoop{},
|
Then: EvalNoop{},
|
||||||
},
|
},
|
||||||
|
|
||||||
&EvalGetProvider{
|
|
||||||
Addr: n.ResolvedProvider,
|
|
||||||
Output: &provider,
|
|
||||||
Schema: &providerSchema,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Make a new diff, in case we've learned new values in the state
|
// Make a new diff, in case we've learned new values in the state
|
||||||
// during apply which we can now incorporate.
|
// during apply which we can now incorporate.
|
||||||
&EvalReadDataDiff{
|
&EvalReadDataDiff{
|
||||||
|
@ -206,9 +207,16 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
|
||||||
|
|
||||||
return &EvalSequence{
|
return &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
|
&EvalGetProvider{
|
||||||
|
Addr: n.ResolvedProvider,
|
||||||
|
Output: &provider,
|
||||||
|
Schema: &providerSchema,
|
||||||
|
},
|
||||||
|
|
||||||
// Get the saved diff for apply
|
// Get the saved diff for apply
|
||||||
&EvalReadDiff{
|
&EvalReadDiff{
|
||||||
Addr: addr.Resource,
|
Addr: addr.Resource,
|
||||||
|
ProviderSchema: &providerSchema,
|
||||||
Change: &diffApply,
|
Change: &diffApply,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -244,11 +252,6 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
&EvalGetProvider{
|
|
||||||
Addr: n.ResolvedProvider,
|
|
||||||
Output: &provider,
|
|
||||||
Schema: &providerSchema,
|
|
||||||
},
|
|
||||||
&EvalReadState{
|
&EvalReadState{
|
||||||
Addr: addr.Resource,
|
Addr: addr.Resource,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
|
@ -274,6 +277,7 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
|
||||||
// Get the saved diff
|
// Get the saved diff
|
||||||
&EvalReadDiff{
|
&EvalReadDiff{
|
||||||
Addr: addr.Resource,
|
Addr: addr.Resource,
|
||||||
|
ProviderSchema: &providerSchema,
|
||||||
Change: &diff,
|
Change: &diff,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -281,6 +285,7 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
|
||||||
&EvalCheckPlannedChange{
|
&EvalCheckPlannedChange{
|
||||||
Addr: addr.Resource,
|
Addr: addr.Resource,
|
||||||
ProviderAddr: n.ResolvedProvider,
|
ProviderAddr: n.ResolvedProvider,
|
||||||
|
ProviderSchema: &providerSchema,
|
||||||
Planned: &diff,
|
Planned: &diff,
|
||||||
Actual: &diffApply,
|
Actual: &diffApply,
|
||||||
},
|
},
|
||||||
|
@ -310,6 +315,8 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
|
||||||
State: &state,
|
State: &state,
|
||||||
Change: &diffApply,
|
Change: &diffApply,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
|
ProviderAddr: n.ResolvedProvider,
|
||||||
|
ProviderSchema: &providerSchema,
|
||||||
Output: &state,
|
Output: &state,
|
||||||
Error: &err,
|
Error: &err,
|
||||||
CreateNew: &createNew,
|
CreateNew: &createNew,
|
||||||
|
|
|
@ -176,9 +176,16 @@ func (n *NodeDestroyResourceInstance) EvalTree() EvalNode {
|
||||||
Ops: []walkOperation{walkApply, walkDestroy},
|
Ops: []walkOperation{walkApply, walkDestroy},
|
||||||
Node: &EvalSequence{
|
Node: &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
|
&EvalGetProvider{
|
||||||
|
Addr: n.ResolvedProvider,
|
||||||
|
Output: &provider,
|
||||||
|
Schema: &providerSchema,
|
||||||
|
},
|
||||||
|
|
||||||
// Get the saved diff for apply
|
// Get the saved diff for apply
|
||||||
&EvalReadDiff{
|
&EvalReadDiff{
|
||||||
Addr: addr.Resource,
|
Addr: addr.Resource,
|
||||||
|
ProviderSchema: &providerSchema,
|
||||||
Change: &changeApply,
|
Change: &changeApply,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -196,11 +203,6 @@ func (n *NodeDestroyResourceInstance) EvalTree() EvalNode {
|
||||||
Then: EvalNoop{},
|
Then: EvalNoop{},
|
||||||
},
|
},
|
||||||
|
|
||||||
&EvalGetProvider{
|
|
||||||
Addr: n.ResolvedProvider,
|
|
||||||
Output: &provider,
|
|
||||||
Schema: &providerSchema,
|
|
||||||
},
|
|
||||||
&EvalReadState{
|
&EvalReadState{
|
||||||
Addr: addr.Resource,
|
Addr: addr.Resource,
|
||||||
Output: &state,
|
Output: &state,
|
||||||
|
@ -269,6 +271,8 @@ func (n *NodeDestroyResourceInstance) EvalTree() EvalNode {
|
||||||
State: &state,
|
State: &state,
|
||||||
Change: &changeApply,
|
Change: &changeApply,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
|
ProviderAddr: n.ResolvedProvider,
|
||||||
|
ProviderSchema: &providerSchema,
|
||||||
Output: &state,
|
Output: &state,
|
||||||
Error: &err,
|
Error: &err,
|
||||||
},
|
},
|
||||||
|
|
|
@ -156,6 +156,8 @@ func (n *graphNodeDeposedResource) EvalTree() EvalNode {
|
||||||
State: &state,
|
State: &state,
|
||||||
Change: &change,
|
Change: &change,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
|
ProviderAddr: n.ResolvedProvider,
|
||||||
|
ProviderSchema: &providerSchema,
|
||||||
Output: &state,
|
Output: &state,
|
||||||
Error: &err,
|
Error: &err,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue