github.com/hashicorp/terraform-plugin-sdk@v1.17.2/terraform/graph_builder.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 8 "github.com/hashicorp/terraform-plugin-sdk/internal/tfdiags" 9 10 "github.com/hashicorp/terraform-plugin-sdk/internal/addrs" 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. 19 Build(addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) 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 32 func (b *BasicGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) { 33 var diags tfdiags.Diagnostics 34 g := &Graph{Path: path} 35 36 var lastStepStr string 37 for _, step := range b.Steps { 38 if step == nil { 39 continue 40 } 41 log.Printf("[TRACE] Executing graph transform %T", step) 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 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 } 64 65 if err != nil { 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 } 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()) 79 diags = diags.Append(err) 80 return nil, diags 81 } 82 } 83 84 return g, diags 85 }