github.com/jpreese/tflint@v0.19.2-0.20200908152133-b01686250fb6/rules/terraformrules/terraform_required_providers.go (about)

     1  package terraformrules
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  
     7  	"github.com/hashicorp/hcl/v2"
     8  	"github.com/terraform-linters/tflint/tflint"
     9  )
    10  
    11  // TerraformRequiredProvidersRule checks whether Terraform sets version constraints for all configured providers
    12  type TerraformRequiredProvidersRule struct{}
    13  
    14  // NewTerraformRequiredProvidersRule returns new rule with default attributes
    15  func NewTerraformRequiredProvidersRule() *TerraformRequiredProvidersRule {
    16  	return &TerraformRequiredProvidersRule{}
    17  }
    18  
    19  // Name returns the rule name
    20  func (r *TerraformRequiredProvidersRule) Name() string {
    21  	return "terraform_required_providers"
    22  }
    23  
    24  // Enabled returns whether the rule is enabled by default
    25  func (r *TerraformRequiredProvidersRule) Enabled() bool {
    26  	return false
    27  }
    28  
    29  // Severity returns the rule severity
    30  func (r *TerraformRequiredProvidersRule) Severity() string {
    31  	return tflint.WARNING
    32  }
    33  
    34  // Link returns the rule reference link
    35  func (r *TerraformRequiredProvidersRule) Link() string {
    36  	return tflint.ReferenceLink(r.Name())
    37  }
    38  
    39  //Check Checks whether provider required version is set
    40  func (r *TerraformRequiredProvidersRule) Check(runner *tflint.Runner) error {
    41  	if !runner.TFConfig.Path.IsRoot() {
    42  		// This rule does not evaluate child modules.
    43  		return nil
    44  	}
    45  
    46  	log.Printf("[TRACE] Check `%s` rule for `%s` runner", r.Name(), runner.TFConfigPath())
    47  
    48  	providers := make(map[string]hcl.Range)
    49  	module := runner.TFConfig.Module
    50  
    51  	for _, provider := range module.ProviderConfigs {
    52  		if _, ok := providers[provider.Name]; !ok {
    53  			providers[provider.Name] = provider.DeclRange
    54  		}
    55  
    56  		if provider.Version.Required != nil {
    57  			runner.EmitIssue(
    58  				r,
    59  				fmt.Sprintf(`%s: version constraint should be specified via "required_providers"`, provider.Addr().String()),
    60  				provider.DeclRange,
    61  			)
    62  		}
    63  	}
    64  
    65  	for _, resource := range module.ManagedResources {
    66  		if _, ok := providers[resource.Provider.Type]; !ok {
    67  			providers[resource.Provider.Type] = resource.DeclRange
    68  		}
    69  	}
    70  
    71  	for _, data := range module.DataResources {
    72  		if _, ok := providers[data.Provider.Type]; !ok {
    73  			providers[data.Provider.Type] = data.DeclRange
    74  		}
    75  	}
    76  
    77  	for name, decl := range providers {
    78  		if _, ok := module.ProviderRequirements.RequiredProviders[name]; !ok {
    79  			runner.EmitIssue(r, fmt.Sprintf(`Missing version constraint for provider "%s" in "required_providers"`, name), decl)
    80  		}
    81  	}
    82  
    83  	return nil
    84  }