github.com/rmenn/terraform@v0.3.8-0.20150225065417-fc84b3a78802/terraform/transform_config.go (about)

     1  package terraform
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/hashicorp/go-multierror"
     8  	"github.com/hashicorp/terraform/config"
     9  	"github.com/hashicorp/terraform/config/module"
    10  )
    11  
    12  // ConfigTransformer is a GraphTransformer that adds the configuration
    13  // to the graph. The module used to configure this transformer must be
    14  // the root module. We'll look up the child module by the Path in the
    15  // Graph.
    16  type ConfigTransformer struct {
    17  	Module *module.Tree
    18  }
    19  
    20  func (t *ConfigTransformer) Transform(g *Graph) error {
    21  	// A module is required and also must be completely loaded.
    22  	if t.Module == nil {
    23  		return errors.New("module must not be nil")
    24  	}
    25  	if !t.Module.Loaded() {
    26  		return errors.New("module must be loaded")
    27  	}
    28  
    29  	// Get the module we care about
    30  	module := t.Module.Child(g.Path[1:])
    31  	if module == nil {
    32  		return nil
    33  	}
    34  
    35  	// Get the configuration for this module
    36  	config := module.Config()
    37  
    38  	// Create the node list we'll use for the graph
    39  	nodes := make([]graphNodeConfig, 0,
    40  		(len(config.ProviderConfigs)+len(config.Modules)+len(config.Resources))*2)
    41  
    42  	// Write all the provider configs out
    43  	for _, pc := range config.ProviderConfigs {
    44  		nodes = append(nodes, &GraphNodeConfigProvider{Provider: pc})
    45  	}
    46  
    47  	// Write all the resources out
    48  	for _, r := range config.Resources {
    49  		nodes = append(nodes, &GraphNodeConfigResource{Resource: r})
    50  	}
    51  
    52  	// Write all the modules out
    53  	children := module.Children()
    54  	for _, m := range config.Modules {
    55  		path := make([]string, len(g.Path), len(g.Path)+1)
    56  		copy(path, g.Path)
    57  		path = append(path, m.Name)
    58  
    59  		nodes = append(nodes, &GraphNodeConfigModule{
    60  			Path:   path,
    61  			Module: m,
    62  			Tree:   children[m.Name],
    63  		})
    64  	}
    65  
    66  	// Write all the outputs out
    67  	for _, o := range config.Outputs {
    68  		nodes = append(nodes, &GraphNodeConfigOutput{Output: o})
    69  	}
    70  
    71  	// Err is where the final error value will go if there is one
    72  	var err error
    73  
    74  	// Build the graph vertices
    75  	for _, n := range nodes {
    76  		g.Add(n)
    77  	}
    78  
    79  	// Build up the dependencies. We have to do this outside of the above
    80  	// loop since the nodes need to be in place for us to build the deps.
    81  	for _, n := range nodes {
    82  		if missing := g.ConnectDependent(n); len(missing) > 0 {
    83  			for _, m := range missing {
    84  				err = multierror.Append(err, fmt.Errorf(
    85  					"%s: missing dependency: %s", n.Name(), m))
    86  			}
    87  		}
    88  	}
    89  
    90  	return err
    91  }
    92  
    93  // varNameForVar returns the VarName value for an interpolated variable.
    94  // This value is compared to the VarName() value for the nodes within the
    95  // graph to build the graph edges.
    96  func varNameForVar(raw config.InterpolatedVariable) string {
    97  	switch v := raw.(type) {
    98  	case *config.ModuleVariable:
    99  		return fmt.Sprintf("module.%s", v.Name)
   100  	case *config.ResourceVariable:
   101  		return v.ResourceId()
   102  	default:
   103  		return ""
   104  	}
   105  }