Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AwsRouteNotSpecifiedTargetDetector #91

Merged
merged 1 commit into from
Apr 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions detector/aws_route_not_specified_target.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package detector

import (
"github.com/hashicorp/hcl/hcl/ast"
"github.com/wata727/tflint/issue"
)

type AwsRouteNotSpecifiedTargetDetector struct {
*Detector
IssueType string
Target string
DeepCheck bool
}

func (d *Detector) CreateAwsRouteNotSpecifiedTargetDetector() *AwsRouteNotSpecifiedTargetDetector {
return &AwsRouteNotSpecifiedTargetDetector{
Detector: d,
IssueType: issue.ERROR,
Target: "aws_route",
DeepCheck: false,
}
}

func (d *AwsRouteNotSpecifiedTargetDetector) Detect(file string, item *ast.ObjectItem, issues *[]*issue.Issue) {
if IsKeyNotFound(item, "gateway_id") &&
IsKeyNotFound(item, "egress_only_gateway_id") &&
IsKeyNotFound(item, "nat_gateway_id") &&
IsKeyNotFound(item, "instance_id") &&
IsKeyNotFound(item, "vpc_peering_connection_id") &&
IsKeyNotFound(item, "network_interface_id") {
issue := &issue.Issue{
Type: d.IssueType,
Message: "route target is not specified, each route must contain either a gateway_id, egress_only_gateway_id a nat_gateway_id, an instance_id or a vpc_peering_connection_id or a network_interface_id.",
Line: item.Pos().Line,
File: file,
}
*issues = append(*issues, issue)
}

}
107 changes: 107 additions & 0 deletions detector/aws_route_not_specified_target_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package detector

import (
"reflect"
"testing"

"github.com/k0kubun/pp"
"github.com/wata727/tflint/config"
"github.com/wata727/tflint/issue"
)

func TestDetectAwsRouteNotSpecifiedTarget(t *testing.T) {
cases := []struct {
Name string
Src string
Issues []*issue.Issue
}{
{
Name: "route target is not specified",
Src: `
resource "aws_route" "foo" {
route_table_id = "rtb-1234abcd"
}`,
Issues: []*issue.Issue{
{
Type: "ERROR",
Message: "route target is not specified, each route must contain either a gateway_id, egress_only_gateway_id a nat_gateway_id, an instance_id or a vpc_peering_connection_id or a network_interface_id.",
Line: 2,
File: "test.tf",
},
},
},
{
Name: "gateway_id is specified",
Src: `
resource "aws_route" "foo" {
route_table_id = "rtb-1234abcd"
gateway_id = "igw-1234abcd"
}`,
Issues: []*issue.Issue{},
},
{
Name: "egress_only_gateway_id is specified",
Src: `
resource "aws_route" "foo" {
route_table_id = "rtb-1234abcd"
egress_only_gateway_id = "eigw-1234abcd"
}`,
Issues: []*issue.Issue{},
},
{
Name: "nat_gateway_id is specified",
Src: `
resource "aws_route" "foo" {
route_table_id = "rtb-1234abcd"
nat_gateway_id = "nat-1234abcd"
}`,
Issues: []*issue.Issue{},
},
{
Name: "instance_id is specified",
Src: `
resource "aws_route" "foo" {
route_table_id = "rtb-1234abcd"
instance_id = "i-1234abcd"
}`,
Issues: []*issue.Issue{},
},
{
Name: "vpc_peering_connection_id is specified",
Src: `
resource "aws_route" "foo" {
route_table_id = "rtb-1234abcd"
vpc_peering_connection_id = "pcx-1234abcd"
}`,
Issues: []*issue.Issue{},
},
{
Name: "network_interface_id is specified",
Src: `
resource "aws_route" "foo" {
route_table_id = "rtb-1234abcd"
network_interface_id = "eni-1234abcd"
}`,
Issues: []*issue.Issue{},
},
}

for _, tc := range cases {
var issues = []*issue.Issue{}
err := TestDetectByCreatorName(
"CreateAwsRouteNotSpecifiedTargetDetector",
tc.Src,
"",
config.Init(),
config.Init().NewAwsClient(),
&issues,
)
if err != nil {
t.Fatalf("\nERROR: %s", err)
}

if !reflect.DeepEqual(issues, tc.Issues) {
t.Fatalf("\nBad: %s\nExpected: %s\n\ntestcase: %s", pp.Sprint(issues), pp.Sprint(tc.Issues), tc.Name)
}
}
}
1 change: 1 addition & 0 deletions detector/detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ var detectors = map[string]string{
"aws_elasticache_cluster_duplicate_id": "CreateAwsElastiCacheClusterDuplicateIDDetector",
"aws_security_group_duplicate_name": "CreateAwsSecurityGroupDuplicateDetector",
"aws_route_invalid_route_table": "CreateAwsRouteInvalidRouteTableDetector",
"aws_route_not_specified_target": "CreateAwsRouteNotSpecifiedTargetDetector",
}

func NewDetector(templates map[string]*ast.File, state *state.TFState, tfvars []*ast.File, c *config.Config) (*Detector, error) {
Expand Down
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Issues are classified into the following three types.
- [aws_elasticache_cluster_invalid_type](aws_elasticache_cluster_invalid_type.md)
- [aws_elasticache_cluster_previous_type](aws_elasticache_cluster_previous_type.md)
- [aws_elasticache_cluster_default_parameter_group](aws_elasticache_cluster_default_parameter_group.md)
- **AWS Route**
- [aws_route_not_specified_target](aws_route_not_specified_target.md)

### Invalid Reference Issue
Report these issues if you have specified invalid resource ID, name, etc. All issues are reported as ERROR. These issues are reported when enabled deep check. In many cases, an incorrect value is specified, so please fix it.
Expand Down
27 changes: 27 additions & 0 deletions docs/aws_route_not_specified_target.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# AWS Route Not Specified Target
Report this issue if route target is not specified. This issue type is ERROR.

## Example
```
resource "aws_route" "foo" {
route_table_id = "rtb-1234abcd"
destination_cidr_block = "10.0.1.0/22"
}
```

The following is the execution result of TFLint:


```
$ tflint
template.tf
ERROR:1 route target is not specified, each route must contain either a gateway_id, egress_only_gateway_id a nat_gateway_id, an instance_id or a vpc_peering_connection_id or a network_interface_id.

Result: 1 issues (1 errors , 0 warnings , 0 notices)
```

## Why
`aws_route` creates new routing in route tables. If a routing target is not specified, an error will occur when run `terraform apply`.

## How To Fix
Please add a routing target. There are kinds of `gateway_id`, `egress_only_gateway_id`, `nat_gateway_id`, `instance_id`, `vpc_peering_connection_id`, `network_interface_id`.