core: Don't count scaled-out resources twice in the UI
This fixes a bug with the new refresh graph behaviour where a resource was being counted twice in the UI on part of being scaled out: * We are no longer transforming refresh nodes without state to plannable resources (the transformer will be removed shortly) * A Quiet flag has been added to EvalDiff and InstanceDiff - this allows for the flagging of a diff that should not be treated as real diff for purposes of planning * When there is no state for a refresh node now, a new path is taken that is similar to plan, but flags Quiet, and does nothing with the diff afterwards. Tests pending - light testing has confirmed this should fix the double count issue, but we should have some tests to actually confirm the bug.
This commit is contained in:
parent
afe891a80e
commit
eef933f2a7
|
@ -100,6 +100,11 @@ func (h *CountHook) PostDiff(
|
|||
return terraform.HookActionContinue, nil
|
||||
}
|
||||
|
||||
// Don't count anything for a Quiet diff
|
||||
if d.Quiet {
|
||||
return terraform.HookActionContinue, nil
|
||||
}
|
||||
|
||||
switch d.ChangeType() {
|
||||
case terraform.DiffDestroyCreate:
|
||||
h.ToRemoveAndAdd += 1
|
||||
|
|
|
@ -373,6 +373,11 @@ type InstanceDiff struct {
|
|||
// mean to be used for additional data a resource may want to pass through.
|
||||
// The value here must only contain Go primitives and collections.
|
||||
Meta map[string]interface{}
|
||||
|
||||
// Quiet should be set when this diff exists only for purposes of providing a
|
||||
// diff to various pre-plan or dry-run steps in the graph. A diff with this
|
||||
// enabled should not be acted on in the plan.
|
||||
Quiet bool
|
||||
}
|
||||
|
||||
func (d *InstanceDiff) Lock() { d.mu.Lock() }
|
||||
|
|
|
@ -81,6 +81,11 @@ type EvalDiff struct {
|
|||
// Resource is needed to fetch the ignore_changes list so we can
|
||||
// filter user-requested ignored attributes from the diff.
|
||||
Resource *config.Resource
|
||||
|
||||
// Quiet is used to indicate that this count should not be used in the UI.
|
||||
// This is used with refresh nodes on scale-out so that resources do not get
|
||||
// counted twice in the UI output.
|
||||
Quiet bool
|
||||
}
|
||||
|
||||
// TODO: test
|
||||
|
@ -157,6 +162,9 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Flag quiet to ensure that this resource is skipped in post-diff hooks, such as count, etc.
|
||||
diff.Quiet = n.Quiet
|
||||
|
||||
// Call post-refresh hook
|
||||
err = ctx.Hook(func(h Hook) (HookAction, error) {
|
||||
return h.PostDiff(n.Info, diff)
|
||||
|
@ -165,8 +173,10 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Update our output
|
||||
*n.OutputDiff = diff
|
||||
// Update our output if we care
|
||||
if n.OutputDiff != nil {
|
||||
*n.OutputDiff = diff
|
||||
}
|
||||
|
||||
// Update the state if we care
|
||||
if n.OutputState != nil {
|
||||
|
|
|
@ -45,13 +45,6 @@ func (n *NodeRefreshableManagedResource) DynamicExpand(ctx EvalContext) (*Graph,
|
|||
Addr: n.ResourceAddr(),
|
||||
},
|
||||
|
||||
// Switch up any node missing state to a plannable resource. This helps
|
||||
// catch cases where data sources depend on the counts from this resource
|
||||
// during a scale out.
|
||||
&ResourceRefreshPlannableTransformer{
|
||||
State: state,
|
||||
},
|
||||
|
||||
// Add the count orphans to make sure these resources are accounted for
|
||||
// during a scale in.
|
||||
&OrphanResourceCountTransformer{
|
||||
|
@ -100,6 +93,9 @@ func (n *NodeRefreshableManagedResourceInstance) EvalTree() EvalNode {
|
|||
// Eval info is different depending on what kind of resource this is
|
||||
switch mode := n.Addr.Mode; mode {
|
||||
case config.ManagedResourceMode:
|
||||
if n.ResourceState == nil {
|
||||
return n.evalTreeManagedScaleInResource()
|
||||
}
|
||||
return n.evalTreeManagedResource()
|
||||
|
||||
case config.DataResourceMode:
|
||||
|
@ -176,3 +172,77 @@ func (n *NodeRefreshableManagedResourceInstance) evalTreeManagedResource() EvalN
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (n *NodeRefreshableManagedResourceInstance) evalTreeManagedScaleInResource() EvalNode {
|
||||
// Declare a bunch of variables that are used for state during
|
||||
// evaluation. Most of this are written to by-address below.
|
||||
var provider ResourceProvider
|
||||
var state *InstanceState
|
||||
var resourceConfig *ResourceConfig
|
||||
|
||||
addr := n.NodeAbstractResource.Addr
|
||||
stateID := addr.stateId()
|
||||
info := &InstanceInfo{
|
||||
Id: stateID,
|
||||
Type: addr.Type,
|
||||
ModulePath: normalizeModulePath(addr.Path),
|
||||
}
|
||||
|
||||
// Build the resource for eval
|
||||
resource := &Resource{
|
||||
Name: addr.Name,
|
||||
Type: addr.Type,
|
||||
CountIndex: addr.Index,
|
||||
}
|
||||
if resource.CountIndex < 0 {
|
||||
resource.CountIndex = 0
|
||||
}
|
||||
|
||||
// Determine the dependencies for the state.
|
||||
stateDeps := n.StateReferences()
|
||||
|
||||
return &EvalSequence{
|
||||
Nodes: []EvalNode{
|
||||
&EvalInterpolate{
|
||||
Config: n.Config.RawConfig.Copy(),
|
||||
Resource: resource,
|
||||
Output: &resourceConfig,
|
||||
},
|
||||
&EvalGetProvider{
|
||||
Name: n.ProvidedBy()[0],
|
||||
Output: &provider,
|
||||
},
|
||||
// Re-run validation to catch any errors we missed, e.g. type
|
||||
// mismatches on computed values.
|
||||
&EvalValidateResource{
|
||||
Provider: &provider,
|
||||
Config: &resourceConfig,
|
||||
ResourceName: n.Config.Name,
|
||||
ResourceType: n.Config.Type,
|
||||
ResourceMode: n.Config.Mode,
|
||||
IgnoreWarnings: true,
|
||||
},
|
||||
&EvalReadState{
|
||||
Name: stateID,
|
||||
Output: &state,
|
||||
},
|
||||
&EvalDiff{
|
||||
Name: stateID,
|
||||
Info: info,
|
||||
Config: &resourceConfig,
|
||||
Resource: n.Config,
|
||||
Provider: &provider,
|
||||
State: &state,
|
||||
OutputState: &state,
|
||||
Quiet: true,
|
||||
},
|
||||
&EvalWriteState{
|
||||
Name: stateID,
|
||||
ResourceType: n.Config.Type,
|
||||
Provider: n.Config.Provider,
|
||||
Dependencies: stateDeps,
|
||||
State: &state,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue