core: Make an instances.Expander available to every graph walk

This is not used yet, but in future commits will be used as a
"blackboard" to centrally aggregate the information pertaining to
expansion of resources and modules (using "count" or "for_each") to help
ensure consistent treatment of the expansion process during a graph walk.

In practice this only really makes sense for the plan walk, because the
apply walk doesn't do any dynamic expansion.
This commit is contained in:
Martin Atkins 2019-11-21 16:21:41 -08:00
parent 1dece66b10
commit 8ea78dfe7d
4 changed files with 48 additions and 28 deletions

View File

@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs"
"github.com/hashicorp/terraform/instances"
"github.com/hashicorp/terraform/lang"
"github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/providers"
@ -788,6 +789,7 @@ func (c *Context) graphWalker(operation walkOperation) *ContextGraphWalker {
Context: c,
State: c.state.SyncWrapper(),
Changes: c.changes.SyncWrapper(),
InstanceExpander: instances.NewExpander(),
Operation: operation,
StopContext: c.runContext,
RootVariableValues: c.variables,

View File

@ -6,6 +6,7 @@ import (
"log"
"sync"
"github.com/hashicorp/terraform/instances"
"github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/provisioners"
@ -53,16 +54,17 @@ type BuiltinEvalContext struct {
VariableValues map[string]map[string]cty.Value
VariableValuesLock *sync.Mutex
Components contextComponentFactory
Hooks []Hook
InputValue UIInput
ProviderCache map[string]providers.Interface
ProviderInputConfig map[string]map[string]cty.Value
ProviderLock *sync.Mutex
ProvisionerCache map[string]provisioners.Interface
ProvisionerLock *sync.Mutex
ChangesValue *plans.ChangesSync
StateValue *states.SyncState
Components contextComponentFactory
Hooks []Hook
InputValue UIInput
ProviderCache map[string]providers.Interface
ProviderInputConfig map[string]map[string]cty.Value
ProviderLock *sync.Mutex
ProvisionerCache map[string]provisioners.Interface
ProvisionerLock *sync.Mutex
ChangesValue *plans.ChangesSync
StateValue *states.SyncState
InstanceExpanderValue *instances.Expander
once sync.Once
}
@ -359,5 +361,9 @@ func (ctx *BuiltinEvalContext) State() *states.SyncState {
return ctx.StateValue
}
func (ctx *BuiltinEvalContext) InstanceExpander() *instances.Expander {
return ctx.InstanceExpanderValue
}
func (ctx *BuiltinEvalContext) init() {
}

View File

@ -5,6 +5,7 @@ import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/instances"
"github.com/hashicorp/terraform/lang"
"github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/providers"
@ -124,6 +125,9 @@ type MockEvalContext struct {
StateCalled bool
StateState *states.SyncState
InstanceExpanderCalled bool
InstanceExpanderExpander *instances.Expander
}
// MockEvalContext implements EvalContext
@ -327,3 +331,8 @@ func (c *MockEvalContext) State() *states.SyncState {
c.StateCalled = true
return c.StateState
}
func (c *MockEvalContext) InstanceExpander() *instances.Expander {
c.InstanceExpanderCalled = true
return c.InstanceExpanderExpander
}

View File

@ -10,6 +10,7 @@ import (
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/dag"
"github.com/hashicorp/terraform/instances"
"github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/provisioners"
@ -24,8 +25,9 @@ type ContextGraphWalker struct {
// Configurable values
Context *Context
State *states.SyncState // Used for safe concurrent access to state
Changes *plans.ChangesSync // Used for safe concurrent writes to changes
State *states.SyncState // Used for safe concurrent access to state
Changes *plans.ChangesSync // Used for safe concurrent writes to changes
InstanceExpander *instances.Expander // Tracks our gradual expansion of module and resource instances
Operation walkOperation
StopContext context.Context
RootVariableValues InputValues
@ -75,22 +77,23 @@ func (w *ContextGraphWalker) EnterPath(path addrs.ModuleInstance) EvalContext {
}
ctx := &BuiltinEvalContext{
StopContext: w.StopContext,
PathValue: path,
Hooks: w.Context.hooks,
InputValue: w.Context.uiInput,
Components: w.Context.components,
Schemas: w.Context.schemas,
ProviderCache: w.providerCache,
ProviderInputConfig: w.Context.providerInputConfig,
ProviderLock: &w.providerLock,
ProvisionerCache: w.provisionerCache,
ProvisionerLock: &w.provisionerLock,
ChangesValue: w.Changes,
StateValue: w.State,
Evaluator: evaluator,
VariableValues: w.variableValues,
VariableValuesLock: &w.variableValuesLock,
StopContext: w.StopContext,
PathValue: path,
Hooks: w.Context.hooks,
InputValue: w.Context.uiInput,
InstanceExpanderValue: w.InstanceExpander,
Components: w.Context.components,
Schemas: w.Context.schemas,
ProviderCache: w.providerCache,
ProviderInputConfig: w.Context.providerInputConfig,
ProviderLock: &w.providerLock,
ProvisionerCache: w.provisionerCache,
ProvisionerLock: &w.provisionerLock,
ChangesValue: w.Changes,
StateValue: w.State,
Evaluator: evaluator,
VariableValues: w.variableValues,
VariableValuesLock: &w.variableValuesLock,
}
w.contexts[key] = ctx