github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/terraform/node_resource_refresh.go (about)

     1  package terraform
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hashicorp/terraform/config"
     7  )
     8  
     9  // NodeRefreshableResource represents a resource that is "applyable":
    10  // it is ready to be applied and is represented by a diff.
    11  type NodeRefreshableResource struct {
    12  	*NodeAbstractResource
    13  }
    14  
    15  // GraphNodeDestroyer
    16  func (n *NodeRefreshableResource) DestroyAddr() *ResourceAddress {
    17  	return n.Addr
    18  }
    19  
    20  // GraphNodeEvalable
    21  func (n *NodeRefreshableResource) EvalTree() EvalNode {
    22  	// Eval info is different depending on what kind of resource this is
    23  	switch mode := n.Addr.Mode; mode {
    24  	case config.ManagedResourceMode:
    25  		return n.evalTreeManagedResource()
    26  
    27  	case config.DataResourceMode:
    28  		// Get the data source node. If we don't have a configuration
    29  		// then it is an orphan so we destroy it (remove it from the state).
    30  		var dn GraphNodeEvalable
    31  		if n.Config != nil {
    32  			dn = &NodeRefreshableDataResourceInstance{
    33  				NodeAbstractResource: n.NodeAbstractResource,
    34  			}
    35  		} else {
    36  			dn = &NodeDestroyableDataResource{
    37  				NodeAbstractResource: n.NodeAbstractResource,
    38  			}
    39  		}
    40  
    41  		return dn.EvalTree()
    42  	default:
    43  		panic(fmt.Errorf("unsupported resource mode %s", mode))
    44  	}
    45  }
    46  
    47  func (n *NodeRefreshableResource) evalTreeManagedResource() EvalNode {
    48  	addr := n.NodeAbstractResource.Addr
    49  
    50  	// stateId is the ID to put into the state
    51  	stateId := addr.stateId()
    52  
    53  	// Build the instance info. More of this will be populated during eval
    54  	info := &InstanceInfo{
    55  		Id:   stateId,
    56  		Type: addr.Type,
    57  	}
    58  
    59  	// Declare a bunch of variables that are used for state during
    60  	// evaluation. Most of this are written to by-address below.
    61  	var provider ResourceProvider
    62  	var state *InstanceState
    63  
    64  	// This happened during initial development. All known cases were
    65  	// fixed and tested but as a sanity check let's assert here.
    66  	if n.ResourceState == nil {
    67  		err := fmt.Errorf(
    68  			"No resource state attached for addr: %s\n\n"+
    69  				"This is a bug. Please report this to Terraform with your configuration\n"+
    70  				"and state attached. Please be careful to scrub any sensitive information.",
    71  			addr)
    72  		return &EvalReturnError{Error: &err}
    73  	}
    74  
    75  	return &EvalSequence{
    76  		Nodes: []EvalNode{
    77  			&EvalGetProvider{
    78  				Name:   n.ProvidedBy()[0],
    79  				Output: &provider,
    80  			},
    81  			&EvalReadState{
    82  				Name:   stateId,
    83  				Output: &state,
    84  			},
    85  			&EvalRefresh{
    86  				Info:     info,
    87  				Provider: &provider,
    88  				State:    &state,
    89  				Output:   &state,
    90  			},
    91  			&EvalWriteState{
    92  				Name:         stateId,
    93  				ResourceType: n.ResourceState.Type,
    94  				Provider:     n.ResourceState.Provider,
    95  				Dependencies: n.ResourceState.Dependencies,
    96  				State:        &state,
    97  			},
    98  		},
    99  	}
   100  }