Merge pull request #25369 from hashicorp/alisdair/fix-provider-requirements-panics
configs: Fix provider requirements panics
This commit is contained in:
commit
563abd55dc
|
@ -4,6 +4,7 @@ import (
|
|||
version "github.com/hashicorp/go-version"
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
// RequiredProvider represents a declaration of a dependency on a particular
|
||||
|
@ -55,41 +56,61 @@ func decodeRequiredProvidersBlock(block *hcl.Block) (*RequiredProviders, hcl.Dia
|
|||
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.
|
||||
constraint := expr.GetAttr("version")
|
||||
if !constraint.Type().Equals(cty.String) || constraint.IsNull() {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Invalid version constraint",
|
||||
Detail: "This string does not use correct version constraint syntax.",
|
||||
Detail: "Version must be specified as a string.",
|
||||
Subject: attr.Expr.Range().Ptr(),
|
||||
})
|
||||
} else {
|
||||
vc.Required = constraints
|
||||
rp.Requirement = vc
|
||||
constraintStr := constraint.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(),
|
||||
})
|
||||
} else {
|
||||
vc.Required = constraints
|
||||
rp.Requirement = vc
|
||||
}
|
||||
}
|
||||
}
|
||||
if expr.Type().HasAttribute("source") {
|
||||
rp.Source = expr.GetAttr("source").AsString()
|
||||
|
||||
fqn, sourceDiags := addrs.ParseProviderSourceString(rp.Source)
|
||||
|
||||
if sourceDiags.HasErrors() {
|
||||
hclDiags := sourceDiags.ToHCL()
|
||||
// The diagnostics from ParseProviderSourceString don't contain
|
||||
// source location information because it has no context to compute
|
||||
// them from, and so we'll add those in quickly here before we
|
||||
// return.
|
||||
for _, diag := range hclDiags {
|
||||
if diag.Subject == nil {
|
||||
diag.Subject = attr.Expr.Range().Ptr()
|
||||
}
|
||||
}
|
||||
diags = append(diags, hclDiags...)
|
||||
source := expr.GetAttr("source")
|
||||
if !source.Type().Equals(cty.String) || source.IsNull() {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Invalid source",
|
||||
Detail: "Source must be specified as a string.",
|
||||
Subject: attr.Expr.Range().Ptr(),
|
||||
})
|
||||
} else {
|
||||
rp.Type = fqn
|
||||
rp.Source = source.AsString()
|
||||
|
||||
fqn, sourceDiags := addrs.ParseProviderSourceString(rp.Source)
|
||||
|
||||
if sourceDiags.HasErrors() {
|
||||
hclDiags := sourceDiags.ToHCL()
|
||||
// The diagnostics from ParseProviderSourceString don't contain
|
||||
// source location information because it has no context to compute
|
||||
// them from, and so we'll add those in quickly here before we
|
||||
// return.
|
||||
for _, diag := range hclDiags {
|
||||
if diag.Subject == nil {
|
||||
diag.Subject = attr.Expr.Range().Ptr()
|
||||
}
|
||||
}
|
||||
diags = append(diags, hclDiags...)
|
||||
} else {
|
||||
rp.Type = fqn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -306,6 +306,32 @@ func TestDecodeRequiredProvidersBlock(t *testing.T) {
|
|||
},
|
||||
Error: "Invalid required_providers syntax",
|
||||
},
|
||||
"invalid source attribute type": {
|
||||
Block: &hcl.Block{
|
||||
Type: "required_providers",
|
||||
Body: hcltest.MockBody(&hcl.BodyContent{
|
||||
Attributes: hcl.Attributes{
|
||||
"my-test": {
|
||||
Name: "my-test",
|
||||
Expr: hcltest.MockExprLiteral(cty.ObjectVal(map[string]cty.Value{
|
||||
"source": cty.DynamicVal,
|
||||
})),
|
||||
},
|
||||
},
|
||||
}),
|
||||
DefRange: blockRange,
|
||||
},
|
||||
Want: &RequiredProviders{
|
||||
RequiredProviders: map[string]*RequiredProvider{
|
||||
"my-test": {
|
||||
Name: "my-test",
|
||||
DeclRange: mockRange,
|
||||
},
|
||||
},
|
||||
DeclRange: blockRange,
|
||||
},
|
||||
Error: "Invalid source",
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
|
|
Loading…
Reference in New Issue