]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/terraform/node_resource_plan_instance.go
update vendor and go.mod
[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 // Eval info is different depending on what kind of resource this is
38 switch addr.Resource.Resource.Mode {
39 case addrs.ManagedResourceMode:
40 return n.evalTreeManagedResource(addr)
41 case addrs.DataResourceMode:
42 return n.evalTreeDataResource(addr)
43 default:
44 panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
45 }
46 }
47
48 func (n *NodePlannableResourceInstance) evalTreeDataResource(addr addrs.AbsResourceInstance) EvalNode {
49 config := n.Config
50 var provider providers.Interface
51 var providerSchema *ProviderSchema
52 var change *plans.ResourceInstanceChange
53 var state *states.ResourceInstanceObject
54 var configVal cty.Value
55
56 return &EvalSequence{
57 Nodes: []EvalNode{
58 &EvalGetProvider{
59 Addr: n.ResolvedProvider,
60 Output: &provider,
61 Schema: &providerSchema,
62 },
63
64 &EvalReadState{
65 Addr: addr.Resource,
66 Provider: &provider,
67 ProviderSchema: &providerSchema,
68
69 Output: &state,
70 },
71
72 // If we already have a non-planned state then we already dealt
73 // with this during the refresh walk and so we have nothing to do
74 // here.
75 &EvalIf{
76 If: func(ctx EvalContext) (bool, error) {
77 depChanges := false
78
79 // Check and see if any of our dependencies have changes.
80 changes := ctx.Changes()
81 for _, d := range n.StateReferences() {
82 ri, ok := d.(addrs.ResourceInstance)
83 if !ok {
84 continue
85 }
86 change := changes.GetResourceInstanceChange(ri.Absolute(ctx.Path()), states.CurrentGen)
87 if change != nil && change.Action != plans.NoOp {
88 depChanges = true
89 break
90 }
91 }
92
93 refreshed := state != nil && state.Status != states.ObjectPlanned
94
95 // If there are no dependency changes, and it's not a forced
96 // read because we there was no Refresh, then we don't need
97 // to re-read. If any dependencies have changes, it means
98 // our config may also have changes and we need to Read the
99 // data source again.
100 if !depChanges && refreshed {
101 return false, EvalEarlyExitError{}
102 }
103 return true, nil
104 },
105 Then: EvalNoop{},
106 },
107
108 &EvalValidateSelfRef{
109 Addr: addr.Resource,
110 Config: config.Config,
111 ProviderSchema: &providerSchema,
112 },
113
114 &EvalReadData{
115 Addr: addr.Resource,
116 Config: n.Config,
117 Dependencies: n.StateReferences(),
118 Provider: &provider,
119 ProviderAddr: n.ResolvedProvider,
120 ProviderSchema: &providerSchema,
121 ForcePlanRead: true, // _always_ produce a Read change, even if the config seems ready
122 OutputChange: &change,
123 OutputValue: &configVal,
124 OutputState: &state,
125 },
126
127 &EvalWriteState{
128 Addr: addr.Resource,
129 ProviderAddr: n.ResolvedProvider,
130 ProviderSchema: &providerSchema,
131 State: &state,
132 },
133
134 &EvalWriteDiff{
135 Addr: addr.Resource,
136 ProviderSchema: &providerSchema,
137 Change: &change,
138 },
139 },
140 }
141 }
142
143 func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsResourceInstance) EvalNode {
144 config := n.Config
145 var provider providers.Interface
146 var providerSchema *ProviderSchema
147 var change *plans.ResourceInstanceChange
148 var state *states.ResourceInstanceObject
149
150 return &EvalSequence{
151 Nodes: []EvalNode{
152 &EvalGetProvider{
153 Addr: n.ResolvedProvider,
154 Output: &provider,
155 Schema: &providerSchema,
156 },
157
158 &EvalReadState{
159 Addr: addr.Resource,
160 Provider: &provider,
161 ProviderSchema: &providerSchema,
162
163 Output: &state,
164 },
165
166 &EvalValidateSelfRef{
167 Addr: addr.Resource,
168 Config: config.Config,
169 ProviderSchema: &providerSchema,
170 },
171
172 &EvalDiff{
173 Addr: addr.Resource,
174 Config: n.Config,
175 CreateBeforeDestroy: n.ForceCreateBeforeDestroy,
176 Provider: &provider,
177 ProviderAddr: n.ResolvedProvider,
178 ProviderSchema: &providerSchema,
179 State: &state,
180 OutputChange: &change,
181 OutputState: &state,
182 },
183 &EvalCheckPreventDestroy{
184 Addr: addr.Resource,
185 Config: n.Config,
186 Change: &change,
187 },
188 &EvalWriteState{
189 Addr: addr.Resource,
190 ProviderAddr: n.ResolvedProvider,
191 State: &state,
192 ProviderSchema: &providerSchema,
193 },
194 &EvalWriteDiff{
195 Addr: addr.Resource,
196 ProviderSchema: &providerSchema,
197 Change: &change,
198 },
199 },
200 }
201 }