]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/terraform/node_resource_plan_instance.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / node_resource_plan_instance.go
1 package terraform
2
3 import (
4 "fmt"
5
6 "github.com/hashicorp/terraform/plans"
7 "github.com/hashicorp/terraform/providers"
8 "github.com/hashicorp/terraform/states"
9
10 "github.com/hashicorp/terraform/addrs"
11 "github.com/zclconf/go-cty/cty"
12 )
13
14 // NodePlannableResourceInstance represents a _single_ resource
15 // instance that is plannable. This means this represents a single
16 // count index, for example.
17 type NodePlannableResourceInstance struct {
18 *NodeAbstractResourceInstance
19 ForceCreateBeforeDestroy bool
20 }
21
22 var (
23 _ GraphNodeSubPath = (*NodePlannableResourceInstance)(nil)
24 _ GraphNodeReferenceable = (*NodePlannableResourceInstance)(nil)
25 _ GraphNodeReferencer = (*NodePlannableResourceInstance)(nil)
26 _ GraphNodeResource = (*NodePlannableResourceInstance)(nil)
27 _ GraphNodeResourceInstance = (*NodePlannableResourceInstance)(nil)
28 _ GraphNodeAttachResourceConfig = (*NodePlannableResourceInstance)(nil)
29 _ GraphNodeAttachResourceState = (*NodePlannableResourceInstance)(nil)
30 _ GraphNodeEvalable = (*NodePlannableResourceInstance)(nil)
31 )
32
33 // GraphNodeEvalable
34 func (n *NodePlannableResourceInstance) EvalTree() EvalNode {
35 addr := n.ResourceInstanceAddr()
36
37 // State still uses legacy-style internal ids, so we need to shim to get
38 // a suitable key to use.
39 stateId := NewLegacyResourceInstanceAddress(addr).stateId()
40
41 // Determine the dependencies for the state.
42 stateDeps := n.StateReferences()
43
44 // Eval info is different depending on what kind of resource this is
45 switch addr.Resource.Resource.Mode {
46 case addrs.ManagedResourceMode:
47 return n.evalTreeManagedResource(addr, stateId, stateDeps)
48 case addrs.DataResourceMode:
49 return n.evalTreeDataResource(addr, stateId, stateDeps)
50 default:
51 panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
52 }
53 }
54
55 func (n *NodePlannableResourceInstance) evalTreeDataResource(addr addrs.AbsResourceInstance, stateId string, stateDeps []addrs.Referenceable) EvalNode {
56 config := n.Config
57 var provider providers.Interface
58 var providerSchema *ProviderSchema
59 var change *plans.ResourceInstanceChange
60 var state *states.ResourceInstanceObject
61 var configVal cty.Value
62
63 return &EvalSequence{
64 Nodes: []EvalNode{
65 &EvalGetProvider{
66 Addr: n.ResolvedProvider,
67 Output: &provider,
68 Schema: &providerSchema,
69 },
70
71 &EvalReadState{
72 Addr: addr.Resource,
73 Provider: &provider,
74 ProviderSchema: &providerSchema,
75
76 Output: &state,
77 },
78
79 // If we already have a non-planned state then we already dealt
80 // with this during the refresh walk and so we have nothing to do
81 // here.
82 &EvalIf{
83 If: func(ctx EvalContext) (bool, error) {
84 depChanges := false
85
86 // Check and see if any of our dependencies have changes.
87 changes := ctx.Changes()
88 for _, d := range n.StateReferences() {
89 ri, ok := d.(addrs.ResourceInstance)
90 if !ok {
91 continue
92 }
93 change := changes.GetResourceInstanceChange(ri.Absolute(ctx.Path()), states.CurrentGen)
94 if change != nil && change.Action != plans.NoOp {
95 depChanges = true
96 break
97 }
98 }
99
100 refreshed := state != nil && state.Status != states.ObjectPlanned
101
102 // If there are no dependency changes, and it's not a forced
103 // read because we there was no Refresh, then we don't need
104 // to re-read. If any dependencies have changes, it means
105 // our config may also have changes and we need to Read the
106 // data source again.
107 if !depChanges && refreshed {
108 return false, EvalEarlyExitError{}
109 }
110 return true, nil
111 },
112 Then: EvalNoop{},
113 },
114
115 &EvalValidateSelfRef{
116 Addr: addr.Resource,
117 Config: config.Config,
118 ProviderSchema: &providerSchema,
119 },
120
121 &EvalReadData{
122 Addr: addr.Resource,
123 Config: n.Config,
124 Dependencies: n.StateReferences(),
125 Provider: &provider,
126 ProviderAddr: n.ResolvedProvider,
127 ProviderSchema: &providerSchema,
128 ForcePlanRead: true, // _always_ produce a Read change, even if the config seems ready
129 OutputChange: &change,
130 OutputValue: &configVal,
131 OutputState: &state,
132 },
133
134 &EvalWriteState{
135 Addr: addr.Resource,
136 ProviderAddr: n.ResolvedProvider,
137 ProviderSchema: &providerSchema,
138 State: &state,
139 },
140
141 &EvalWriteDiff{
142 Addr: addr.Resource,
143 ProviderSchema: &providerSchema,
144 Change: &change,
145 },
146 },
147 }
148 }
149
150 func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsResourceInstance, stateId string, stateDeps []addrs.Referenceable) EvalNode {
151 config := n.Config
152 var provider providers.Interface
153 var providerSchema *ProviderSchema
154 var change *plans.ResourceInstanceChange
155 var state *states.ResourceInstanceObject
156
157 return &EvalSequence{
158 Nodes: []EvalNode{
159 &EvalGetProvider{
160 Addr: n.ResolvedProvider,
161 Output: &provider,
162 Schema: &providerSchema,
163 },
164
165 &EvalReadState{
166 Addr: addr.Resource,
167 Provider: &provider,
168 ProviderSchema: &providerSchema,
169
170 Output: &state,
171 },
172
173 &EvalValidateSelfRef{
174 Addr: addr.Resource,
175 Config: config.Config,
176 ProviderSchema: &providerSchema,
177 },
178
179 &EvalDiff{
180 Addr: addr.Resource,
181 Config: n.Config,
182 CreateBeforeDestroy: n.ForceCreateBeforeDestroy,
183 Provider: &provider,
184 ProviderAddr: n.ResolvedProvider,
185 ProviderSchema: &providerSchema,
186 State: &state,
187 OutputChange: &change,
188 OutputState: &state,
189 },
190 &EvalCheckPreventDestroy{
191 Addr: addr.Resource,
192 Config: n.Config,
193 Change: &change,
194 },
195 &EvalWriteState{
196 Addr: addr.Resource,
197 ProviderAddr: n.ResolvedProvider,
198 State: &state,
199 ProviderSchema: &providerSchema,
200 },
201 &EvalWriteDiff{
202 Addr: addr.Resource,
203 ProviderSchema: &providerSchema,
204 Change: &change,
205 },
206 },
207 }
208 }