2019-12-06 18:14:54 +01:00
|
|
|
package configs
|
|
|
|
|
|
|
|
import (
|
2020-01-10 17:54:53 +01:00
|
|
|
version "github.com/hashicorp/go-version"
|
2019-12-06 18:14:54 +01:00
|
|
|
"github.com/hashicorp/hcl/v2"
|
2020-01-13 17:31:47 +01:00
|
|
|
"github.com/hashicorp/terraform/addrs"
|
2019-12-06 18:14:54 +01:00
|
|
|
)
|
|
|
|
|
2020-01-13 17:31:47 +01:00
|
|
|
// RequiredProvider represents a declaration of a dependency on a particular
|
2020-03-12 17:00:00 +01:00
|
|
|
// provider version or source without actually configuring that provider. This
|
|
|
|
// is used in child modules that expect a provider to be passed in from their
|
|
|
|
// parent.
|
2020-01-13 17:31:47 +01:00
|
|
|
type RequiredProvider struct {
|
2019-12-06 18:14:54 +01:00
|
|
|
Name string
|
2020-03-12 17:00:00 +01:00
|
|
|
Source Source
|
2019-12-06 18:14:54 +01:00
|
|
|
Requirement VersionConstraint
|
|
|
|
}
|
|
|
|
|
2020-03-12 17:00:00 +01:00
|
|
|
type Source struct {
|
|
|
|
SourceStr string
|
|
|
|
DeclRange hcl.Range
|
|
|
|
}
|
|
|
|
|
2020-01-13 17:31:47 +01:00
|
|
|
// ProviderRequirements represents merged provider version constraints.
|
|
|
|
// VersionConstraints come from terraform.require_providers blocks and provider
|
|
|
|
// blocks.
|
|
|
|
type ProviderRequirements struct {
|
|
|
|
Type addrs.Provider
|
|
|
|
VersionConstraints []VersionConstraint
|
|
|
|
}
|
|
|
|
|
|
|
|
func decodeRequiredProvidersBlock(block *hcl.Block) ([]*RequiredProvider, hcl.Diagnostics) {
|
2019-12-06 18:14:54 +01:00
|
|
|
attrs, diags := block.Body.JustAttributes()
|
2020-01-13 17:31:47 +01:00
|
|
|
var reqs []*RequiredProvider
|
2019-12-06 18:14:54 +01:00
|
|
|
for name, attr := range attrs {
|
2020-01-10 17:54:53 +01:00
|
|
|
expr, err := attr.Expr.Value(nil)
|
|
|
|
if err != nil {
|
|
|
|
diags = append(diags, err...)
|
|
|
|
}
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case expr.Type().IsPrimitiveType():
|
|
|
|
vc, reqDiags := decodeVersionConstraint(attr)
|
|
|
|
diags = append(diags, reqDiags...)
|
2020-01-13 17:31:47 +01:00
|
|
|
reqs = append(reqs, &RequiredProvider{
|
2019-12-06 18:14:54 +01:00
|
|
|
Name: name,
|
2020-01-10 17:54:53 +01:00
|
|
|
Requirement: vc,
|
|
|
|
})
|
|
|
|
case expr.Type().IsObjectType():
|
2020-02-11 19:17:37 +01:00
|
|
|
ret := &RequiredProvider{Name: name}
|
2020-01-10 17:54:53 +01:00
|
|
|
if expr.Type().HasAttribute("version") {
|
|
|
|
vc := VersionConstraint{
|
|
|
|
DeclRange: attr.Range,
|
|
|
|
}
|
|
|
|
constraintStr := expr.GetAttr("version").AsString()
|
|
|
|
constraints, err := version.NewConstraint(constraintStr)
|
|
|
|
if err != nil {
|
|
|
|
// NewConstraint doesn't return user-friendly errors, so we'll just
|
|
|
|
// ignore the provided error and produce our own generic one.
|
|
|
|
diags = append(diags, &hcl.Diagnostic{
|
|
|
|
Severity: hcl.DiagError,
|
|
|
|
Summary: "Invalid version constraint",
|
|
|
|
Detail: "This string does not use correct version constraint syntax.",
|
|
|
|
Subject: attr.Expr.Range().Ptr(),
|
|
|
|
})
|
2020-02-11 19:17:37 +01:00
|
|
|
} else {
|
|
|
|
vc.Required = constraints
|
|
|
|
ret.Requirement = vc
|
2020-01-10 17:54:53 +01:00
|
|
|
}
|
|
|
|
}
|
2020-02-11 19:17:37 +01:00
|
|
|
if expr.Type().HasAttribute("source") {
|
2020-03-12 17:00:00 +01:00
|
|
|
ret.Source.SourceStr = expr.GetAttr("source").AsString()
|
|
|
|
ret.Source.DeclRange = attr.Range
|
2020-02-11 19:17:37 +01:00
|
|
|
}
|
|
|
|
reqs = append(reqs, ret)
|
2020-01-10 17:54:53 +01:00
|
|
|
default:
|
|
|
|
// should not happen
|
|
|
|
diags = append(diags, &hcl.Diagnostic{
|
|
|
|
Severity: hcl.DiagError,
|
|
|
|
Summary: "Invalid provider_requirements syntax",
|
|
|
|
Detail: "provider_requirements entries must be strings or objects.",
|
|
|
|
Subject: attr.Expr.Range().Ptr(),
|
2019-12-06 18:14:54 +01:00
|
|
|
})
|
2020-01-13 17:31:47 +01:00
|
|
|
reqs = append(reqs, &RequiredProvider{Name: name})
|
2020-01-10 17:54:53 +01:00
|
|
|
return reqs, diags
|
2019-12-06 18:14:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return reqs, diags
|
|
|
|
}
|