Skip to content

Commit

Permalink
Merge pull request #3 from kishaningithub/add-tests-for-custom-id-logic
Browse files Browse the repository at this point in the history
Add support for aws_security_group_rule resource type and fix id generation logic
  • Loading branch information
kishaningithub committed Sep 18, 2023
2 parents 888cbfa + 5d4139f commit d4b39c4
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 86 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
- Fork and clone this repo
- Ensure you have the latest version of [golang](https://go.dev/) and [make](https://www.gnu.org/software/make/)
installed.
- To format the code, run command `make fmt`
- To build the project, run command `make build`
- To run the test suite, run command `make test`
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
test:
go test -race -v ./...

build: download-deps tidy-deps fmt compile test
build: download-deps tidy-deps compile test

fmt:
gofmt -l -s -w .
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/kishaningithub/tf-import-gen

go 1.21.1
go 1.21

require (
github.com/hashicorp/terraform-json v0.17.1
Expand All @@ -9,13 +9,13 @@ require (
)

require (
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/zclconf/go-cty v1.13.2 // indirect
golang.org/x/text v0.3.8 // indirect
github.com/zclconf/go-cty v1.14.0 // indirect
golang.org/x/text v0.13.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -20,10 +20,10 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/zclconf/go-cty v1.13.2 h1:4GvrUxe/QUDYuJKAav4EYqdM47/kZa672LwmXFmEKT0=
github.com/zclconf/go-cty v1.13.2/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
github.com/zclconf/go-cty v1.14.0 h1:/Xrd39K7DXbHzlisFP9c4pHao4yyf+/Ug9LEz+Y/yhc=
github.com/zclconf/go-cty v1.14.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
62 changes: 62 additions & 0 deletions pkg/convertor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package tfimportgen

import (
"fmt"
"github.com/kishaningithub/tf-import-gen/pkg/internal/parser"
"strings"
)

func computeTerraformImportForResource(resource parser.TerraformResource) TerraformImport {
return TerraformImport{
ResourceAddress: resource.Address,
ResourceID: computeResourceID(resource),
}
}

func computeResourceID(resource parser.TerraformResource) string {
switch resource.Type {
case "aws_iam_role_policy_attachment":
role := fmt.Sprint(resource.AttributeValues["role"])
policyArn := fmt.Sprint(resource.AttributeValues["policy_arn"])
return fmt.Sprintf("%s/%s", role, policyArn)
case "aws_lambda_permission":
functionName := fmt.Sprint(resource.AttributeValues["function_name"])
statementId := fmt.Sprint(resource.AttributeValues["statement_id"])
return fmt.Sprintf("%s/%s", functionName, statementId)
case "aws_security_group_rule":
return computeResourceIDForAWSSecurityGroupRole(resource)
default:
return fmt.Sprint(resource.AttributeValues["id"])
}
}

func computeResourceIDForAWSSecurityGroupRole(resource parser.TerraformResource) string {
// Required Fields
securityGroupId := fmt.Sprint(resource.AttributeValues["security_group_id"])
securityGroupType := fmt.Sprint(resource.AttributeValues["type"])
protocol := fmt.Sprint(resource.AttributeValues["protocol"])
fromPort := fmt.Sprint(resource.AttributeValues["from_port"])
toPort := fmt.Sprint(resource.AttributeValues["to_port"])

// Optional Fields
sourceSecurityGroupId, isSourceSecurityGroupIdValid := resource.AttributeValues["source_security_group_id"].(string)
if isSourceSecurityGroupIdValid {
isSourceSecurityGroupIdValid = len(sourceSecurityGroupId) > 0
}
cidrBlocks, isCidrBlocksValid := resource.AttributeValues["cidr_blocks"].([]any)
if isCidrBlocksValid {
isCidrBlocksValid = len(cidrBlocks) > 0
}
resourceID := fmt.Sprintf("%s_%s_%s_%s_%s", securityGroupId, securityGroupType, protocol, fromPort, toPort)
if isSourceSecurityGroupIdValid {
return fmt.Sprintf("%s_%s", resourceID, sourceSecurityGroupId)
}
if isCidrBlocksValid {
var cidrStringBlocks []string
for _, cidrBlock := range cidrBlocks {
cidrStringBlocks = append(cidrStringBlocks, fmt.Sprint(cidrBlock))
}
return fmt.Sprintf("%s_%s", resourceID, strings.Join(cidrStringBlocks, "_"))
}
return resourceID
}
104 changes: 104 additions & 0 deletions pkg/convertor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package tfimportgen

import (
"github.com/kishaningithub/tf-import-gen/pkg/internal/parser"
"github.com/stretchr/testify/require"
"testing"
)

func Test_ComputeTerraformImportForResource(t *testing.T) {
tests := []struct {
name string
terraformResource parser.TerraformResource
expected TerraformImport
}{
{
name: "For aws_iam_role_policy_attachment",
terraformResource: parser.TerraformResource{
Address: "aws_iam_role_policy_attachment.test",
Type: "aws_iam_role_policy_attachment",
AttributeValues: map[string]any{
"role": "test-role",
"policy_arn": "test-policy-arn",
},
},
expected: TerraformImport{
ResourceAddress: "aws_iam_role_policy_attachment.test",
ResourceID: "test-role/test-policy-arn",
},
},
{
name: "For aws_lambda_permission",
terraformResource: parser.TerraformResource{
Address: "aws_lambda_permission.test",
Type: "aws_lambda_permission",
AttributeValues: map[string]any{
"statement_id": "test-statement-id",
"function_name": "test-function-name",
},
},
expected: TerraformImport{
ResourceAddress: "aws_lambda_permission.test",
ResourceID: "test-function-name/test-statement-id",
},
},
{
name: "For aws_security_group_rule with source_security_group_id",
terraformResource: parser.TerraformResource{
Address: "aws_security_group_rule.test",
Type: "aws_security_group_rule",
AttributeValues: map[string]any{
"security_group_id": "security-group-id",
"type": "type",
"protocol": "protocol",
"from_port": 1234,
"to_port": 5678,
"source_security_group_id": "source-security-group-id",
},
},
expected: TerraformImport{
ResourceAddress: "aws_security_group_rule.test",
ResourceID: "security-group-id_type_protocol_1234_5678_source-security-group-id",
},
},
{
name: "For aws_security_group_rule with cidr_blocks",
terraformResource: parser.TerraformResource{
Address: "aws_security_group_rule.test",
Type: "aws_security_group_rule",
AttributeValues: map[string]any{
"security_group_id": "security-group-id",
"type": "type",
"protocol": "protocol",
"from_port": 1234,
"to_port": 5678,
"cidr_blocks": []any{"cidr-block-1", "cidr-block-2"},
},
},
expected: TerraformImport{
ResourceAddress: "aws_security_group_rule.test",
ResourceID: "security-group-id_type_protocol_1234_5678_cidr-block-1_cidr-block-2",
},
},
{
name: "For everything else",
terraformResource: parser.TerraformResource{
Address: "example.address",
Type: "example_type",
AttributeValues: map[string]any{
"id": "test_id",
},
},
expected: TerraformImport{
ResourceAddress: "example.address",
ResourceID: "test_id",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual := computeTerraformImportForResource(tt.terraformResource)
require.Equal(t, tt.expected, actual)
})
}
}
33 changes: 33 additions & 0 deletions pkg/import.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package tfimportgen

import (
"fmt"
"strings"
)

var _ fmt.Stringer = TerraformImport{}

type TerraformImport struct {
ResourceAddress string
ResourceID string
}

func (terraformImport TerraformImport) String() string {
importTemplate := `import {
to = %s
id = "%s"
}`
return fmt.Sprintln(fmt.Sprintf(importTemplate, terraformImport.ResourceAddress, terraformImport.ResourceID))
}

var _ fmt.Stringer = (TerraformImports)(nil)

type TerraformImports []TerraformImport

func (terraformImports TerraformImports) String() string {
var terraformImportsStr strings.Builder
for _, terraformImport := range terraformImports {
terraformImportsStr.WriteString(fmt.Sprintln(terraformImport))
}
return terraformImportsStr.String()
}
5 changes: 2 additions & 3 deletions pkg/internal/import_test.go → pkg/import_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package internal_test
package tfimportgen_test

import (
"fmt"
tfimportgen "github.com/kishaningithub/tf-import-gen/pkg/internal"
"github.com/kishaningithub/tf-import-gen/pkg"
"github.com/stretchr/testify/require"
"testing"
)
Expand Down Expand Up @@ -53,5 +53,4 @@ import {
require.Equal(t, expectedResult, fmt.Sprint(imports))
require.Equal(t, expectedResult, fmt.Sprintf("%s", imports))
require.Equal(t, expectedResult, fmt.Sprintf("%v", imports))

}
60 changes: 0 additions & 60 deletions pkg/internal/import.go

This file was deleted.

7 changes: 3 additions & 4 deletions pkg/tfimportgen.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
package tfimportgen

import (
"github.com/kishaningithub/tf-import-gen/pkg/internal"
"github.com/kishaningithub/tf-import-gen/pkg/internal/parser"
"io"
)

func GenerateImports(stateJsonReader io.Reader, address string) (internal.TerraformImports, error) {
func GenerateImports(stateJsonReader io.Reader, address string) (TerraformImports, error) {
resources, err := parser.NewTerraformStateJsonParser(stateJsonReader).Parse()
if err != nil {
return nil, err
}

resources = resources.FilterByAddress(address)

var imports internal.TerraformImports
var imports TerraformImports
for _, resource := range resources {
terraformImport := internal.NewTerraformImport(resource)
terraformImport := computeTerraformImportForResource(resource)
imports = append(imports, terraformImport)
}

Expand Down
Loading

0 comments on commit d4b39c4

Please sign in to comment.