mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
core: Wire back in module input variables to the evaluator
I took some missteps here while doing the initial refactor for HCL2 types. This restores the map of maps that retains all of the variable values, and then makes it available to the evaluator.
This commit is contained in:
parent
4b5868f653
commit
25e3ac56d2
@ -347,12 +347,11 @@ func (c *Context) State() *State {
|
|||||||
// receiving context.
|
// receiving context.
|
||||||
func (c *Context) Evaluator() *Evaluator {
|
func (c *Context) Evaluator() *Evaluator {
|
||||||
return &Evaluator{
|
return &Evaluator{
|
||||||
Operation: walkApply,
|
Operation: walkApply,
|
||||||
Meta: c.meta,
|
Meta: c.meta,
|
||||||
Config: c.config,
|
Config: c.config,
|
||||||
State: c.state,
|
State: c.state,
|
||||||
StateLock: &c.stateLock,
|
StateLock: &c.stateLock,
|
||||||
RootVariableValues: c.variables,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -786,9 +785,10 @@ func (c *Context) walk(graph *Graph, operation walkOperation) (*ContextGraphWalk
|
|||||||
log.Printf("[DEBUG] Starting graph walk: %s", operation.String())
|
log.Printf("[DEBUG] Starting graph walk: %s", operation.String())
|
||||||
|
|
||||||
walker := &ContextGraphWalker{
|
walker := &ContextGraphWalker{
|
||||||
Context: realCtx,
|
Context: realCtx,
|
||||||
Operation: operation,
|
Operation: operation,
|
||||||
StopContext: c.runContext,
|
StopContext: c.runContext,
|
||||||
|
RootVariableValues: c.variables,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch for a stop so we can call the provider Stop() API.
|
// Watch for a stop so we can call the provider Stop() API.
|
||||||
|
@ -27,8 +27,14 @@ type BuiltinEvalContext struct {
|
|||||||
// eval context.
|
// eval context.
|
||||||
Evaluator *Evaluator
|
Evaluator *Evaluator
|
||||||
|
|
||||||
ChildModuleCallArgs map[string]map[string]cty.Value
|
// VariableValues contains the variable values across all modules. This
|
||||||
ChildModuleCallsLock *sync.Mutex
|
// structure is shared across the entire containing context, and so it
|
||||||
|
// may be accessed only when holding VariableValuesLock.
|
||||||
|
// The keys of the first level of VariableValues are the string
|
||||||
|
// representations of addrs.ModuleInstance values. The second-level keys
|
||||||
|
// are variable names within each module instance.
|
||||||
|
VariableValues map[string]map[string]cty.Value
|
||||||
|
VariableValuesLock *sync.Mutex
|
||||||
|
|
||||||
Components contextComponentFactory
|
Components contextComponentFactory
|
||||||
Hooks []Hook
|
Hooks []Hook
|
||||||
@ -322,16 +328,17 @@ func (ctx *BuiltinEvalContext) Path() addrs.ModuleInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *BuiltinEvalContext) SetModuleCallArguments(n addrs.ModuleCallInstance, vals map[string]cty.Value) {
|
func (ctx *BuiltinEvalContext) SetModuleCallArguments(n addrs.ModuleCallInstance, vals map[string]cty.Value) {
|
||||||
ctx.ChildModuleCallsLock.Lock()
|
ctx.VariableValuesLock.Lock()
|
||||||
defer ctx.ChildModuleCallsLock.Unlock()
|
defer ctx.VariableValuesLock.Unlock()
|
||||||
|
|
||||||
childPath := ctx.Path().Child(n.Call.Name, n.Key)
|
childPath := n.ModuleInstance(ctx.PathValue)
|
||||||
key := childPath.String()
|
key := childPath.String()
|
||||||
|
|
||||||
args := ctx.ChildModuleCallArgs[key]
|
args := ctx.VariableValues[key]
|
||||||
if args == nil {
|
if args == nil {
|
||||||
args = make(map[string]cty.Value)
|
args = make(map[string]cty.Value)
|
||||||
ctx.ChildModuleCallArgs[key] = args
|
ctx.VariableValues[key] = vals
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range vals {
|
for k, v := range vals {
|
||||||
|
@ -24,10 +24,15 @@ type Evaluator struct {
|
|||||||
// Config is the root node in the configuration tree.
|
// Config is the root node in the configuration tree.
|
||||||
Config *configs.Config
|
Config *configs.Config
|
||||||
|
|
||||||
// RootVariableValues is a map of values for variables defined in the
|
// VariableValues is a map from variable names to their associated values,
|
||||||
// root module, passed in from external sources. This must not be
|
// within the module indicated by ModulePath. VariableValues is modified
|
||||||
// modified during evaluation.
|
// concurrently, and so it must be accessed only while holding
|
||||||
RootVariableValues map[string]*InputValue
|
// VariableValuesLock.
|
||||||
|
//
|
||||||
|
// The first map level is string representations of addr.ModuleInstance
|
||||||
|
// values, while the second level is variable names.
|
||||||
|
VariableValues map[string]map[string]cty.Value
|
||||||
|
VariableValuesLock *sync.Mutex
|
||||||
|
|
||||||
// State is the current state. During some operations this structure
|
// State is the current state. During some operations this structure
|
||||||
// is mutated concurrently, and so it must be accessed only while holding
|
// is mutated concurrently, and so it must be accessed only while holding
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/config/configschema"
|
"github.com/hashicorp/terraform/config/configschema"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
|
|
||||||
@ -19,26 +21,27 @@ type ContextGraphWalker struct {
|
|||||||
NullGraphWalker
|
NullGraphWalker
|
||||||
|
|
||||||
// Configurable values
|
// Configurable values
|
||||||
Context *Context
|
Context *Context
|
||||||
Operation walkOperation
|
Operation walkOperation
|
||||||
StopContext context.Context
|
StopContext context.Context
|
||||||
|
RootVariableValues InputValues
|
||||||
|
|
||||||
// This is an output. Do not set this, nor read it while a graph walk
|
// This is an output. Do not set this, nor read it while a graph walk
|
||||||
// is in progress.
|
// is in progress.
|
||||||
NonFatalDiagnostics tfdiags.Diagnostics
|
NonFatalDiagnostics tfdiags.Diagnostics
|
||||||
|
|
||||||
errorLock sync.Mutex
|
errorLock sync.Mutex
|
||||||
once sync.Once
|
once sync.Once
|
||||||
contexts map[string]*BuiltinEvalContext
|
contexts map[string]*BuiltinEvalContext
|
||||||
contextLock sync.Mutex
|
contextLock sync.Mutex
|
||||||
interpolaterVars map[string]map[string]interface{}
|
variableValues map[string]map[string]cty.Value
|
||||||
interpolaterVarLock sync.Mutex
|
variableValuesLock sync.Mutex
|
||||||
providerCache map[string]ResourceProvider
|
providerCache map[string]ResourceProvider
|
||||||
providerSchemas map[string]*ProviderSchema
|
providerSchemas map[string]*ProviderSchema
|
||||||
providerLock sync.Mutex
|
providerLock sync.Mutex
|
||||||
provisionerCache map[string]ResourceProvisioner
|
provisionerCache map[string]ResourceProvisioner
|
||||||
provisionerSchemas map[string]*configschema.Block
|
provisionerSchemas map[string]*configschema.Block
|
||||||
provisionerLock sync.Mutex
|
provisionerLock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *ContextGraphWalker) EnterPath(path addrs.ModuleInstance) EvalContext {
|
func (w *ContextGraphWalker) EnterPath(path addrs.ModuleInstance) EvalContext {
|
||||||
@ -53,38 +56,18 @@ func (w *ContextGraphWalker) EnterPath(path addrs.ModuleInstance) EvalContext {
|
|||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the variables for this interpolater
|
|
||||||
variables := make(map[string]interface{})
|
|
||||||
if len(path) <= 1 {
|
|
||||||
for k, v := range w.Context.variables {
|
|
||||||
variables[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.interpolaterVarLock.Lock()
|
|
||||||
if m, ok := w.interpolaterVars[key]; ok {
|
|
||||||
for k, v := range m {
|
|
||||||
variables[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.interpolaterVars[key] = variables
|
|
||||||
w.interpolaterVarLock.Unlock()
|
|
||||||
|
|
||||||
// Our evaluator shares some locks with the main context and the walker
|
// Our evaluator shares some locks with the main context and the walker
|
||||||
// so that we can safely run multiple evaluations at once across
|
// so that we can safely run multiple evaluations at once across
|
||||||
// different modules.
|
// different modules.
|
||||||
evaluator := &Evaluator{
|
evaluator := &Evaluator{
|
||||||
Meta: w.Context.meta,
|
Meta: w.Context.meta,
|
||||||
Config: w.Context.config,
|
Config: w.Context.config,
|
||||||
State: w.Context.state,
|
State: w.Context.state,
|
||||||
StateLock: &w.Context.stateLock,
|
StateLock: &w.Context.stateLock,
|
||||||
ProviderSchemas: w.providerSchemas,
|
ProviderSchemas: w.providerSchemas,
|
||||||
ProvidersLock: &w.providerLock,
|
ProvidersLock: &w.providerLock,
|
||||||
|
VariableValues: w.variableValues,
|
||||||
// FIXME: This was a design mistake on the evaluator, which should
|
VariableValuesLock: &w.variableValuesLock,
|
||||||
// get replaced with something like the interpolatorVars thing above
|
|
||||||
// once we verify exactly how that was used in the old Interpolator
|
|
||||||
// codepath.
|
|
||||||
RootVariableValues: map[string]*InputValue{},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := &BuiltinEvalContext{
|
ctx := &BuiltinEvalContext{
|
||||||
@ -104,6 +87,8 @@ func (w *ContextGraphWalker) EnterPath(path addrs.ModuleInstance) EvalContext {
|
|||||||
StateValue: w.Context.state,
|
StateValue: w.Context.state,
|
||||||
StateLock: &w.Context.stateLock,
|
StateLock: &w.Context.stateLock,
|
||||||
Evaluator: evaluator,
|
Evaluator: evaluator,
|
||||||
|
VariableValues: w.variableValues,
|
||||||
|
VariableValuesLock: &w.variableValuesLock,
|
||||||
}
|
}
|
||||||
|
|
||||||
w.contexts[key] = ctx
|
w.contexts[key] = ctx
|
||||||
@ -158,5 +143,12 @@ func (w *ContextGraphWalker) init() {
|
|||||||
w.providerSchemas = make(map[string]*ProviderSchema)
|
w.providerSchemas = make(map[string]*ProviderSchema)
|
||||||
w.provisionerCache = make(map[string]ResourceProvisioner)
|
w.provisionerCache = make(map[string]ResourceProvisioner)
|
||||||
w.provisionerSchemas = make(map[string]*configschema.Block)
|
w.provisionerSchemas = make(map[string]*configschema.Block)
|
||||||
w.interpolaterVars = make(map[string]map[string]interface{})
|
w.variableValues = make(map[string]map[string]cty.Value)
|
||||||
|
|
||||||
|
// Populate root module variable values. Other modules will be populated
|
||||||
|
// during the graph walk.
|
||||||
|
w.variableValues[""] = make(map[string]cty.Value)
|
||||||
|
for k, iv := range w.RootVariableValues {
|
||||||
|
w.variableValues[""][k] = iv.Value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user