github.com/ves/terraform@v0.8.0-beta2/terraform/node_resource_plan.go (about)

     1  package terraform
     2  
     3  import (
     4  	"github.com/hashicorp/terraform/dag"
     5  )
     6  
     7  // NodePlannableResource represents a resource that is "plannable":
     8  // it is ready to be planned in order to create a diff.
     9  type NodePlannableResource struct {
    10  	*NodeAbstractResource
    11  
    12  	// Set by GraphNodeTargetable and used during DynamicExpand to
    13  	// forward targets downwards.
    14  	targets []ResourceAddress
    15  }
    16  
    17  // GraphNodeTargetable
    18  func (n *NodePlannableResource) SetTargets(targets []ResourceAddress) {
    19  	n.targets = targets
    20  }
    21  
    22  // GraphNodeEvalable
    23  func (n *NodePlannableResource) EvalTree() EvalNode {
    24  	return &EvalSequence{
    25  		Nodes: []EvalNode{
    26  			// The EvalTree for a plannable resource primarily involves
    27  			// interpolating the count since it can contain variables
    28  			// we only just received access to.
    29  			//
    30  			// With the interpolated count, we can then DynamicExpand
    31  			// into the proper number of instances.
    32  			&EvalInterpolate{Config: n.Config.RawCount},
    33  
    34  			&EvalCountCheckComputed{Resource: n.Config},
    35  			&EvalCountFixZeroOneBoundary{Resource: n.Config},
    36  		},
    37  	}
    38  }
    39  
    40  // GraphNodeDynamicExpandable
    41  func (n *NodePlannableResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
    42  	// Grab the state which we read
    43  	state, lock := ctx.State()
    44  	lock.RLock()
    45  	defer lock.RUnlock()
    46  
    47  	// Expand the resource count which must be available by now from EvalTree
    48  	count, err := n.Config.Count()
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	// The concrete resource factory we'll use
    54  	concreteResource := func(a *NodeAbstractResource) dag.Vertex {
    55  		// Add the config and state since we don't do that via transforms
    56  		a.Config = n.Config
    57  
    58  		return &NodePlannableResourceInstance{
    59  			NodeAbstractResource: a,
    60  		}
    61  	}
    62  
    63  	// The concrete resource factory we'll use for oprhans
    64  	concreteResourceOrphan := func(a *NodeAbstractResource) dag.Vertex {
    65  		// Add the config and state since we don't do that via transforms
    66  		a.Config = n.Config
    67  
    68  		return &NodePlannableResourceOrphan{
    69  			NodeAbstractResource: a,
    70  		}
    71  	}
    72  
    73  	// Start creating the steps
    74  	steps := []GraphTransformer{
    75  		// Expand the count.
    76  		&ResourceCountTransformer{
    77  			Concrete: concreteResource,
    78  			Count:    count,
    79  			Addr:     n.ResourceAddr(),
    80  		},
    81  
    82  		// Add the count orphans
    83  		&OrphanResourceCountTransformer{
    84  			Concrete: concreteResourceOrphan,
    85  			Count:    count,
    86  			Addr:     n.ResourceAddr(),
    87  			State:    state,
    88  		},
    89  
    90  		// Attach the state
    91  		&AttachStateTransformer{State: state},
    92  
    93  		// Targeting
    94  		&TargetsTransformer{ParsedTargets: n.targets},
    95  
    96  		// Connect references so ordering is correct
    97  		&ReferenceTransformer{},
    98  
    99  		// Make sure there is a single root
   100  		&RootTransformer{},
   101  	}
   102  
   103  	// Build the graph
   104  	b := &BasicGraphBuilder{Steps: steps, Validate: true}
   105  	return b.Build(ctx.Path())
   106  }