From 8ea78dfe7dea51ac88ddf3b2b66f227b0d52eb19 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Thu, 21 Nov 2019 16:21:41 -0800 Subject: [PATCH] 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. --- terraform/context.go | 2 ++ terraform/eval_context_builtin.go | 26 +++++++++++++-------- terraform/eval_context_mock.go | 9 +++++++ terraform/graph_walk_context.go | 39 +++++++++++++++++-------------- 4 files changed, 48 insertions(+), 28 deletions(-) diff --git a/terraform/context.go b/terraform/context.go index 2a438787f..1817aa541 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -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, diff --git a/terraform/eval_context_builtin.go b/terraform/eval_context_builtin.go index d4db78f51..308512ec6 100644 --- a/terraform/eval_context_builtin.go +++ b/terraform/eval_context_builtin.go @@ -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() { } diff --git a/terraform/eval_context_mock.go b/terraform/eval_context_mock.go index 7329dd31a..228bbc4ee 100644 --- a/terraform/eval_context_mock.go +++ b/terraform/eval_context_mock.go @@ -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 +} diff --git a/terraform/graph_walk_context.go b/terraform/graph_walk_context.go index 03c192a86..d53ebe97a 100644 --- a/terraform/graph_walk_context.go +++ b/terraform/graph_walk_context.go @@ -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