diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/configs/module_merge.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/configs/module_merge.go | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/configs/module_merge.go b/vendor/github.com/hashicorp/terraform/configs/module_merge.go new file mode 100644 index 0000000..12614c1 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/configs/module_merge.go | |||
@@ -0,0 +1,247 @@ | |||
1 | package configs | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | |||
6 | "github.com/hashicorp/terraform/addrs" | ||
7 | |||
8 | "github.com/hashicorp/hcl2/hcl" | ||
9 | "github.com/zclconf/go-cty/cty" | ||
10 | "github.com/zclconf/go-cty/cty/convert" | ||
11 | ) | ||
12 | |||
13 | // The methods in this file are used by Module.mergeFile to apply overrides | ||
14 | // to our different configuration elements. These methods all follow the | ||
15 | // pattern of mutating the receiver to incorporate settings from the parameter, | ||
16 | // returning error diagnostics if any aspect of the parameter cannot be merged | ||
17 | // into the receiver for some reason. | ||
18 | // | ||
19 | // User expectation is that anything _explicitly_ set in the given object | ||
20 | // should take precedence over the corresponding settings in the receiver, | ||
21 | // but that anything omitted in the given object should be left unchanged. | ||
22 | // In some cases it may be reasonable to do a "deep merge" of certain nested | ||
23 | // features, if it is possible to unambiguously correlate the nested elements | ||
24 | // and their behaviors are orthogonal to each other. | ||
25 | |||
26 | func (p *Provider) merge(op *Provider) hcl.Diagnostics { | ||
27 | var diags hcl.Diagnostics | ||
28 | |||
29 | if op.Version.Required != nil { | ||
30 | p.Version = op.Version | ||
31 | } | ||
32 | |||
33 | p.Config = MergeBodies(p.Config, op.Config) | ||
34 | |||
35 | return diags | ||
36 | } | ||
37 | |||
38 | func mergeProviderVersionConstraints(recv map[string][]VersionConstraint, ovrd []*ProviderRequirement) { | ||
39 | // Any provider name that's mentioned in the override gets nilled out in | ||
40 | // our map so that we'll rebuild it below. Any provider not mentioned is | ||
41 | // left unchanged. | ||
42 | for _, reqd := range ovrd { | ||
43 | delete(recv, reqd.Name) | ||
44 | } | ||
45 | for _, reqd := range ovrd { | ||
46 | recv[reqd.Name] = append(recv[reqd.Name], reqd.Requirement) | ||
47 | } | ||
48 | } | ||
49 | |||
50 | func (v *Variable) merge(ov *Variable) hcl.Diagnostics { | ||
51 | var diags hcl.Diagnostics | ||
52 | |||
53 | if ov.DescriptionSet { | ||
54 | v.Description = ov.Description | ||
55 | v.DescriptionSet = ov.DescriptionSet | ||
56 | } | ||
57 | if ov.Default != cty.NilVal { | ||
58 | v.Default = ov.Default | ||
59 | } | ||
60 | if ov.Type != cty.NilType { | ||
61 | v.Type = ov.Type | ||
62 | } | ||
63 | if ov.ParsingMode != 0 { | ||
64 | v.ParsingMode = ov.ParsingMode | ||
65 | } | ||
66 | |||
67 | // If the override file overrode type without default or vice-versa then | ||
68 | // it may have created an invalid situation, which we'll catch now by | ||
69 | // attempting to re-convert the value. | ||
70 | // | ||
71 | // Note that here we may be re-converting an already-converted base value | ||
72 | // from the base config. This will be a no-op if the type was not changed, | ||
73 | // but in particular might be user-observable in the edge case where the | ||
74 | // literal value in config could've been converted to the overridden type | ||
75 | // constraint but the converted value cannot. In practice, this situation | ||
76 | // should be rare since most of our conversions are interchangable. | ||
77 | if v.Default != cty.NilVal { | ||
78 | val, err := convert.Convert(v.Default, v.Type) | ||
79 | if err != nil { | ||
80 | // What exactly we'll say in the error message here depends on whether | ||
81 | // it was Default or Type that was overridden here. | ||
82 | switch { | ||
83 | case ov.Type != cty.NilType && ov.Default == cty.NilVal: | ||
84 | // If only the type was overridden | ||
85 | diags = append(diags, &hcl.Diagnostic{ | ||
86 | Severity: hcl.DiagError, | ||
87 | Summary: "Invalid default value for variable", | ||
88 | Detail: fmt.Sprintf("Overriding this variable's type constraint has made its default value invalid: %s.", err), | ||
89 | Subject: &ov.DeclRange, | ||
90 | }) | ||
91 | case ov.Type == cty.NilType && ov.Default != cty.NilVal: | ||
92 | // Only the default was overridden | ||
93 | diags = append(diags, &hcl.Diagnostic{ | ||
94 | Severity: hcl.DiagError, | ||
95 | Summary: "Invalid default value for variable", | ||
96 | Detail: fmt.Sprintf("The overridden default value for this variable is not compatible with the variable's type constraint: %s.", err), | ||
97 | Subject: &ov.DeclRange, | ||
98 | }) | ||
99 | default: | ||
100 | diags = append(diags, &hcl.Diagnostic{ | ||
101 | Severity: hcl.DiagError, | ||
102 | Summary: "Invalid default value for variable", | ||
103 | Detail: fmt.Sprintf("This variable's default value is not compatible with its type constraint: %s.", err), | ||
104 | Subject: &ov.DeclRange, | ||
105 | }) | ||
106 | } | ||
107 | } else { | ||
108 | v.Default = val | ||
109 | } | ||
110 | } | ||
111 | |||
112 | return diags | ||
113 | } | ||
114 | |||
115 | func (l *Local) merge(ol *Local) hcl.Diagnostics { | ||
116 | var diags hcl.Diagnostics | ||
117 | |||
118 | // Since a local is just a single expression in configuration, the | ||
119 | // override definition entirely replaces the base definition, including | ||
120 | // the source range so that we'll send the user to the right place if | ||
121 | // there is an error. | ||
122 | l.Expr = ol.Expr | ||
123 | l.DeclRange = ol.DeclRange | ||
124 | |||
125 | return diags | ||
126 | } | ||
127 | |||
128 | func (o *Output) merge(oo *Output) hcl.Diagnostics { | ||
129 | var diags hcl.Diagnostics | ||
130 | |||
131 | if oo.Description != "" { | ||
132 | o.Description = oo.Description | ||
133 | } | ||
134 | if oo.Expr != nil { | ||
135 | o.Expr = oo.Expr | ||
136 | } | ||
137 | if oo.SensitiveSet { | ||
138 | o.Sensitive = oo.Sensitive | ||
139 | o.SensitiveSet = oo.SensitiveSet | ||
140 | } | ||
141 | |||
142 | // We don't allow depends_on to be overridden because that is likely to | ||
143 | // cause confusing misbehavior. | ||
144 | if len(oo.DependsOn) != 0 { | ||
145 | diags = append(diags, &hcl.Diagnostic{ | ||
146 | Severity: hcl.DiagError, | ||
147 | Summary: "Unsupported override", | ||
148 | Detail: "The depends_on argument may not be overridden.", | ||
149 | Subject: oo.DependsOn[0].SourceRange().Ptr(), // the first item is the closest range we have | ||
150 | }) | ||
151 | } | ||
152 | |||
153 | return diags | ||
154 | } | ||
155 | |||
156 | func (mc *ModuleCall) merge(omc *ModuleCall) hcl.Diagnostics { | ||
157 | var diags hcl.Diagnostics | ||
158 | |||
159 | if omc.SourceSet { | ||
160 | mc.SourceAddr = omc.SourceAddr | ||
161 | mc.SourceAddrRange = omc.SourceAddrRange | ||
162 | mc.SourceSet = omc.SourceSet | ||
163 | } | ||
164 | |||
165 | if omc.Count != nil { | ||
166 | mc.Count = omc.Count | ||
167 | } | ||
168 | |||
169 | if omc.ForEach != nil { | ||
170 | mc.ForEach = omc.ForEach | ||
171 | } | ||
172 | |||
173 | if len(omc.Version.Required) != 0 { | ||
174 | mc.Version = omc.Version | ||
175 | } | ||
176 | |||
177 | mc.Config = MergeBodies(mc.Config, omc.Config) | ||
178 | |||
179 | // We don't allow depends_on to be overridden because that is likely to | ||
180 | // cause confusing misbehavior. | ||
181 | if len(mc.DependsOn) != 0 { | ||
182 | diags = append(diags, &hcl.Diagnostic{ | ||
183 | Severity: hcl.DiagError, | ||
184 | Summary: "Unsupported override", | ||
185 | Detail: "The depends_on argument may not be overridden.", | ||
186 | Subject: mc.DependsOn[0].SourceRange().Ptr(), // the first item is the closest range we have | ||
187 | }) | ||
188 | } | ||
189 | |||
190 | return diags | ||
191 | } | ||
192 | |||
193 | func (r *Resource) merge(or *Resource) hcl.Diagnostics { | ||
194 | var diags hcl.Diagnostics | ||
195 | |||
196 | if r.Mode != or.Mode { | ||
197 | // This is always a programming error, since managed and data resources | ||
198 | // are kept in separate maps in the configuration structures. | ||
199 | panic(fmt.Errorf("can't merge %s into %s", or.Mode, r.Mode)) | ||
200 | } | ||
201 | |||
202 | if or.Count != nil { | ||
203 | r.Count = or.Count | ||
204 | } | ||
205 | if or.ForEach != nil { | ||
206 | r.ForEach = or.ForEach | ||
207 | } | ||
208 | if or.ProviderConfigRef != nil { | ||
209 | r.ProviderConfigRef = or.ProviderConfigRef | ||
210 | } | ||
211 | if r.Mode == addrs.ManagedResourceMode { | ||
212 | // or.Managed is always non-nil for managed resource mode | ||
213 | |||
214 | if or.Managed.Connection != nil { | ||
215 | r.Managed.Connection = or.Managed.Connection | ||
216 | } | ||
217 | if or.Managed.CreateBeforeDestroySet { | ||
218 | r.Managed.CreateBeforeDestroy = or.Managed.CreateBeforeDestroy | ||
219 | r.Managed.CreateBeforeDestroySet = or.Managed.CreateBeforeDestroySet | ||
220 | } | ||
221 | if len(or.Managed.IgnoreChanges) != 0 { | ||
222 | r.Managed.IgnoreChanges = or.Managed.IgnoreChanges | ||
223 | } | ||
224 | if or.Managed.PreventDestroySet { | ||
225 | r.Managed.PreventDestroy = or.Managed.PreventDestroy | ||
226 | r.Managed.PreventDestroySet = or.Managed.PreventDestroySet | ||
227 | } | ||
228 | if len(or.Managed.Provisioners) != 0 { | ||
229 | r.Managed.Provisioners = or.Managed.Provisioners | ||
230 | } | ||
231 | } | ||
232 | |||
233 | r.Config = MergeBodies(r.Config, or.Config) | ||
234 | |||
235 | // We don't allow depends_on to be overridden because that is likely to | ||
236 | // cause confusing misbehavior. | ||
237 | if len(or.DependsOn) != 0 { | ||
238 | diags = append(diags, &hcl.Diagnostic{ | ||
239 | Severity: hcl.DiagError, | ||
240 | Summary: "Unsupported override", | ||
241 | Detail: "The depends_on argument may not be overridden.", | ||
242 | Subject: or.DependsOn[0].SourceRange().Ptr(), // the first item is the closest range we have | ||
243 | }) | ||
244 | } | ||
245 | |||
246 | return diags | ||
247 | } | ||