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  }