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 }