]>
Commit | Line | Data |
---|---|---|
bae9f6d2 JC |
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 | } |