terraform/terraform/graph_builder.go

78 lines
1.6 KiB
Go

package terraform
import (
"fmt"
"log"
"strings"
)
// GraphBuilder is an interface that can be implemented and used with
// Terraform to build the graph that Terraform walks.
type GraphBuilder interface {
// Build builds the graph for the given module path. It is up to
// the interface implementation whether this build should expand
// the graph or not.
Build(path []string) (*Graph, error)
}
// BasicGraphBuilder is a GraphBuilder that builds a graph out of a
// series of transforms and (optionally) validates the graph is a valid
// structure.
type BasicGraphBuilder struct {
Steps []GraphTransformer
Validate bool
// Optional name to add to the graph debug log
Name string
}
func (b *BasicGraphBuilder) Build(path []string) (*Graph, error) {
g := &Graph{Path: path}
debugName := "graph.json"
if b.Name != "" {
debugName = b.Name + "-" + debugName
}
debugBuf := dbug.NewFileWriter(debugName)
g.SetDebugWriter(debugBuf)
defer debugBuf.Close()
for _, step := range b.Steps {
if step == nil {
continue
}
stepName := fmt.Sprintf("%T", step)
dot := strings.LastIndex(stepName, ".")
if dot >= 0 {
stepName = stepName[dot+1:]
}
debugOp := g.DebugOperation(stepName, "")
err := step.Transform(g)
errMsg := ""
if err != nil {
errMsg = err.Error()
}
debugOp.End(errMsg)
log.Printf(
"[TRACE] Graph after step %T:\n\n%s",
step, g.StringWithNodeTypes())
if err != nil {
return g, err
}
}
// Validate the graph structure
if b.Validate {
if err := g.Validate(); err != nil {
log.Printf("[ERROR] Graph validation failed. Graph:\n\n%s", g.String())
return nil, err
}
}
return g, nil
}