simplify EvalMaybeTainted logic

The EvalMaybeTainted logic was confusing, with deep nesting and unneeded
duplicate fields.
This commit is contained in:
James Bardin 2019-11-06 17:23:21 -05:00
parent 4b04e3fa59
commit 84b5de9ae4
2 changed files with 29 additions and 32 deletions

View File

@ -376,40 +376,39 @@ type EvalMaybeTainted struct {
Change **plans.ResourceInstanceChange
State **states.ResourceInstanceObject
Error *error
// If StateOutput is not nil, its referent will be assigned either the same
// pointer as State or a new object with its status set as Tainted,
// depending on whether an error is given and if this was a create action.
StateOutput **states.ResourceInstanceObject
}
// TODO: test
func (n *EvalMaybeTainted) Eval(ctx EvalContext) (interface{}, error) {
if n.State == nil || n.Change == nil || n.Error == nil {
return nil, nil
}
state := *n.State
change := *n.Change
err := *n.Error
// nothing to do if everything went as planned
if err == nil {
return nil, nil
}
if state != nil && state.Status == states.ObjectTainted {
log.Printf("[TRACE] EvalMaybeTainted: %s was already tainted, so nothing to do", n.Addr.Absolute(ctx.Path()))
return nil, nil
}
if n.StateOutput != nil {
if err != nil && change.Action == plans.Create {
// If there are errors during a _create_ then the object is
// in an undefined state, and so we'll mark it as tainted so
// we can try again on the next run.
//
// We don't do this for other change actions because errors
// during updates will often not change the remote object at all.
// If there _were_ changes prior to the error, it's the provider's
// responsibility to record the effect of those changes in the
// object value it returned.
log.Printf("[TRACE] EvalMaybeTainted: %s encountered an error during creation, so it is now marked as tainted", n.Addr.Absolute(ctx.Path()))
*n.StateOutput = state.AsTainted()
} else {
*n.StateOutput = state
}
if change.Action == plans.Create {
// If there are errors during a _create_ then the object is
// in an undefined state, and so we'll mark it as tainted so
// we can try again on the next run.
//
// We don't do this for other change actions because errors
// during updates will often not change the remote object at all.
// If there _were_ changes prior to the error, it's the provider's
// responsibility to record the effect of those changes in the
// object value it returned.
log.Printf("[TRACE] EvalMaybeTainted: %s encountered an error during creation, so it is now marked as tainted", n.Addr.Absolute(ctx.Path()))
*n.State = state.AsTainted()
}
return nil, nil

View File

@ -356,11 +356,10 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
CreateNew: &createNew,
},
&EvalMaybeTainted{
Addr: addr.Resource,
State: &state,
Change: &diffApply,
Error: &err,
StateOutput: &state,
Addr: addr.Resource,
State: &state,
Change: &diffApply,
Error: &err,
},
&EvalWriteState{
Addr: addr.Resource,
@ -378,11 +377,10 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
When: configs.ProvisionerWhenCreate,
},
&EvalMaybeTainted{
Addr: addr.Resource,
State: &state,
Change: &diffApply,
Error: &err,
StateOutput: &state,
Addr: addr.Resource,
State: &state,
Change: &diffApply,
Error: &err,
},
&EvalWriteState{
Addr: addr.Resource,