aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/terraform/addrs/provider_config.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/addrs/provider_config.go')
-rw-r--r--vendor/github.com/hashicorp/terraform/addrs/provider_config.go297
1 files changed, 297 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/addrs/provider_config.go b/vendor/github.com/hashicorp/terraform/addrs/provider_config.go
new file mode 100644
index 0000000..340dd19
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/addrs/provider_config.go
@@ -0,0 +1,297 @@
1package addrs
2
3import (
4 "fmt"
5
6 "github.com/hashicorp/terraform/tfdiags"
7
8 "github.com/hashicorp/hcl2/hcl"
9 "github.com/hashicorp/hcl2/hcl/hclsyntax"
10)
11
12// ProviderConfig is the address of a provider configuration.
13type ProviderConfig struct {
14 Type string
15
16 // If not empty, Alias identifies which non-default (aliased) provider
17 // configuration this address refers to.
18 Alias string
19}
20
21// NewDefaultProviderConfig returns the address of the default (un-aliased)
22// configuration for the provider with the given type name.
23func NewDefaultProviderConfig(typeName string) ProviderConfig {
24 return ProviderConfig{
25 Type: typeName,
26 }
27}
28
29// ParseProviderConfigCompact parses the given absolute traversal as a relative
30// provider address in compact form. The following are examples of traversals
31// that can be successfully parsed as compact relative provider configuration
32// addresses:
33//
34// aws
35// aws.foo
36//
37// This function will panic if given a relative traversal.
38//
39// If the returned diagnostics contains errors then the result value is invalid
40// and must not be used.
41func ParseProviderConfigCompact(traversal hcl.Traversal) (ProviderConfig, tfdiags.Diagnostics) {
42 var diags tfdiags.Diagnostics
43 ret := ProviderConfig{
44 Type: traversal.RootName(),
45 }
46
47 if len(traversal) < 2 {
48 // Just a type name, then.
49 return ret, diags
50 }
51
52 aliasStep := traversal[1]
53 switch ts := aliasStep.(type) {
54 case hcl.TraverseAttr:
55 ret.Alias = ts.Name
56 return ret, diags
57 default:
58 diags = diags.Append(&hcl.Diagnostic{
59 Severity: hcl.DiagError,
60 Summary: "Invalid provider configuration address",
61 Detail: "The provider type name must either stand alone or be followed by an alias name separated with a dot.",
62 Subject: aliasStep.SourceRange().Ptr(),
63 })
64 }
65
66 if len(traversal) > 2 {
67 diags = diags.Append(&hcl.Diagnostic{
68 Severity: hcl.DiagError,
69 Summary: "Invalid provider configuration address",
70 Detail: "Extraneous extra operators after provider configuration address.",
71 Subject: traversal[2:].SourceRange().Ptr(),
72 })
73 }
74
75 return ret, diags
76}
77
78// ParseProviderConfigCompactStr is a helper wrapper around ParseProviderConfigCompact
79// that takes a string and parses it with the HCL native syntax traversal parser
80// before interpreting it.
81//
82// This should be used only in specialized situations since it will cause the
83// created references to not have any meaningful source location information.
84// If a reference string is coming from a source that should be identified in
85// error messages then the caller should instead parse it directly using a
86// suitable function from the HCL API and pass the traversal itself to
87// ParseProviderConfigCompact.
88//
89// Error diagnostics are returned if either the parsing fails or the analysis
90// of the traversal fails. There is no way for the caller to distinguish the
91// two kinds of diagnostics programmatically. If error diagnostics are returned
92// then the returned address is invalid.
93func ParseProviderConfigCompactStr(str string) (ProviderConfig, tfdiags.Diagnostics) {
94 var diags tfdiags.Diagnostics
95
96 traversal, parseDiags := hclsyntax.ParseTraversalAbs([]byte(str), "", hcl.Pos{Line: 1, Column: 1})
97 diags = diags.Append(parseDiags)
98 if parseDiags.HasErrors() {
99 return ProviderConfig{}, diags
100 }
101
102 addr, addrDiags := ParseProviderConfigCompact(traversal)
103 diags = diags.Append(addrDiags)
104 return addr, diags
105}
106
107// Absolute returns an AbsProviderConfig from the receiver and the given module
108// instance address.
109func (pc ProviderConfig) Absolute(module ModuleInstance) AbsProviderConfig {
110 return AbsProviderConfig{
111 Module: module,
112 ProviderConfig: pc,
113 }
114}
115
116func (pc ProviderConfig) String() string {
117 if pc.Type == "" {
118 // Should never happen; always indicates a bug
119 return "provider.<invalid>"
120 }
121
122 if pc.Alias != "" {
123 return fmt.Sprintf("provider.%s.%s", pc.Type, pc.Alias)
124 }
125
126 return "provider." + pc.Type
127}
128
129// StringCompact is an alternative to String that returns the form that can
130// be parsed by ParseProviderConfigCompact, without the "provider." prefix.
131func (pc ProviderConfig) StringCompact() string {
132 if pc.Alias != "" {
133 return fmt.Sprintf("%s.%s", pc.Type, pc.Alias)
134 }
135 return pc.Type
136}
137
138// AbsProviderConfig is the absolute address of a provider configuration
139// within a particular module instance.
140type AbsProviderConfig struct {
141 Module ModuleInstance
142 ProviderConfig ProviderConfig
143}
144
145// ParseAbsProviderConfig parses the given traversal as an absolute provider
146// address. The following are examples of traversals that can be successfully
147// parsed as absolute provider configuration addresses:
148//
149// provider.aws
150// provider.aws.foo
151// module.bar.provider.aws
152// module.bar.module.baz.provider.aws.foo
153// module.foo[1].provider.aws.foo
154//
155// This type of address is used, for example, to record the relationships
156// between resources and provider configurations in the state structure.
157// This type of address is not generally used in the UI, except in error
158// messages that refer to provider configurations.
159func ParseAbsProviderConfig(traversal hcl.Traversal) (AbsProviderConfig, tfdiags.Diagnostics) {
160 modInst, remain, diags := parseModuleInstancePrefix(traversal)
161 ret := AbsProviderConfig{
162 Module: modInst,
163 }
164 if len(remain) < 2 || remain.RootName() != "provider" {
165 diags = diags.Append(&hcl.Diagnostic{
166 Severity: hcl.DiagError,
167 Summary: "Invalid provider configuration address",
168 Detail: "Provider address must begin with \"provider.\", followed by a provider type name.",
169 Subject: remain.SourceRange().Ptr(),
170 })
171 return ret, diags
172 }
173 if len(remain) > 3 {
174 diags = diags.Append(&hcl.Diagnostic{
175 Severity: hcl.DiagError,
176 Summary: "Invalid provider configuration address",
177 Detail: "Extraneous operators after provider configuration alias.",
178 Subject: hcl.Traversal(remain[3:]).SourceRange().Ptr(),
179 })
180 return ret, diags
181 }
182
183 if tt, ok := remain[1].(hcl.TraverseAttr); ok {
184 ret.ProviderConfig.Type = tt.Name
185 } else {
186 diags = diags.Append(&hcl.Diagnostic{
187 Severity: hcl.DiagError,
188 Summary: "Invalid provider configuration address",
189 Detail: "The prefix \"provider.\" must be followed by a provider type name.",
190 Subject: remain[1].SourceRange().Ptr(),
191 })
192 return ret, diags
193 }
194
195 if len(remain) == 3 {
196 if tt, ok := remain[2].(hcl.TraverseAttr); ok {
197 ret.ProviderConfig.Alias = tt.Name
198 } else {
199 diags = diags.Append(&hcl.Diagnostic{
200 Severity: hcl.DiagError,
201 Summary: "Invalid provider configuration address",
202 Detail: "Provider type name must be followed by a configuration alias name.",
203 Subject: remain[2].SourceRange().Ptr(),
204 })
205 return ret, diags
206 }
207 }
208
209 return ret, diags
210}
211
212// ParseAbsProviderConfigStr is a helper wrapper around ParseAbsProviderConfig
213// that takes a string and parses it with the HCL native syntax traversal parser
214// before interpreting it.
215//
216// This should be used only in specialized situations since it will cause the
217// created references to not have any meaningful source location information.
218// If a reference string is coming from a source that should be identified in
219// error messages then the caller should instead parse it directly using a
220// suitable function from the HCL API and pass the traversal itself to
221// ParseAbsProviderConfig.
222//
223// Error diagnostics are returned if either the parsing fails or the analysis
224// of the traversal fails. There is no way for the caller to distinguish the
225// two kinds of diagnostics programmatically. If error diagnostics are returned
226// the returned address is invalid.
227func ParseAbsProviderConfigStr(str string) (AbsProviderConfig, tfdiags.Diagnostics) {
228 var diags tfdiags.Diagnostics
229
230 traversal, parseDiags := hclsyntax.ParseTraversalAbs([]byte(str), "", hcl.Pos{Line: 1, Column: 1})
231 diags = diags.Append(parseDiags)
232 if parseDiags.HasErrors() {
233 return AbsProviderConfig{}, diags
234 }
235
236 addr, addrDiags := ParseAbsProviderConfig(traversal)
237 diags = diags.Append(addrDiags)
238 return addr, diags
239}
240
241// ProviderConfigDefault returns the address of the default provider config
242// of the given type inside the recieving module instance.
243func (m ModuleInstance) ProviderConfigDefault(name string) AbsProviderConfig {
244 return AbsProviderConfig{
245 Module: m,
246 ProviderConfig: ProviderConfig{
247 Type: name,
248 },
249 }
250}
251
252// ProviderConfigAliased returns the address of an aliased provider config
253// of with given type and alias inside the recieving module instance.
254func (m ModuleInstance) ProviderConfigAliased(name, alias string) AbsProviderConfig {
255 return AbsProviderConfig{
256 Module: m,
257 ProviderConfig: ProviderConfig{
258 Type: name,
259 Alias: alias,
260 },
261 }
262}
263
264// Inherited returns an address that the receiving configuration address might
265// inherit from in a parent module. The second bool return value indicates if
266// such inheritance is possible, and thus whether the returned address is valid.
267//
268// Inheritance is possible only for default (un-aliased) providers in modules
269// other than the root module. Even if a valid address is returned, inheritence
270// may not be performed for other reasons, such as if the calling module
271// provided explicit provider configurations within the call for this module.
272// The ProviderTransformer graph transform in the main terraform module has
273// the authoritative logic for provider inheritance, and this method is here
274// mainly just for its benefit.
275func (pc AbsProviderConfig) Inherited() (AbsProviderConfig, bool) {
276 // Can't inherit if we're already in the root.
277 if len(pc.Module) == 0 {
278 return AbsProviderConfig{}, false
279 }
280
281 // Can't inherit if we have an alias.
282 if pc.ProviderConfig.Alias != "" {
283 return AbsProviderConfig{}, false
284 }
285
286 // Otherwise, we might inherit from a configuration with the same
287 // provider name in the parent module instance.
288 parentMod := pc.Module.Parent()
289 return pc.ProviderConfig.Absolute(parentMod), true
290}
291
292func (pc AbsProviderConfig) String() string {
293 if len(pc.Module) == 0 {
294 return pc.ProviderConfig.String()
295 }
296 return fmt.Sprintf("%s.%s", pc.Module.String(), pc.ProviderConfig.String())
297}