github.com/rmenn/terraform@v0.3.8-0.20150225065417-fc84b3a78802/terraform/graph_builder.go (about) 1 package terraform 2 3 import ( 4 "log" 5 6 "github.com/hashicorp/terraform/config/module" 7 ) 8 9 // GraphBuilder is an interface that can be implemented and used with 10 // Terraform to build the graph that Terraform walks. 11 type GraphBuilder interface { 12 // Build builds the graph for the given module path. It is up to 13 // the interface implementation whether this build should expand 14 // the graph or not. 15 Build(path []string) (*Graph, error) 16 } 17 18 // BasicGraphBuilder is a GraphBuilder that builds a graph out of a 19 // series of transforms and validates the graph is a valid structure. 20 type BasicGraphBuilder struct { 21 Steps []GraphTransformer 22 } 23 24 func (b *BasicGraphBuilder) Build(path []string) (*Graph, error) { 25 g := &Graph{Path: path} 26 for _, step := range b.Steps { 27 if err := step.Transform(g); err != nil { 28 return g, err 29 } 30 31 log.Printf("[TRACE] Graph after step %T:\n\n%s", step, g.String()) 32 } 33 34 // Validate the graph structure 35 if err := g.Validate(); err != nil { 36 log.Printf("[ERROR] Graph validation failed. Graph:\n\n%s", g.String()) 37 return nil, err 38 } 39 40 return g, nil 41 } 42 43 // BuiltinGraphBuilder is responsible for building the complete graph that 44 // Terraform uses for execution. It is an opinionated builder that defines 45 // the step order required to build a complete graph as is used and expected 46 // by Terraform. 47 // 48 // If you require a custom graph, you'll have to build it up manually 49 // on your own by building a new GraphBuilder implementation. 50 type BuiltinGraphBuilder struct { 51 // Root is the root module of the graph to build. 52 Root *module.Tree 53 54 // Diff is the diff. The proper module diffs will be looked up. 55 Diff *Diff 56 57 // State is the global state. The proper module states will be looked 58 // up by graph path. 59 State *State 60 61 // Providers is the list of providers supported. 62 Providers []string 63 64 // Provisioners is the list of provisioners supported. 65 Provisioners []string 66 } 67 68 // Build builds the graph according to the steps returned by Steps. 69 func (b *BuiltinGraphBuilder) Build(path []string) (*Graph, error) { 70 basic := &BasicGraphBuilder{ 71 Steps: b.Steps(), 72 } 73 74 return basic.Build(path) 75 } 76 77 // Steps returns the ordered list of GraphTransformers that must be executed 78 // to build a complete graph. 79 func (b *BuiltinGraphBuilder) Steps() []GraphTransformer { 80 return []GraphTransformer{ 81 // Create all our resources from the configuration and state 82 &ConfigTransformer{Module: b.Root}, 83 &OrphanTransformer{State: b.State, Module: b.Root}, 84 85 // Provider-related transformations 86 &MissingProviderTransformer{Providers: b.Providers}, 87 &ProviderTransformer{}, 88 &PruneProviderTransformer{}, 89 90 // Provisioner-related transformations 91 &MissingProvisionerTransformer{Provisioners: b.Provisioners}, 92 &ProvisionerTransformer{}, 93 &PruneProvisionerTransformer{}, 94 95 // Run our vertex-level transforms 96 &VertexTransformer{ 97 Transforms: []GraphVertexTransformer{ 98 // Expand any statically expanded nodes, such as module graphs 99 &ExpandTransform{ 100 Builder: b, 101 }, 102 }, 103 }, 104 105 // Create the destruction nodes 106 &DestroyTransformer{}, 107 &CreateBeforeDestroyTransformer{}, 108 &PruneDestroyTransformer{Diff: b.Diff, State: b.State}, 109 110 // Make sure we create one root 111 &RootTransformer{}, 112 } 113 }