github.com/trawler/terraform@v0.10.8-0.20171106022149-4b1c7a1d9b48/terraform/node_module_variable.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 6 "github.com/hashicorp/terraform/config" 7 "github.com/hashicorp/terraform/config/module" 8 ) 9 10 // NodeApplyableModuleVariable represents a module variable input during 11 // the apply step. 12 type NodeApplyableModuleVariable struct { 13 PathValue []string 14 Config *config.Variable // Config is the var in the config 15 Value *config.RawConfig // Value is the value that is set 16 17 Module *module.Tree // Antiquated, want to remove 18 } 19 20 func (n *NodeApplyableModuleVariable) Name() string { 21 result := fmt.Sprintf("var.%s", n.Config.Name) 22 if len(n.PathValue) > 1 { 23 result = fmt.Sprintf("%s.%s", modulePrefixStr(n.PathValue), result) 24 } 25 26 return result 27 } 28 29 // GraphNodeSubPath 30 func (n *NodeApplyableModuleVariable) Path() []string { 31 // We execute in the parent scope (above our own module) so that 32 // we can access the proper interpolations. 33 if len(n.PathValue) > 2 { 34 return n.PathValue[:len(n.PathValue)-1] 35 } 36 37 return rootModulePath 38 } 39 40 // RemovableIfNotTargeted 41 func (n *NodeApplyableModuleVariable) RemoveIfNotTargeted() bool { 42 // We need to add this so that this node will be removed if 43 // it isn't targeted or a dependency of a target. 44 return true 45 } 46 47 // GraphNodeReferenceGlobal 48 func (n *NodeApplyableModuleVariable) ReferenceGlobal() bool { 49 // We have to create fully qualified references because we cross 50 // boundaries here: our ReferenceableName is in one path and our 51 // References are from another path. 52 return true 53 } 54 55 // GraphNodeReferenceable 56 func (n *NodeApplyableModuleVariable) ReferenceableName() []string { 57 return []string{n.Name()} 58 } 59 60 // GraphNodeReferencer 61 func (n *NodeApplyableModuleVariable) References() []string { 62 // If we have no value set, we depend on nothing 63 if n.Value == nil { 64 return nil 65 } 66 67 // Can't depend on anything if we're in the root 68 if len(n.PathValue) < 2 { 69 return nil 70 } 71 72 // Otherwise, we depend on anything that is in our value, but 73 // specifically in the namespace of the parent path. 74 // Create the prefix based on the path 75 var prefix string 76 if p := n.Path(); len(p) > 0 { 77 prefix = modulePrefixStr(p) 78 } 79 80 result := ReferencesFromConfig(n.Value) 81 return modulePrefixList(result, prefix) 82 } 83 84 // GraphNodeEvalable 85 func (n *NodeApplyableModuleVariable) EvalTree() EvalNode { 86 // If we have no value, do nothing 87 if n.Value == nil { 88 return &EvalNoop{} 89 } 90 91 // Otherwise, interpolate the value of this variable and set it 92 // within the variables mapping. 93 var config *ResourceConfig 94 variables := make(map[string]interface{}) 95 96 return &EvalSequence{ 97 Nodes: []EvalNode{ 98 &EvalOpFilter{ 99 Ops: []walkOperation{walkInput}, 100 Node: &EvalInterpolate{ 101 Config: n.Value, 102 Output: &config, 103 ContinueOnErr: true, 104 }, 105 }, 106 &EvalOpFilter{ 107 Ops: []walkOperation{walkRefresh, walkPlan, walkApply, 108 walkDestroy, walkValidate}, 109 Node: &EvalInterpolate{ 110 Config: n.Value, 111 Output: &config, 112 }, 113 }, 114 115 &EvalVariableBlock{ 116 Config: &config, 117 VariableValues: variables, 118 }, 119 120 &EvalCoerceMapVariable{ 121 Variables: variables, 122 ModulePath: n.PathValue, 123 ModuleTree: n.Module, 124 }, 125 126 &EvalTypeCheckVariable{ 127 Variables: variables, 128 ModulePath: n.PathValue, 129 ModuleTree: n.Module, 130 }, 131 132 &EvalSetVariables{ 133 Module: &n.PathValue[len(n.PathValue)-1], 134 Variables: variables, 135 }, 136 }, 137 } 138 }