Skip to content

Commit

Permalink
Merge pull request #97 from wata727/aws_route_invalid_instance
Browse files Browse the repository at this point in the history
Add AwsRouteInvalidInstanceDetector
  • Loading branch information
wata727 authored Apr 9, 2017
2 parents 08060cb + 4b6e65a commit 6dbf052
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 2 deletions.
64 changes: 64 additions & 0 deletions detector/aws_route_invalid_instance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package detector

import (
"fmt"

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

type AwsRouteInvalidInstanceDetector struct {
*Detector
IssueType string
Target string
DeepCheck bool
instances map[string]bool
}

func (d *Detector) CreateAwsRouteInvalidInstanceDetector() *AwsRouteInvalidInstanceDetector {
return &AwsRouteInvalidInstanceDetector{
Detector: d,
IssueType: issue.ERROR,
Target: "aws_route",
DeepCheck: true,
instances: map[string]bool{},
}
}

func (d *AwsRouteInvalidInstanceDetector) PreProcess() {
resp, err := d.AwsClient.DescribeInstances()
if err != nil {
d.Logger.Error(err)
d.Error = true
return
}

for _, reservation := range resp.Reservations {
for _, instance := range reservation.Instances {
d.instances[*instance.InstanceId] = true
}
}
}

func (d *AwsRouteInvalidInstanceDetector) Detect(file string, item *ast.ObjectItem, issues *[]*issue.Issue) {
instanceToken, err := hclLiteralToken(item, "instance_id")
if err != nil {
d.Logger.Error(err)
return
}
instance, err := d.evalToString(instanceToken.Text)
if err != nil {
d.Logger.Error(err)
return
}

if !d.instances[instance] {
issue := &issue.Issue{
Type: d.IssueType,
Message: fmt.Sprintf("\"%s\" is invalid instance ID.", instance),
Line: instanceToken.Pos.Line,
File: file,
}
*issues = append(*issues, issue)
}
}
98 changes: 98 additions & 0 deletions detector/aws_route_invalid_instance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package detector

import (
"reflect"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/golang/mock/gomock"
"github.com/k0kubun/pp"
"github.com/wata727/tflint/config"
"github.com/wata727/tflint/issue"
"github.com/wata727/tflint/mock"
)

func TestDetectAwsRouteInvalidInstance(t *testing.T) {
cases := []struct {
Name string
Src string
Response []*ec2.Instance
Issues []*issue.Issue
}{
{
Name: "instance id is invalid",
Src: `
resource "aws_route" "foo" {
instance_id = "i-1234abcd"
}`,
Response: []*ec2.Instance{
{
InstanceId: aws.String("i-5678abcd"),
},
{
InstanceId: aws.String("i-abcd1234"),
},
},
Issues: []*issue.Issue{
{
Type: "ERROR",
Message: "\"i-1234abcd\" is invalid instance ID.",
Line: 3,
File: "test.tf",
},
},
},
{
Name: "instance id is valid",
Src: `
resource "aws_route" "foo" {
instance_id = "i-1234abcd"
}`,
Response: []*ec2.Instance{
{
InstanceId: aws.String("i-1234abcd"),
},
{
InstanceId: aws.String("i-abcd1234"),
},
},
Issues: []*issue.Issue{},
},
}

for _, tc := range cases {
c := config.Init()
c.DeepCheck = true

awsClient := c.NewAwsClient()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
ec2mock := mock.NewMockEC2API(ctrl)
ec2mock.EXPECT().DescribeInstances(&ec2.DescribeInstancesInput{}).Return(&ec2.DescribeInstancesOutput{
Reservations: []*ec2.Reservation{
{
Instances: tc.Response,
},
},
}, nil)
awsClient.Ec2 = ec2mock

var issues = []*issue.Issue{}
err := TestDetectByCreatorName(
"CreateAwsRouteInvalidInstanceDetector",
tc.Src,
"",
c,
awsClient,
&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)
}
}
}
2 changes: 0 additions & 2 deletions detector/aws_route_invalid_vpc_peering_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,11 @@ func (d *AwsRouteInvalidVpcPeeringConnectionDetector) Detect(file string, item *
vpcPeeringConnectionToken, err := hclLiteralToken(item, "vpc_peering_connection_id")
if err != nil {
d.Logger.Error(err)
d.Error = true
return
}
vpcPeeringConnection, err := d.evalToString(vpcPeeringConnectionToken.Text)
if err != nil {
d.Logger.Error(err)
d.Error = true
return
}

Expand Down
1 change: 1 addition & 0 deletions detector/detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ var detectors = map[string]string{
"aws_route_invalid_egress_only_gateway": "CreateAwsRouteInvalidEgressOnlyGatewayDetector",
"aws_route_invalid_nat_gateway": "CreateAwsRouteInvalidNatGatewayDetector",
"aws_route_invalid_vpc_peering_connection": "CreateAwsRouteInvalidVpcPeeringConnectionDetector",
"aws_route_invalid_instance": "CreateAwsRouteInvalidInstanceDetector",
}

func NewDetector(templates map[string]*ast.File, state *state.TFState, tfvars []*ast.File, c *config.Config) (*Detector, error) {
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ Report these issues if you have specified invalid resource ID, name, etc. All is
- aws_route_invalid_egress_only_gateway
- aws_route_invalid_nat_gateway
- aws_route_invalid_vpc_peering_connection
- aws_route_invalid_instance

### Duplicate Resource Issue
Report these issues if you have specified resource ID, name, etc that already existed and must be unique. All issues are reported as ERROR. These issues are reported when enabled deep check. For example, it happens when resources with the same name is already created. Please check the actual resources again.
Expand Down

0 comments on commit 6dbf052

Please sign in to comment.