]>
Commit | Line | Data |
---|---|---|
bae9f6d2 JC |
1 | package terraform |
2 | ||
3 | import ( | |
4 | "fmt" | |
5 | "log" | |
6 | "strings" | |
107c1cdb ND |
7 | |
8 | "github.com/hashicorp/terraform/tfdiags" | |
9 | ||
10 | "github.com/hashicorp/terraform/addrs" | |
bae9f6d2 JC |
11 | ) |
12 | ||
13 | // GraphBuilder is an interface that can be implemented and used with | |
14 | // Terraform to build the graph that Terraform walks. | |
15 | type GraphBuilder interface { | |
16 | // Build builds the graph for the given module path. It is up to | |
17 | // the interface implementation whether this build should expand | |
18 | // the graph or not. | |
107c1cdb | 19 | Build(addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) |
bae9f6d2 JC |
20 | } |
21 | ||
22 | // BasicGraphBuilder is a GraphBuilder that builds a graph out of a | |
23 | // series of transforms and (optionally) validates the graph is a valid | |
24 | // structure. | |
25 | type BasicGraphBuilder struct { | |
26 | Steps []GraphTransformer | |
27 | Validate bool | |
28 | // Optional name to add to the graph debug log | |
29 | Name string | |
30 | } | |
31 | ||
107c1cdb ND |
32 | func (b *BasicGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) { |
33 | var diags tfdiags.Diagnostics | |
bae9f6d2 JC |
34 | g := &Graph{Path: path} |
35 | ||
107c1cdb | 36 | var lastStepStr string |
bae9f6d2 JC |
37 | for _, step := range b.Steps { |
38 | if step == nil { | |
39 | continue | |
40 | } | |
107c1cdb | 41 | log.Printf("[TRACE] Executing graph transform %T", step) |
bae9f6d2 JC |
42 | |
43 | stepName := fmt.Sprintf("%T", step) | |
44 | dot := strings.LastIndex(stepName, ".") | |
45 | if dot >= 0 { | |
46 | stepName = stepName[dot+1:] | |
47 | } | |
48 | ||
49 | debugOp := g.DebugOperation(stepName, "") | |
50 | err := step.Transform(g) | |
51 | ||
52 | errMsg := "" | |
53 | if err != nil { | |
54 | errMsg = err.Error() | |
55 | } | |
56 | debugOp.End(errMsg) | |
57 | ||
107c1cdb ND |
58 | if thisStepStr := g.StringWithNodeTypes(); thisStepStr != lastStepStr { |
59 | log.Printf("[TRACE] Completed graph transform %T with new graph:\n%s------", step, thisStepStr) | |
60 | lastStepStr = thisStepStr | |
61 | } else { | |
62 | log.Printf("[TRACE] Completed graph transform %T (no changes)", step) | |
63 | } | |
bae9f6d2 JC |
64 | |
65 | if err != nil { | |
107c1cdb ND |
66 | if nf, isNF := err.(tfdiags.NonFatalError); isNF { |
67 | diags = diags.Append(nf.Diagnostics) | |
68 | } else { | |
69 | diags = diags.Append(err) | |
70 | return g, diags | |
71 | } | |
bae9f6d2 JC |
72 | } |
73 | } | |
74 | ||
75 | // Validate the graph structure | |
76 | if b.Validate { | |
77 | if err := g.Validate(); err != nil { | |
78 | log.Printf("[ERROR] Graph validation failed. Graph:\n\n%s", g.String()) | |
107c1cdb ND |
79 | diags = diags.Append(err) |
80 | return nil, diags | |
bae9f6d2 JC |
81 | } |
82 | } | |
83 | ||
107c1cdb | 84 | return g, diags |
bae9f6d2 | 85 | } |