From 1ad97f6be8b8654ee152366f5259d784d8947ae7 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Tue, 26 Sep 2017 19:00:57 -0400 Subject: [PATCH] use an EvalOpFilter for module variables Remove the Input flag threaded through the input graph creation process to prevent interpolation failures on module variables. Use an EvalOpFilter instead to inset the correct EvalNode during walkInput. Remove the EvalTryInterpolate type, and use the same ContinueOnErr flag as the output node for consistency and to try and keep the number possible eval node types down. --- terraform/eval_interpolate.go | 36 ++++++-------------------- terraform/graph_builder_input.go | 3 --- terraform/graph_builder_plan.go | 4 --- terraform/node_module_variable.go | 34 ++++++++++++------------ terraform/transform_module_variable.go | 2 -- 5 files changed, 24 insertions(+), 55 deletions(-) diff --git a/terraform/eval_interpolate.go b/terraform/eval_interpolate.go index df3bcb98e..78c881360 100644 --- a/terraform/eval_interpolate.go +++ b/terraform/eval_interpolate.go @@ -9,14 +9,19 @@ import ( // EvalInterpolate is an EvalNode implementation that takes a raw // configuration and interpolates it. type EvalInterpolate struct { - Config *config.RawConfig - Resource *Resource - Output **ResourceConfig + Config *config.RawConfig + Resource *Resource + Output **ResourceConfig + ContinueOnErr bool } func (n *EvalInterpolate) Eval(ctx EvalContext) (interface{}, error) { rc, err := ctx.Interpolate(n.Config, n.Resource) if err != nil { + if n.ContinueOnErr { + log.Printf("[WARN] Interpolation %q failed: %s", n.Config.Key, err) + return nil, EvalEarlyExitError{} + } return nil, err } @@ -26,28 +31,3 @@ func (n *EvalInterpolate) Eval(ctx EvalContext) (interface{}, error) { return nil, nil } - -// EvalTryInterpolate is an EvalNode implementation that takes a raw -// configuration and interpolates it, but only logs a warning on an -// interpolation error, and stops further Eval steps. -// This is used during Input where a value may not be known before Refresh, but -// we don't want to block Input. -type EvalTryInterpolate struct { - Config *config.RawConfig - Resource *Resource - Output **ResourceConfig -} - -func (n *EvalTryInterpolate) Eval(ctx EvalContext) (interface{}, error) { - rc, err := ctx.Interpolate(n.Config, n.Resource) - if err != nil { - log.Printf("[WARN] Interpolation %q failed: %s", n.Config.Key, err) - return nil, EvalEarlyExitError{} - } - - if n.Output != nil { - *n.Output = rc - } - - return nil, nil -} diff --git a/terraform/graph_builder_input.go b/terraform/graph_builder_input.go index 10fd8b1e9..0df48cdb8 100644 --- a/terraform/graph_builder_input.go +++ b/terraform/graph_builder_input.go @@ -10,9 +10,6 @@ import ( // and is based on the PlanGraphBuilder. The PlanGraphBuilder passed in will be // modified and should not be used for any other operations. func InputGraphBuilder(p *PlanGraphBuilder) GraphBuilder { - // convert this to an InputPlan - p.Input = true - // We're going to customize the concrete functions p.CustomConcrete = true diff --git a/terraform/graph_builder_plan.go b/terraform/graph_builder_plan.go index 9d05d4a43..429e42481 100644 --- a/terraform/graph_builder_plan.go +++ b/terraform/graph_builder_plan.go @@ -40,9 +40,6 @@ type PlanGraphBuilder struct { // Validate will do structural validation of the graph. Validate bool - // Input represents that this builder is for an Input operation. - Input bool - // CustomConcrete can be set to customize the node types created // for various parts of the plan. This is useful in order to customize // the plan behavior. @@ -115,7 +112,6 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer { // Add module variables &ModuleVariableTransformer{ Module: b.Module, - Input: b.Input, }, // Connect so that the references are ready for targeting. We'll diff --git a/terraform/node_module_variable.go b/terraform/node_module_variable.go index 63b84a9c5..66ff7d5e3 100644 --- a/terraform/node_module_variable.go +++ b/terraform/node_module_variable.go @@ -15,9 +15,6 @@ type NodeApplyableModuleVariable struct { Value *config.RawConfig // Value is the value that is set Module *module.Tree // Antiquated, want to remove - - // Input is set if this graph was created for the Input operation. - Input bool } func (n *NodeApplyableModuleVariable) Name() string { @@ -96,23 +93,24 @@ func (n *NodeApplyableModuleVariable) EvalTree() EvalNode { var config *ResourceConfig variables := make(map[string]interface{}) - var interpolate EvalNode - - if n.Input { - interpolate = &EvalTryInterpolate{ - Config: n.Value, - Output: &config, - } - } else { - interpolate = &EvalInterpolate{ - Config: n.Value, - Output: &config, - } - } - return &EvalSequence{ Nodes: []EvalNode{ - interpolate, + &EvalOpFilter{ + Ops: []walkOperation{walkInput}, + Node: &EvalInterpolate{ + Config: n.Value, + Output: &config, + ContinueOnErr: true, + }, + }, + &EvalOpFilter{ + Ops: []walkOperation{walkRefresh, walkPlan, walkApply, + walkDestroy, walkValidate}, + Node: &EvalInterpolate{ + Config: n.Value, + Output: &config, + }, + }, &EvalVariableBlock{ Config: &config, diff --git a/terraform/transform_module_variable.go b/terraform/transform_module_variable.go index dbfd16871..467950bdc 100644 --- a/terraform/transform_module_variable.go +++ b/terraform/transform_module_variable.go @@ -17,7 +17,6 @@ type ModuleVariableTransformer struct { Module *module.Tree DisablePrune bool // True if pruning unreferenced should be disabled - Input bool // True if this is from an Input operation. } func (t *ModuleVariableTransformer) Transform(g *Graph) error { @@ -100,7 +99,6 @@ func (t *ModuleVariableTransformer) transformSingle(g *Graph, parent, m *module. Config: v, Value: value, Module: t.Module, - Input: t.Input, } if !t.DisablePrune {