aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/terraform/states/module.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/states/module.go')
-rw-r--r--vendor/github.com/hashicorp/terraform/states/module.go285
1 files changed, 285 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/states/module.go b/vendor/github.com/hashicorp/terraform/states/module.go
new file mode 100644
index 0000000..d89e787
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/states/module.go
@@ -0,0 +1,285 @@
1package states
2
3import (
4 "github.com/zclconf/go-cty/cty"
5
6 "github.com/hashicorp/terraform/addrs"
7)
8
9// Module is a container for the states of objects within a particular module.
10type Module struct {
11 Addr addrs.ModuleInstance
12
13 // Resources contains the state for each resource. The keys in this map are
14 // an implementation detail and must not be used by outside callers.
15 Resources map[string]*Resource
16
17 // OutputValues contains the state for each output value. The keys in this
18 // map are output value names.
19 OutputValues map[string]*OutputValue
20
21 // LocalValues contains the value for each named output value. The keys
22 // in this map are local value names.
23 LocalValues map[string]cty.Value
24}
25
26// NewModule constructs an empty module state for the given module address.
27func NewModule(addr addrs.ModuleInstance) *Module {
28 return &Module{
29 Addr: addr,
30 Resources: map[string]*Resource{},
31 OutputValues: map[string]*OutputValue{},
32 LocalValues: map[string]cty.Value{},
33 }
34}
35
36// Resource returns the state for the resource with the given address within
37// the receiving module state, or nil if the requested resource is not tracked
38// in the state.
39func (ms *Module) Resource(addr addrs.Resource) *Resource {
40 return ms.Resources[addr.String()]
41}
42
43// ResourceInstance returns the state for the resource instance with the given
44// address within the receiving module state, or nil if the requested instance
45// is not tracked in the state.
46func (ms *Module) ResourceInstance(addr addrs.ResourceInstance) *ResourceInstance {
47 rs := ms.Resource(addr.Resource)
48 if rs == nil {
49 return nil
50 }
51 return rs.Instance(addr.Key)
52}
53
54// SetResourceMeta updates the resource-level metadata for the resource
55// with the given address, creating the resource state for it if it doesn't
56// already exist.
57func (ms *Module) SetResourceMeta(addr addrs.Resource, eachMode EachMode, provider addrs.AbsProviderConfig) {
58 rs := ms.Resource(addr)
59 if rs == nil {
60 rs = &Resource{
61 Addr: addr,
62 Instances: map[addrs.InstanceKey]*ResourceInstance{},
63 }
64 ms.Resources[addr.String()] = rs
65 }
66
67 rs.EachMode = eachMode
68 rs.ProviderConfig = provider
69}
70
71// RemoveResource removes the entire state for the given resource, taking with
72// it any instances associated with the resource. This should generally be
73// called only for resource objects whose instances have all been destroyed.
74func (ms *Module) RemoveResource(addr addrs.Resource) {
75 delete(ms.Resources, addr.String())
76}
77
78// SetResourceInstanceCurrent saves the given instance object as the current
79// generation of the resource instance with the given address, simulataneously
80// updating the recorded provider configuration address, dependencies, and
81// resource EachMode.
82//
83// Any existing current instance object for the given resource is overwritten.
84// Set obj to nil to remove the primary generation object altogether. If there
85// are no deposed objects then the instance will be removed altogether.
86//
87// The provider address and "each mode" are resource-wide settings and so they
88// are updated for all other instances of the same resource as a side-effect of
89// this call.
90func (ms *Module) SetResourceInstanceCurrent(addr addrs.ResourceInstance, obj *ResourceInstanceObjectSrc, provider addrs.AbsProviderConfig) {
91 ms.SetResourceMeta(addr.Resource, eachModeForInstanceKey(addr.Key), provider)
92
93 rs := ms.Resource(addr.Resource)
94 is := rs.EnsureInstance(addr.Key)
95
96 is.Current = obj
97
98 if !is.HasObjects() {
99 // If we have no objects at all then we'll clean up.
100 delete(rs.Instances, addr.Key)
101 }
102 if rs.EachMode == NoEach && len(rs.Instances) == 0 {
103 // Also clean up if we only expect to have one instance anyway
104 // and there are none. We leave the resource behind if an each mode
105 // is active because an empty list or map of instances is a valid state.
106 delete(ms.Resources, addr.Resource.String())
107 }
108}
109
110// SetResourceInstanceDeposed saves the given instance object as a deposed
111// generation of the resource instance with the given address and deposed key.
112//
113// Call this method only for pre-existing deposed objects that already have
114// a known DeposedKey. For example, this method is useful if reloading objects
115// that were persisted to a state file. To mark the current object as deposed,
116// use DeposeResourceInstanceObject instead.
117//
118// The resource that contains the given instance must already exist in the
119// state, or this method will panic. Use Resource to check first if its
120// presence is not already guaranteed.
121//
122// Any existing current instance object for the given resource and deposed key
123// is overwritten. Set obj to nil to remove the deposed object altogether. If
124// the instance is left with no objects after this operation then it will
125// be removed from its containing resource altogether.
126func (ms *Module) SetResourceInstanceDeposed(addr addrs.ResourceInstance, key DeposedKey, obj *ResourceInstanceObjectSrc, provider addrs.AbsProviderConfig) {
127 ms.SetResourceMeta(addr.Resource, eachModeForInstanceKey(addr.Key), provider)
128
129 rs := ms.Resource(addr.Resource)
130 is := rs.EnsureInstance(addr.Key)
131 if obj != nil {
132 is.Deposed[key] = obj
133 } else {
134 delete(is.Deposed, key)
135 }
136
137 if !is.HasObjects() {
138 // If we have no objects at all then we'll clean up.
139 delete(rs.Instances, addr.Key)
140 }
141 if rs.EachMode == NoEach && len(rs.Instances) == 0 {
142 // Also clean up if we only expect to have one instance anyway
143 // and there are none. We leave the resource behind if an each mode
144 // is active because an empty list or map of instances is a valid state.
145 delete(ms.Resources, addr.Resource.String())
146 }
147}
148
149// ForgetResourceInstanceAll removes the record of all objects associated with
150// the specified resource instance, if present. If not present, this is a no-op.
151func (ms *Module) ForgetResourceInstanceAll(addr addrs.ResourceInstance) {
152 rs := ms.Resource(addr.Resource)
153 if rs == nil {
154 return
155 }
156 delete(rs.Instances, addr.Key)
157
158 if rs.EachMode == NoEach && len(rs.Instances) == 0 {
159 // Also clean up if we only expect to have one instance anyway
160 // and there are none. We leave the resource behind if an each mode
161 // is active because an empty list or map of instances is a valid state.
162 delete(ms.Resources, addr.Resource.String())
163 }
164}
165
166// ForgetResourceInstanceDeposed removes the record of the deposed object with
167// the given address and key, if present. If not present, this is a no-op.
168func (ms *Module) ForgetResourceInstanceDeposed(addr addrs.ResourceInstance, key DeposedKey) {
169 rs := ms.Resource(addr.Resource)
170 if rs == nil {
171 return
172 }
173 is := rs.Instance(addr.Key)
174 if is == nil {
175 return
176 }
177 delete(is.Deposed, key)
178
179 if !is.HasObjects() {
180 // If we have no objects at all then we'll clean up.
181 delete(rs.Instances, addr.Key)
182 }
183 if rs.EachMode == NoEach && len(rs.Instances) == 0 {
184 // Also clean up if we only expect to have one instance anyway
185 // and there are none. We leave the resource behind if an each mode
186 // is active because an empty list or map of instances is a valid state.
187 delete(ms.Resources, addr.Resource.String())
188 }
189}
190
191// deposeResourceInstanceObject is the real implementation of
192// SyncState.DeposeResourceInstanceObject.
193func (ms *Module) deposeResourceInstanceObject(addr addrs.ResourceInstance, forceKey DeposedKey) DeposedKey {
194 is := ms.ResourceInstance(addr)
195 if is == nil {
196 return NotDeposed
197 }
198 return is.deposeCurrentObject(forceKey)
199}
200
201// maybeRestoreResourceInstanceDeposed is the real implementation of
202// SyncState.MaybeRestoreResourceInstanceDeposed.
203func (ms *Module) maybeRestoreResourceInstanceDeposed(addr addrs.ResourceInstance, key DeposedKey) bool {
204 rs := ms.Resource(addr.Resource)
205 if rs == nil {
206 return false
207 }
208 is := rs.Instance(addr.Key)
209 if is == nil {
210 return false
211 }
212 if is.Current != nil {
213 return false
214 }
215 if len(is.Deposed) == 0 {
216 return false
217 }
218 is.Current = is.Deposed[key]
219 delete(is.Deposed, key)
220 return true
221}
222
223// SetOutputValue writes an output value into the state, overwriting any
224// existing value of the same name.
225func (ms *Module) SetOutputValue(name string, value cty.Value, sensitive bool) *OutputValue {
226 os := &OutputValue{
227 Value: value,
228 Sensitive: sensitive,
229 }
230 ms.OutputValues[name] = os
231 return os
232}
233
234// RemoveOutputValue removes the output value of the given name from the state,
235// if it exists. This method is a no-op if there is no value of the given
236// name.
237func (ms *Module) RemoveOutputValue(name string) {
238 delete(ms.OutputValues, name)
239}
240
241// SetLocalValue writes a local value into the state, overwriting any
242// existing value of the same name.
243func (ms *Module) SetLocalValue(name string, value cty.Value) {
244 ms.LocalValues[name] = value
245}
246
247// RemoveLocalValue removes the local value of the given name from the state,
248// if it exists. This method is a no-op if there is no value of the given
249// name.
250func (ms *Module) RemoveLocalValue(name string) {
251 delete(ms.LocalValues, name)
252}
253
254// PruneResourceHusks is a specialized method that will remove any Resource
255// objects that do not contain any instances, even if they have an EachMode.
256//
257// You probably shouldn't call this! See the method of the same name on
258// type State for more information on what this is for and the rare situations
259// where it is safe to use.
260func (ms *Module) PruneResourceHusks() {
261 for _, rs := range ms.Resources {
262 if len(rs.Instances) == 0 {
263 ms.RemoveResource(rs.Addr)
264 }
265 }
266}
267
268// empty returns true if the receving module state is contributing nothing
269// to the state. In other words, it returns true if the module could be
270// removed from the state altogether without changing the meaning of the state.
271//
272// In practice a module containing no objects is the same as a non-existent
273// module, and so we can opportunistically clean up once a module becomes
274// empty on the assumption that it will be re-added if needed later.
275func (ms *Module) empty() bool {
276 if ms == nil {
277 return true
278 }
279
280 // This must be updated to cover any new collections added to Module
281 // in future.
282 return (len(ms.Resources) == 0 &&
283 len(ms.OutputValues) == 0 &&
284 len(ms.LocalValues) == 0)
285}