github.com/wata727/tflint@v0.12.2-0.20191013070026-96dd0d36f385/rules/awsrules/aws_route_specified_multiple_targets.go (about)

     1  package awsrules
     2  
     3  import (
     4  	"log"
     5  
     6  	hcl "github.com/hashicorp/hcl/v2"
     7  	"github.com/wata727/tflint/tflint"
     8  )
     9  
    10  // AwsRouteSpecifiedMultipleTargetsRule checks whether a route definition has multiple routing targets
    11  type AwsRouteSpecifiedMultipleTargetsRule struct {
    12  	resourceType string
    13  }
    14  
    15  // NewAwsRouteSpecifiedMultipleTargetsRule returns new rule with default attributes
    16  func NewAwsRouteSpecifiedMultipleTargetsRule() *AwsRouteSpecifiedMultipleTargetsRule {
    17  	return &AwsRouteSpecifiedMultipleTargetsRule{
    18  		resourceType: "aws_route",
    19  	}
    20  }
    21  
    22  // Name returns the rule name
    23  func (r *AwsRouteSpecifiedMultipleTargetsRule) Name() string {
    24  	return "aws_route_specified_multiple_targets"
    25  }
    26  
    27  // Enabled returns whether the rule is enabled by default
    28  func (r *AwsRouteSpecifiedMultipleTargetsRule) Enabled() bool {
    29  	return true
    30  }
    31  
    32  // Severity returns the rule severity
    33  func (r *AwsRouteSpecifiedMultipleTargetsRule) Severity() string {
    34  	return tflint.ERROR
    35  }
    36  
    37  // Link returns the rule reference link
    38  func (r *AwsRouteSpecifiedMultipleTargetsRule) Link() string {
    39  	return tflint.ReferenceLink(r.Name())
    40  }
    41  
    42  // Check checks whether a resource defines `gateway_id`, `egress_only_gateway_id`, `nat_gateway_id`
    43  // `instance_id`, `vpc_peering_connection_id` or `network_interface_id` at the same time
    44  func (r *AwsRouteSpecifiedMultipleTargetsRule) Check(runner *tflint.Runner) error {
    45  	log.Printf("[TRACE] Check `%s` rule for `%s` runner", r.Name(), runner.TFConfigPath())
    46  
    47  	for _, resource := range runner.LookupResourcesByType(r.resourceType) {
    48  		body, _, diags := resource.Config.PartialContent(&hcl.BodySchema{
    49  			Attributes: []hcl.AttributeSchema{
    50  				{
    51  					Name: "gateway_id",
    52  				},
    53  				{
    54  					Name: "egress_only_gateway_id",
    55  				},
    56  				{
    57  					Name: "nat_gateway_id",
    58  				},
    59  				{
    60  					Name: "instance_id",
    61  				},
    62  				{
    63  					Name: "vpc_peering_connection_id",
    64  				},
    65  				{
    66  					Name: "network_interface_id",
    67  				},
    68  				{
    69  					Name: "transit_gateway_id",
    70  				},
    71  			},
    72  		})
    73  		if diags.HasErrors() {
    74  			return diags
    75  		}
    76  
    77  		var nullAttributes int
    78  		for _, attribute := range body.Attributes {
    79  			isNull, err := runner.IsNullExpr(attribute.Expr)
    80  			if err != nil {
    81  				return err
    82  			}
    83  
    84  			if isNull {
    85  				nullAttributes = nullAttributes + 1
    86  			}
    87  		}
    88  
    89  		if len(body.Attributes)-nullAttributes > 1 {
    90  			runner.EmitIssue(
    91  				r,
    92  				"More than one routing target specified. It must be one.",
    93  				resource.DeclRange,
    94  			)
    95  		}
    96  	}
    97  
    98  	return nil
    99  }