2018-02-02 05:33:06 +01:00
|
|
|
package configs
|
|
|
|
|
|
|
|
import (
|
2018-02-03 02:22:25 +01:00
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/hashicorp/hcl2/gohcl"
|
2018-02-02 05:33:06 +01:00
|
|
|
"github.com/hashicorp/hcl2/hcl"
|
2018-02-03 02:22:25 +01:00
|
|
|
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
2018-02-02 05:33:06 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Provider represents a "provider" block in a module or file. A provider
|
|
|
|
// block is a provider configuration, and there can be zero or more
|
|
|
|
// configurations for each actual provider.
|
|
|
|
type Provider struct {
|
|
|
|
Name string
|
2018-02-03 02:22:25 +01:00
|
|
|
NameRange hcl.Range
|
2018-02-02 05:33:06 +01:00
|
|
|
Alias string
|
2018-02-03 02:22:25 +01:00
|
|
|
AliasRange *hcl.Range // nil if no alias set
|
2018-02-02 05:33:06 +01:00
|
|
|
|
|
|
|
Version VersionConstraint
|
|
|
|
|
|
|
|
Config hcl.Body
|
|
|
|
|
|
|
|
DeclRange hcl.Range
|
|
|
|
}
|
|
|
|
|
2018-02-03 02:22:25 +01:00
|
|
|
func decodeProviderBlock(block *hcl.Block) (*Provider, hcl.Diagnostics) {
|
|
|
|
content, config, diags := block.Body.PartialContent(providerBlockSchema)
|
|
|
|
|
|
|
|
provider := &Provider{
|
|
|
|
Name: block.Labels[0],
|
|
|
|
NameRange: block.LabelRanges[0],
|
|
|
|
Config: config,
|
|
|
|
DeclRange: block.DefRange,
|
|
|
|
}
|
|
|
|
|
|
|
|
if attr, exists := content.Attributes["alias"]; exists {
|
|
|
|
valDiags := gohcl.DecodeExpression(attr.Expr, nil, &provider.Alias)
|
|
|
|
diags = append(diags, valDiags...)
|
|
|
|
provider.AliasRange = attr.Expr.Range().Ptr()
|
|
|
|
|
|
|
|
if !hclsyntax.ValidIdentifier(provider.Alias) {
|
|
|
|
diags = append(diags, &hcl.Diagnostic{
|
|
|
|
Severity: hcl.DiagError,
|
|
|
|
Summary: "Invalid provider configuration alias",
|
|
|
|
Detail: fmt.Sprintf("An alias must be a valid name. %s", badIdentifierDetail),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if attr, exists := content.Attributes["version"]; exists {
|
|
|
|
var versionDiags hcl.Diagnostics
|
|
|
|
provider.Version, versionDiags = decodeVersionConstraint(attr)
|
|
|
|
diags = append(diags, versionDiags...)
|
|
|
|
}
|
|
|
|
|
|
|
|
return provider, diags
|
|
|
|
}
|
|
|
|
|
2018-02-07 01:28:40 +01:00
|
|
|
func (p *Provider) moduleUniqueKey() string {
|
|
|
|
if p.Alias != "" {
|
|
|
|
return fmt.Sprintf("%s.%s", p.Name, p.Alias)
|
|
|
|
}
|
|
|
|
return p.Name
|
|
|
|
}
|
|
|
|
|
2018-02-02 05:33:06 +01:00
|
|
|
// ProviderRequirement represents a declaration of a dependency on a particular
|
|
|
|
// provider version without actually configuring that provider. This is used in
|
|
|
|
// child modules that expect a provider to be passed in from their parent.
|
|
|
|
type ProviderRequirement struct {
|
|
|
|
Name string
|
|
|
|
Requirement VersionConstraint
|
|
|
|
}
|
2018-02-03 02:22:25 +01:00
|
|
|
|
|
|
|
func decodeRequiredProvidersBlock(block *hcl.Block) ([]*ProviderRequirement, hcl.Diagnostics) {
|
|
|
|
attrs, diags := block.Body.JustAttributes()
|
|
|
|
var reqs []*ProviderRequirement
|
|
|
|
for name, attr := range attrs {
|
|
|
|
req, reqDiags := decodeVersionConstraint(attr)
|
|
|
|
diags = append(diags, reqDiags...)
|
|
|
|
if !diags.HasErrors() {
|
|
|
|
reqs = append(reqs, &ProviderRequirement{
|
|
|
|
Name: name,
|
|
|
|
Requirement: req,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return reqs, diags
|
|
|
|
}
|
|
|
|
|
|
|
|
var providerBlockSchema = &hcl.BodySchema{
|
|
|
|
Attributes: []hcl.AttributeSchema{
|
|
|
|
{
|
|
|
|
Name: "alias",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "version",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|