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"
|
version "github.com/hashicorp/go-version"
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RequiredProvider represents a declaration of a dependency on a particular
|
// RequiredProvider represents a declaration of a dependency on a particular
|
||||||
|
@ -55,41 +56,61 @@ func decodeRequiredProvidersBlock(block *hcl.Block) (*RequiredProviders, hcl.Dia
|
||||||
vc := VersionConstraint{
|
vc := VersionConstraint{
|
||||||
DeclRange: attr.Range,
|
DeclRange: attr.Range,
|
||||||
}
|
}
|
||||||
constraintStr := expr.GetAttr("version").AsString()
|
constraint := expr.GetAttr("version")
|
||||||
constraints, err := version.NewConstraint(constraintStr)
|
if !constraint.Type().Equals(cty.String) || constraint.IsNull() {
|
||||||
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{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
Summary: "Invalid version constraint",
|
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(),
|
Subject: attr.Expr.Range().Ptr(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
vc.Required = constraints
|
constraintStr := constraint.AsString()
|
||||||
rp.Requirement = vc
|
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") {
|
if expr.Type().HasAttribute("source") {
|
||||||
rp.Source = expr.GetAttr("source").AsString()
|
source := expr.GetAttr("source")
|
||||||
|
if !source.Type().Equals(cty.String) || source.IsNull() {
|
||||||
fqn, sourceDiags := addrs.ParseProviderSourceString(rp.Source)
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
|
Severity: hcl.DiagError,
|
||||||
if sourceDiags.HasErrors() {
|
Summary: "Invalid source",
|
||||||
hclDiags := sourceDiags.ToHCL()
|
Detail: "Source must be specified as a string.",
|
||||||
// The diagnostics from ParseProviderSourceString don't contain
|
Subject: attr.Expr.Range().Ptr(),
|
||||||
// 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 {
|
} 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",
|
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 {
|
for name, test := range tests {
|
||||||
|
|
Loading…
Reference in New Issue