github.com/iaas-resource-provision/iaas-rpc@v1.0.7-0.20211021023331-ed21f798c408/internal/terraform/graph_builder.go (about)

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