github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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 }