]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - vendor/github.com/hashicorp/terraform/terraform/node_resource_plan_instance.go
Merge branch 'fix_read_test' of github.com:alexandreFre/terraform-provider-statuscake
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / node_resource_plan_instance.go
CommitLineData
bae9f6d2
JC
1package terraform
2
3import (
4 "fmt"
5
107c1cdb
ND
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"
bae9f6d2
JC
12)
13
14// NodePlannableResourceInstance represents a _single_ resource
15// instance that is plannable. This means this represents a single
16// count index, for example.
17type NodePlannableResourceInstance struct {
107c1cdb
ND
18 *NodeAbstractResourceInstance
19 ForceCreateBeforeDestroy bool
bae9f6d2
JC
20}
21
107c1cdb
ND
22var (
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
bae9f6d2
JC
33// GraphNodeEvalable
34func (n *NodePlannableResourceInstance) EvalTree() EvalNode {
107c1cdb 35 addr := n.ResourceInstanceAddr()
bae9f6d2 36
107c1cdb
ND
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()
bae9f6d2
JC
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
107c1cdb
ND
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)
bae9f6d2
JC
50 default:
51 panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
52 }
53}
54
107c1cdb
ND
55func (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
bae9f6d2
JC
62
63 return &EvalSequence{
64 Nodes: []EvalNode{
107c1cdb
ND
65 &EvalGetProvider{
66 Addr: n.ResolvedProvider,
67 Output: &provider,
68 Schema: &providerSchema,
bae9f6d2
JC
69 },
70
107c1cdb
ND
71 &EvalReadState{
72 Addr: addr.Resource,
73 Provider: &provider,
74 ProviderSchema: &providerSchema,
75
76 Output: &state,
bae9f6d2
JC
77 },
78
107c1cdb
ND
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.
bae9f6d2
JC
82 &EvalIf{
83 If: func(ctx EvalContext) (bool, error) {
107c1cdb
ND
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 }
bae9f6d2
JC
98 }
99
107c1cdb
ND
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 }
bae9f6d2
JC
110 return true, nil
111 },
112 Then: EvalNoop{},
113 },
114
107c1cdb
ND
115 &EvalValidateSelfRef{
116 Addr: addr.Resource,
117 Config: config.Config,
118 ProviderSchema: &providerSchema,
bae9f6d2
JC
119 },
120
107c1cdb
ND
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,
bae9f6d2
JC
132 },
133
134 &EvalWriteState{
107c1cdb
ND
135 Addr: addr.Resource,
136 ProviderAddr: n.ResolvedProvider,
137 ProviderSchema: &providerSchema,
138 State: &state,
bae9f6d2
JC
139 },
140
141 &EvalWriteDiff{
107c1cdb
ND
142 Addr: addr.Resource,
143 ProviderSchema: &providerSchema,
144 Change: &change,
bae9f6d2
JC
145 },
146 },
147 }
148}
149
107c1cdb
ND
150func (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
bae9f6d2
JC
156
157 return &EvalSequence{
158 Nodes: []EvalNode{
bae9f6d2 159 &EvalGetProvider{
107c1cdb 160 Addr: n.ResolvedProvider,
bae9f6d2 161 Output: &provider,
107c1cdb 162 Schema: &providerSchema,
bae9f6d2 163 },
107c1cdb 164
bae9f6d2 165 &EvalReadState{
107c1cdb
ND
166 Addr: addr.Resource,
167 Provider: &provider,
168 ProviderSchema: &providerSchema,
169
bae9f6d2
JC
170 Output: &state,
171 },
107c1cdb
ND
172
173 &EvalValidateSelfRef{
174 Addr: addr.Resource,
175 Config: config.Config,
176 ProviderSchema: &providerSchema,
177 },
178
bae9f6d2 179 &EvalDiff{
107c1cdb
ND
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,
bae9f6d2
JC
189 },
190 &EvalCheckPreventDestroy{
107c1cdb
ND
191 Addr: addr.Resource,
192 Config: n.Config,
193 Change: &change,
bae9f6d2
JC
194 },
195 &EvalWriteState{
107c1cdb
ND
196 Addr: addr.Resource,
197 ProviderAddr: n.ResolvedProvider,
198 State: &state,
199 ProviderSchema: &providerSchema,
bae9f6d2
JC
200 },
201 &EvalWriteDiff{
107c1cdb
ND
202 Addr: addr.Resource,
203 ProviderSchema: &providerSchema,
204 Change: &change,
bae9f6d2
JC
205 },
206 },
207 }
208}