github.com/wata727/tflint@v0.12.2-0.20191013070026-96dd0d36f385/rules/awsrules/aws_route_not_specified_target.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  // AwsRouteNotSpecifiedTargetRule checks whether a route definition has a routing target
    11  type AwsRouteNotSpecifiedTargetRule struct {
    12  	resourceType string
    13  }
    14  
    15  // NewAwsRouteNotSpecifiedTargetRule returns new rule with default attributes
    16  func NewAwsRouteNotSpecifiedTargetRule() *AwsRouteNotSpecifiedTargetRule {
    17  	return &AwsRouteNotSpecifiedTargetRule{
    18  		resourceType: "aws_route",
    19  	}
    20  }
    21  
    22  // Name returns the rule name
    23  func (r *AwsRouteNotSpecifiedTargetRule) Name() string {
    24  	return "aws_route_not_specified_target"
    25  }
    26  
    27  // Enabled returns whether the rule is enabled by default
    28  func (r *AwsRouteNotSpecifiedTargetRule) Enabled() bool {
    29  	return true
    30  }
    31  
    32  // Severity returns the rule severity
    33  func (r *AwsRouteNotSpecifiedTargetRule) Severity() string {
    34  	return tflint.ERROR
    35  }
    36  
    37  // Link returns the rule reference link
    38  func (r *AwsRouteNotSpecifiedTargetRule) Link() string {
    39  	return tflint.ReferenceLink(r.Name())
    40  }
    41  
    42  // Check checks whether `gateway_id`, `egress_only_gateway_id`, `nat_gateway_id`, `instance_id`
    43  // `vpc_peering_connection_id` or `network_interface_id` is defined in a resource
    44  func (r *AwsRouteNotSpecifiedTargetRule) 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 == 0 {
    90  			runner.EmitIssue(
    91  				r,
    92  				"The routing target is not specified, each aws_route must contain either egress_only_gateway_id, gateway_id, instance_id, nat_gateway_id, network_interface_id, transit_gateway_id, or vpc_peering_connection_id.",
    93  				resource.DeclRange,
    94  			)
    95  		}
    96  	}
    97  
    98  	return nil
    99  }