78 lines
1.6 KiB
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
|
|
}
|