github.com/hs0210/hashicorp-terraform@v0.11.12-beta1/terraform/transform_module_variable.go (about)

     1  package terraform
     2  
     3  import (
     4  	"log"
     5  
     6  	"github.com/hashicorp/terraform/config"
     7  	"github.com/hashicorp/terraform/config/module"
     8  	"github.com/hashicorp/terraform/dag"
     9  )
    10  
    11  // ModuleVariableTransformer is a GraphTransformer that adds all the variables
    12  // in the configuration to the graph.
    13  //
    14  // This only adds variables that are referenced by other things in the graph.
    15  // If a module variable is not referenced, it won't be added to the graph.
    16  type ModuleVariableTransformer struct {
    17  	Module *module.Tree
    18  
    19  	DisablePrune bool // True if pruning unreferenced should be disabled
    20  }
    21  
    22  func (t *ModuleVariableTransformer) Transform(g *Graph) error {
    23  	return t.transform(g, nil, t.Module)
    24  }
    25  
    26  func (t *ModuleVariableTransformer) transform(g *Graph, parent, m *module.Tree) error {
    27  	// If no config, no variables
    28  	if m == nil {
    29  		return nil
    30  	}
    31  
    32  	// Transform all the children. This must be done BEFORE the transform
    33  	// above since child module variables can reference parent module variables.
    34  	for _, c := range m.Children() {
    35  		if err := t.transform(g, m, c); err != nil {
    36  			return err
    37  		}
    38  	}
    39  
    40  	// If we have a parent, we can determine if a module variable is being
    41  	// used, so we transform this.
    42  	if parent != nil {
    43  		if err := t.transformSingle(g, parent, m); err != nil {
    44  			return err
    45  		}
    46  	}
    47  
    48  	return nil
    49  }
    50  
    51  func (t *ModuleVariableTransformer) transformSingle(g *Graph, parent, m *module.Tree) error {
    52  	// If we have no vars, we're done!
    53  	vars := m.Config().Variables
    54  	if len(vars) == 0 {
    55  		log.Printf("[TRACE] Module %#v has no variables, skipping.", m.Path())
    56  		return nil
    57  	}
    58  
    59  	// Look for usage of this module
    60  	var mod *config.Module
    61  	for _, modUse := range parent.Config().Modules {
    62  		if modUse.Name == m.Name() {
    63  			mod = modUse
    64  			break
    65  		}
    66  	}
    67  	if mod == nil {
    68  		log.Printf("[INFO] Module %#v not used, not adding variables", m.Path())
    69  		return nil
    70  	}
    71  
    72  	// Build the reference map so we can determine if we're referencing things.
    73  	refMap := NewReferenceMap(g.Vertices())
    74  
    75  	// Add all variables here
    76  	for _, v := range vars {
    77  		// Determine the value of the variable. If it isn't in the
    78  		// configuration then it was never set and that's not a problem.
    79  		var value *config.RawConfig
    80  		if raw, ok := mod.RawConfig.Raw[v.Name]; ok {
    81  			var err error
    82  			value, err = config.NewRawConfig(map[string]interface{}{
    83  				v.Name: raw,
    84  			})
    85  			if err != nil {
    86  				// This shouldn't happen because it is already in
    87  				// a RawConfig above meaning it worked once before.
    88  				panic(err)
    89  			}
    90  		}
    91  
    92  		// Build the node.
    93  		//
    94  		// NOTE: For now this is just an "applyable" variable. As we build
    95  		// new graph builders for the other operations I suspect we'll
    96  		// find a way to parameterize this, require new transforms, etc.
    97  		node := &NodeApplyableModuleVariable{
    98  			PathValue: normalizeModulePath(m.Path()),
    99  			Config:    v,
   100  			Value:     value,
   101  			Module:    t.Module,
   102  		}
   103  
   104  		if !t.DisablePrune {
   105  			// If the node is not referenced by anything, then we don't need
   106  			// to include it since it won't be used.
   107  			if matches := refMap.ReferencedBy(node); len(matches) == 0 {
   108  				log.Printf(
   109  					"[INFO] Not including %q in graph, nothing depends on it",
   110  					dag.VertexName(node))
   111  				continue
   112  			}
   113  		}
   114  
   115  		// Add it!
   116  		g.Add(node)
   117  	}
   118  
   119  	return nil
   120  }