github.com/Hashicorp/terraform@v0.11.12-beta1/terraform/transform_output.go (about)

     1  package terraform
     2  
     3  import (
     4  	"log"
     5  
     6  	"github.com/hashicorp/terraform/config/module"
     7  	"github.com/hashicorp/terraform/dag"
     8  )
     9  
    10  // OutputTransformer is a GraphTransformer that adds all the outputs
    11  // in the configuration to the graph.
    12  //
    13  // This is done for the apply graph builder even if dependent nodes
    14  // aren't changing since there is no downside: the state will be available
    15  // even if the dependent items aren't changing.
    16  type OutputTransformer struct {
    17  	Module *module.Tree
    18  }
    19  
    20  func (t *OutputTransformer) Transform(g *Graph) error {
    21  	return t.transform(g, t.Module)
    22  }
    23  
    24  func (t *OutputTransformer) transform(g *Graph, m *module.Tree) error {
    25  	// If no config, no outputs
    26  	if m == nil {
    27  		return nil
    28  	}
    29  
    30  	// Transform all the children. We must do this first because
    31  	// we can reference module outputs and they must show up in the
    32  	// reference map.
    33  	for _, c := range m.Children() {
    34  		if err := t.transform(g, c); err != nil {
    35  			return err
    36  		}
    37  	}
    38  
    39  	// If we have no outputs, we're done!
    40  	os := m.Config().Outputs
    41  	if len(os) == 0 {
    42  		return nil
    43  	}
    44  
    45  	// Add all outputs here
    46  	for _, o := range os {
    47  		node := &NodeApplyableOutput{
    48  			PathValue: normalizeModulePath(m.Path()),
    49  			Config:    o,
    50  		}
    51  
    52  		// Add it!
    53  		g.Add(node)
    54  	}
    55  
    56  	return nil
    57  }
    58  
    59  // DestroyOutputTransformer is a GraphTransformer that adds nodes to delete
    60  // outputs during destroy. We need to do this to ensure that no stale outputs
    61  // are ever left in the state.
    62  type DestroyOutputTransformer struct {
    63  }
    64  
    65  func (t *DestroyOutputTransformer) Transform(g *Graph) error {
    66  	for _, v := range g.Vertices() {
    67  		output, ok := v.(*NodeApplyableOutput)
    68  		if !ok {
    69  			continue
    70  		}
    71  
    72  		// create the destroy node for this output
    73  		node := &NodeDestroyableOutput{
    74  			PathValue: output.PathValue,
    75  			Config:    output.Config,
    76  		}
    77  
    78  		log.Printf("[TRACE] creating %s", node.Name())
    79  		g.Add(node)
    80  
    81  		deps, err := g.Descendents(v)
    82  		if err != nil {
    83  			return err
    84  		}
    85  
    86  		// the destroy node must depend on the eval node
    87  		deps.Add(v)
    88  
    89  		for _, d := range deps.List() {
    90  			log.Printf("[TRACE] %s depends on %s", node.Name(), dag.VertexName(d))
    91  			g.Connect(dag.BasicEdge(node, d))
    92  		}
    93  	}
    94  	return nil
    95  }