in tflint-ruleset-blueprint/rules/terraform_required_version_range.go [57:175]
func (r *TerraformRequiredVersionRange) Check(runner tflint.Runner) error {
config := &TerraformRequiredVersionRangeConfig{}
if err := runner.DecodeRuleConfig(r.Name(), config); err != nil {
return err
}
minVersion := minimumTerraformRequiredVersionRange
if config.MinVersion != "" {
if _, err := version.NewSemver(config.MinVersion); err != nil {
return err
}
minVersion = config.MinVersion
}
maxVersion := maximumTerraformRequiredVersionRange
if config.MaxVersion != "" {
if _, err := version.NewSemver(config.MaxVersion); err != nil {
return err
}
maxVersion = config.MaxVersion
}
logger.Info(fmt.Sprintf("Running with min_version: %q max_version: %q", minVersion, maxVersion))
splitVersion := strings.Split(minVersion, ".")
majorVersion, err := strconv.Atoi(splitVersion[0])
if err != nil {
return err
}
minorVersion, err := strconv.Atoi(splitVersion[1])
if err != nil {
return err
}
var terraform_below_minimum_required_version string
if minorVersion > 0 {
terraform_below_minimum_required_version = fmt.Sprintf(
"v%d.%d.999",
majorVersion,
minorVersion - 1,
)
} else {
if majorVersion == 0 {
return fmt.Errorf("Error: minimum version test constraint would be below zero: v%d.%d.999", majorVersion - 1, 999)
}
terraform_below_minimum_required_version = fmt.Sprintf(
"v%d.%d.999",
majorVersion - 1,
999,
)
}
below_required_version, err := version.NewVersion(terraform_below_minimum_required_version)
if err != nil {
return err
}
minimum_required_version, err := version.NewVersion(minVersion)
if err != nil {
return err
}
maximum_required_version, err := version.NewVersion(maxVersion)
if err != nil {
return err
}
path, err := runner.GetModulePath()
if err != nil {
return err
}
if !path.IsRoot() {
return nil
}
content, err := runner.GetModuleContent(&hclext.BodySchema{
Blocks: []hclext.BlockSchema{
{
Type: "terraform",
Body: &hclext.BodySchema{
Attributes: []hclext.AttributeSchema{{Name: "required_version"}},
},
},
},
}, &tflint.GetModuleContentOption{ExpandMode: tflint.ExpandModeNone})
if err != nil {
return err
}
for _, block := range content.Blocks {
requiredVersion, exists := block.Body.Attributes["required_version"]
if !exists {
logger.Info(fmt.Sprintf("terraform block does not contain required_version: %s", block.DefRange))
continue
}
var raw_terraform_required_version string
diags := gohcl.DecodeExpression(requiredVersion.Expr, nil, &raw_terraform_required_version)
if diags.HasErrors() {
return fmt.Errorf("failed to decode terraform block required_version: %v", diags.Error())
}
constraints, err := version.NewConstraint(raw_terraform_required_version)
if err != nil {
return err
}
if !((constraints.Check(minimum_required_version) || constraints.Check(maximum_required_version)) && !constraints.Check(below_required_version)) {
//TODO: use EmitIssueWithFix()
err := runner.EmitIssue(r, fmt.Sprintf("required_version is not inclusive of the the minimum %q and maximum %q terraform required_version: %q", minVersion, maxVersion, constraints.String()), block.DefRange)
if err != nil {
return err
}
}
}
return nil
}