github.com/2matz/terraform@v0.6.1-0.20150714181608-a03cbdb5d5bd/terraform/graph_config_node_variable.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 6 "github.com/hashicorp/terraform/config" 7 "github.com/hashicorp/terraform/dag" 8 ) 9 10 // GraphNodeConfigVariable represents a Variable in the config. 11 type GraphNodeConfigVariable struct { 12 Variable *config.Variable 13 14 // Value, if non-nil, will be used to set the value of the variable 15 // during evaluation. If this is nil, evaluation will do nothing. 16 // 17 // Module is the name of the module to set the variables on. 18 Module string 19 Value *config.RawConfig 20 21 depPrefix string 22 } 23 24 func (n *GraphNodeConfigVariable) Name() string { 25 return fmt.Sprintf("var.%s", n.Variable.Name) 26 } 27 28 func (n *GraphNodeConfigVariable) ConfigType() GraphNodeConfigType { 29 return GraphNodeConfigTypeVariable 30 } 31 32 func (n *GraphNodeConfigVariable) DependableName() []string { 33 return []string{n.Name()} 34 } 35 36 func (n *GraphNodeConfigVariable) DependentOn() []string { 37 // If we don't have any value set, we don't depend on anything 38 if n.Value == nil { 39 return nil 40 } 41 42 // Get what we depend on based on our value 43 vars := n.Value.Variables 44 result := make([]string, 0, len(vars)) 45 for _, v := range vars { 46 if vn := varNameForVar(v); vn != "" { 47 result = append(result, vn) 48 } 49 } 50 51 return result 52 } 53 54 func (n *GraphNodeConfigVariable) VariableName() string { 55 return n.Variable.Name 56 } 57 58 // GraphNodeDestroyEdgeInclude impl. 59 func (n *GraphNodeConfigVariable) DestroyEdgeInclude(v dag.Vertex) bool { 60 // Only include this variable in a destroy edge if the source vertex 61 // "v" has a count dependency on this variable. 62 cv, ok := v.(GraphNodeCountDependent) 63 if !ok { 64 return false 65 } 66 67 for _, d := range cv.CountDependentOn() { 68 for _, d2 := range n.DependableName() { 69 if d == d2 { 70 return true 71 } 72 } 73 } 74 75 return false 76 } 77 78 // GraphNodeProxy impl. 79 func (n *GraphNodeConfigVariable) Proxy() bool { 80 return true 81 } 82 83 // GraphNodeEvalable impl. 84 func (n *GraphNodeConfigVariable) EvalTree() EvalNode { 85 // If we have no value, do nothing 86 if n.Value == nil { 87 return &EvalNoop{} 88 } 89 90 // Otherwise, interpolate the value of this variable and set it 91 // within the variables mapping. 92 var config *ResourceConfig 93 variables := make(map[string]string) 94 return &EvalSequence{ 95 Nodes: []EvalNode{ 96 &EvalInterpolate{ 97 Config: n.Value, 98 Output: &config, 99 }, 100 101 &EvalVariableBlock{ 102 Config: &config, 103 Variables: variables, 104 }, 105 106 &EvalSetVariables{ 107 Module: &n.Module, 108 Variables: variables, 109 }, 110 }, 111 } 112 } 113 114 // GraphNodeFlattenable impl. 115 func (n *GraphNodeConfigVariable) Flatten(p []string) (dag.Vertex, error) { 116 return &GraphNodeConfigVariableFlat{ 117 GraphNodeConfigVariable: n, 118 PathValue: p, 119 }, nil 120 } 121 122 type GraphNodeConfigVariableFlat struct { 123 *GraphNodeConfigVariable 124 125 PathValue []string 126 } 127 128 func (n *GraphNodeConfigVariableFlat) Name() string { 129 return fmt.Sprintf( 130 "%s.%s", modulePrefixStr(n.PathValue), n.GraphNodeConfigVariable.Name()) 131 } 132 133 func (n *GraphNodeConfigVariableFlat) DependableName() []string { 134 return []string{n.Name()} 135 } 136 137 func (n *GraphNodeConfigVariableFlat) DependentOn() []string { 138 // We only wrap the dependencies and such if we have a path that is 139 // longer than 2 elements (root, child, more). This is because when 140 // flattened, variables can point outside the graph. 141 prefix := "" 142 if len(n.PathValue) > 2 { 143 prefix = modulePrefixStr(n.PathValue[:len(n.PathValue)-1]) 144 } 145 146 return modulePrefixList( 147 n.GraphNodeConfigVariable.DependentOn(), 148 prefix) 149 } 150 151 func (n *GraphNodeConfigVariableFlat) Path() []string { 152 if len(n.PathValue) > 2 { 153 return n.PathValue[:len(n.PathValue)-1] 154 } 155 156 return nil 157 }