github.com/davebizus/terraform-main@v0.11.12-beta1/terraform/graph_builder_plan.go (about)

     1  package terraform
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/hashicorp/terraform/config/module"
     7  	"github.com/hashicorp/terraform/dag"
     8  )
     9  
    10  // PlanGraphBuilder implements GraphBuilder and is responsible for building
    11  // a graph for planning (creating a Terraform Diff).
    12  //
    13  // The primary difference between this graph and others:
    14  //
    15  //   * Based on the config since it represents the target state
    16  //
    17  //   * Ignores lifecycle options since no lifecycle events occur here. This
    18  //     simplifies the graph significantly since complex transforms such as
    19  //     create-before-destroy can be completely ignored.
    20  //
    21  type PlanGraphBuilder struct {
    22  	// Module is the root module for the graph to build.
    23  	Module *module.Tree
    24  
    25  	// State is the current state
    26  	State *State
    27  
    28  	// Providers is the list of providers supported.
    29  	Providers []string
    30  
    31  	// Provisioners is the list of provisioners supported.
    32  	Provisioners []string
    33  
    34  	// Targets are resources to target
    35  	Targets []string
    36  
    37  	// DisableReduce, if true, will not reduce the graph. Great for testing.
    38  	DisableReduce bool
    39  
    40  	// Validate will do structural validation of the graph.
    41  	Validate bool
    42  
    43  	// CustomConcrete can be set to customize the node types created
    44  	// for various parts of the plan. This is useful in order to customize
    45  	// the plan behavior.
    46  	CustomConcrete         bool
    47  	ConcreteProvider       ConcreteProviderNodeFunc
    48  	ConcreteResource       ConcreteResourceNodeFunc
    49  	ConcreteResourceOrphan ConcreteResourceNodeFunc
    50  
    51  	once sync.Once
    52  }
    53  
    54  // See GraphBuilder
    55  func (b *PlanGraphBuilder) Build(path []string) (*Graph, error) {
    56  	return (&BasicGraphBuilder{
    57  		Steps:    b.Steps(),
    58  		Validate: b.Validate,
    59  		Name:     "PlanGraphBuilder",
    60  	}).Build(path)
    61  }
    62  
    63  // See GraphBuilder
    64  func (b *PlanGraphBuilder) Steps() []GraphTransformer {
    65  	b.once.Do(b.init)
    66  
    67  	steps := []GraphTransformer{
    68  		// Creates all the resources represented in the config
    69  		&ConfigTransformer{
    70  			Concrete: b.ConcreteResource,
    71  			Module:   b.Module,
    72  		},
    73  
    74  		// Add the local values
    75  		&LocalTransformer{Module: b.Module},
    76  
    77  		// Add the outputs
    78  		&OutputTransformer{Module: b.Module},
    79  
    80  		// Add orphan resources
    81  		&OrphanResourceTransformer{
    82  			Concrete: b.ConcreteResourceOrphan,
    83  			State:    b.State,
    84  			Module:   b.Module,
    85  		},
    86  
    87  		// Create orphan output nodes
    88  		&OrphanOutputTransformer{
    89  			Module: b.Module,
    90  			State:  b.State,
    91  		},
    92  
    93  		// Attach the configuration to any resources
    94  		&AttachResourceConfigTransformer{Module: b.Module},
    95  
    96  		// Attach the state
    97  		&AttachStateTransformer{State: b.State},
    98  
    99  		// Add root variables
   100  		&RootVariableTransformer{Module: b.Module},
   101  
   102  		TransformProviders(b.Providers, b.ConcreteProvider, b.Module),
   103  
   104  		// Provisioner-related transformations. Only add these if requested.
   105  		GraphTransformIf(
   106  			func() bool { return b.Provisioners != nil },
   107  			GraphTransformMulti(
   108  				&MissingProvisionerTransformer{Provisioners: b.Provisioners},
   109  				&ProvisionerTransformer{},
   110  			),
   111  		),
   112  
   113  		// Add module variables
   114  		&ModuleVariableTransformer{
   115  			Module: b.Module,
   116  		},
   117  
   118  		// Remove modules no longer present in the config
   119  		&RemovedModuleTransformer{Module: b.Module, State: b.State},
   120  
   121  		// Connect so that the references are ready for targeting. We'll
   122  		// have to connect again later for providers and so on.
   123  		&ReferenceTransformer{},
   124  
   125  		// Add the node to fix the state count boundaries
   126  		&CountBoundaryTransformer{},
   127  
   128  		// Target
   129  		&TargetsTransformer{
   130  			Targets: b.Targets,
   131  
   132  			// Resource nodes from config have not yet been expanded for
   133  			// "count", so we must apply targeting without indices. Exact
   134  			// targeting will be dealt with later when these resources
   135  			// DynamicExpand.
   136  			IgnoreIndices: true,
   137  		},
   138  
   139  		// Close opened plugin connections
   140  		&CloseProviderTransformer{},
   141  		&CloseProvisionerTransformer{},
   142  
   143  		// Single root
   144  		&RootTransformer{},
   145  	}
   146  
   147  	if !b.DisableReduce {
   148  		// Perform the transitive reduction to make our graph a bit
   149  		// more sane if possible (it usually is possible).
   150  		steps = append(steps, &TransitiveReductionTransformer{})
   151  	}
   152  
   153  	return steps
   154  }
   155  
   156  func (b *PlanGraphBuilder) init() {
   157  	// Do nothing if the user requests customizing the fields
   158  	if b.CustomConcrete {
   159  		return
   160  	}
   161  
   162  	b.ConcreteProvider = func(a *NodeAbstractProvider) dag.Vertex {
   163  		return &NodeApplyableProvider{
   164  			NodeAbstractProvider: a,
   165  		}
   166  	}
   167  
   168  	b.ConcreteResource = func(a *NodeAbstractResource) dag.Vertex {
   169  		return &NodePlannableResource{
   170  			NodeAbstractCountResource: &NodeAbstractCountResource{
   171  				NodeAbstractResource: a,
   172  			},
   173  		}
   174  	}
   175  
   176  	b.ConcreteResourceOrphan = func(a *NodeAbstractResource) dag.Vertex {
   177  		return &NodePlannableResourceOrphan{
   178  			NodeAbstractResource: a,
   179  		}
   180  	}
   181  }