]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/terraform/node_resource_plan_instance.go
Initial transfer of provider code
[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/config"
7 )
8
9 // NodePlannableResourceInstance represents a _single_ resource
10 // instance that is plannable. This means this represents a single
11 // count index, for example.
12 type NodePlannableResourceInstance struct {
13 *NodeAbstractResource
14 }
15
16 // GraphNodeEvalable
17 func (n *NodePlannableResourceInstance) EvalTree() EvalNode {
18 addr := n.NodeAbstractResource.Addr
19
20 // stateId is the ID to put into the state
21 stateId := addr.stateId()
22
23 // Build the instance info. More of this will be populated during eval
24 info := &InstanceInfo{
25 Id: stateId,
26 Type: addr.Type,
27 ModulePath: normalizeModulePath(addr.Path),
28 }
29
30 // Build the resource for eval
31 resource := &Resource{
32 Name: addr.Name,
33 Type: addr.Type,
34 CountIndex: addr.Index,
35 }
36 if resource.CountIndex < 0 {
37 resource.CountIndex = 0
38 }
39
40 // Determine the dependencies for the state.
41 stateDeps := n.StateReferences()
42
43 // Eval info is different depending on what kind of resource this is
44 switch n.Config.Mode {
45 case config.ManagedResourceMode:
46 return n.evalTreeManagedResource(
47 stateId, info, resource, stateDeps,
48 )
49 case config.DataResourceMode:
50 return n.evalTreeDataResource(
51 stateId, info, resource, stateDeps)
52 default:
53 panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
54 }
55 }
56
57 func (n *NodePlannableResourceInstance) evalTreeDataResource(
58 stateId string, info *InstanceInfo,
59 resource *Resource, stateDeps []string) EvalNode {
60 var provider ResourceProvider
61 var config *ResourceConfig
62 var diff *InstanceDiff
63 var state *InstanceState
64
65 return &EvalSequence{
66 Nodes: []EvalNode{
67 &EvalReadState{
68 Name: stateId,
69 Output: &state,
70 },
71
72 // We need to re-interpolate the config here because some
73 // of the attributes may have become computed during
74 // earlier planning, due to other resources having
75 // "requires new resource" diffs.
76 &EvalInterpolate{
77 Config: n.Config.RawConfig.Copy(),
78 Resource: resource,
79 Output: &config,
80 },
81
82 &EvalIf{
83 If: func(ctx EvalContext) (bool, error) {
84 computed := config.ComputedKeys != nil && len(config.ComputedKeys) > 0
85
86 // If the configuration is complete and we
87 // already have a state then we don't need to
88 // do any further work during apply, because we
89 // already populated the state during refresh.
90 if !computed && state != nil {
91 return true, EvalEarlyExitError{}
92 }
93
94 return true, nil
95 },
96 Then: EvalNoop{},
97 },
98
99 &EvalGetProvider{
100 Name: n.ProvidedBy()[0],
101 Output: &provider,
102 },
103
104 &EvalReadDataDiff{
105 Info: info,
106 Config: &config,
107 Provider: &provider,
108 Output: &diff,
109 OutputState: &state,
110 },
111
112 &EvalWriteState{
113 Name: stateId,
114 ResourceType: n.Config.Type,
115 Provider: n.Config.Provider,
116 Dependencies: stateDeps,
117 State: &state,
118 },
119
120 &EvalWriteDiff{
121 Name: stateId,
122 Diff: &diff,
123 },
124 },
125 }
126 }
127
128 func (n *NodePlannableResourceInstance) evalTreeManagedResource(
129 stateId string, info *InstanceInfo,
130 resource *Resource, stateDeps []string) EvalNode {
131 // Declare a bunch of variables that are used for state during
132 // evaluation. Most of this are written to by-address below.
133 var provider ResourceProvider
134 var diff *InstanceDiff
135 var state *InstanceState
136 var resourceConfig *ResourceConfig
137
138 return &EvalSequence{
139 Nodes: []EvalNode{
140 &EvalInterpolate{
141 Config: n.Config.RawConfig.Copy(),
142 Resource: resource,
143 Output: &resourceConfig,
144 },
145 &EvalGetProvider{
146 Name: n.ProvidedBy()[0],
147 Output: &provider,
148 },
149 // Re-run validation to catch any errors we missed, e.g. type
150 // mismatches on computed values.
151 &EvalValidateResource{
152 Provider: &provider,
153 Config: &resourceConfig,
154 ResourceName: n.Config.Name,
155 ResourceType: n.Config.Type,
156 ResourceMode: n.Config.Mode,
157 IgnoreWarnings: true,
158 },
159 &EvalReadState{
160 Name: stateId,
161 Output: &state,
162 },
163 &EvalDiff{
164 Name: stateId,
165 Info: info,
166 Config: &resourceConfig,
167 Resource: n.Config,
168 Provider: &provider,
169 State: &state,
170 OutputDiff: &diff,
171 OutputState: &state,
172 },
173 &EvalCheckPreventDestroy{
174 Resource: n.Config,
175 Diff: &diff,
176 },
177 &EvalWriteState{
178 Name: stateId,
179 ResourceType: n.Config.Type,
180 Provider: n.Config.Provider,
181 Dependencies: stateDeps,
182 State: &state,
183 },
184 &EvalWriteDiff{
185 Name: stateId,
186 Diff: &diff,
187 },
188 },
189 }
190 }