From 70afa3abaa8c56786bb6e2e6876b7ad11d11a38e Mon Sep 17 00:00:00 2001 From: James Woolfenden Date: Wed, 30 Aug 2023 16:46:15 +0100 Subject: [PATCH] add the reverse lookup --- .github/stale.yml | 18 ------------------ .github/workflows/ci.yml | 2 +- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/pr.yml | 6 +++--- .github/workflows/release.yml | 6 +++--- .pre-commit-config.yaml | 12 ++++++------ main.go | 24 ++++++++++++++++++------ src/arm/parse.go | 6 +++--- src/arm/resources.go | 2 +- src/see/lookup.go | 20 ++++++++++++++++++-- src/see/lookup_test.go | 11 +++++++---- 11 files changed, 63 insertions(+), 50 deletions(-) delete mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index 6e38a59..0000000 --- a/.github/stale.yml +++ /dev/null @@ -1,18 +0,0 @@ -# Number of days of inactivity before an issue becomes stale -daysUntilStale: 30 -# Number of days of inactivity before a stale issue is closed -daysUntilClose: 7 -# Issues with these labels will never be considered stale -exemptLabels: - - pinned - - security - - enhancement -# Label to use when marking an issue as stale -staleLabel: wontfix -# Comment to post when marking an issue as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. -# Comment to post when closing a stale issue. Set to `false` to disable -closeComment: false diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 17cd029..d02e6f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: steps: ## sets up go based on the version - name: Install Go - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: ${{ matrix.go-version }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 7a3ce84..9eb10bc 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -43,7 +43,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@1245696032ecf7d39f87d54daa406e22ddf769a8 # codeql-bundle-20230524 + uses: github/codeql-action/init@f9a7c6738f28efb36e31d49c53a201a9c5d6a476 # codeql-bundle-v2.14.2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -57,7 +57,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@1245696032ecf7d39f87d54daa406e22ddf769a8 # codeql-bundle-20230524 + uses: github/codeql-action/autobuild@f9a7c6738f28efb36e31d49c53a201a9c5d6a476 # codeql-bundle-v2.14.2 # ℹī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -70,4 +70,4 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1245696032ecf7d39f87d54daa406e22ddf769a8 # codeql-bundle-20230524 + uses: github/codeql-action/analyze@f9a7c6738f28efb36e31d49c53a201a9c5d6a476 # codeql-bundle-v2.14.2 diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 1d3e2d4..f3a696b 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -8,7 +8,7 @@ jobs: - name: Checkout code uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Install Go - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: 1.20.x - name: Restore cache @@ -30,7 +30,7 @@ jobs: - name: Checkout code uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Install Go - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: ${{ matrix.go-version }} - name: Restore cache @@ -48,6 +48,6 @@ jobs: - name: Checkout code uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Install Go - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: 1.20.x diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 71b4530..76c7e84 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: - name: Unshallow run: git fetch --prune --unshallow - name: Set up Go - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: 1.19 - name: Import GPG key @@ -25,7 +25,7 @@ jobs: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.PASSPHRASE }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@336e29918d653399e599bfca99fadc1d7ffbc9f7 # v4.3.0 + uses: goreleaser/goreleaser-action@3fa32b8bb5620a2c1afe798654bbad59f9da4906 # v4.4.0 with: version: latest args: release --clean @@ -50,7 +50,7 @@ jobs: password: ${{ secrets.DOCKERHUB_PASSWORD }} tags: "latest,${{ github.ref_name }}" - name: Update Docker Hub README - uses: peter-evans/dockerhub-description@579f64ca0abced29dbbc44ab4c6a0b9e33ab3588 # v3.4.1 + uses: peter-evans/dockerhub-description@dc67fad7001ef9e8e3c124cb7a64e16d0a63d864 # v3.4.2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1c4ef70..9817897 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ --- # yamllint disable rule:line-length default_language_version: - python: python3.10 + python: python3.11 repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 @@ -20,7 +20,7 @@ repos: - id: detect-aws-credentials - id: detect-private-key - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.5.1 + rev: v1.5.4 hooks: - id: forbid-tabs exclude_types: [ python, javascript, dtd, markdown, makefile, xml ] @@ -54,17 +54,17 @@ repos: - id: go-mod-tidy - id: go-generate - repo: https://github.com/golangci/golangci-lint - rev: v1.53.3 + rev: v1.54.2 hooks: - id: golangci-lint - repo: https://github.com/bridgecrewio/checkov - rev: 2.3.306 + rev: 2.4.18 hooks: - id: checkov - language_version: python3.10 + language_version: python3.11 args: ["-d", "."] - repo: https://github.com/jameswoolfenden/ghat - rev: v0.0.11 + rev: v0.0.24 hooks: - id: ghat-go name: ghat diff --git a/main.go b/main.go index dffc51b..757e19e 100644 --- a/main.go +++ b/main.go @@ -27,6 +27,8 @@ func main() { var resource string + var flip bool + app := &cli.App{ EnableBashCompletion: true, Flags: []cli.Flag{}, @@ -101,15 +103,18 @@ func main() { }, { Name: "see", - Usage: "shows equivalent Terraform resource", + Usage: "shows equivalent Terraform resource or the reverse", Action: func(*cli.Context) error { - result, err := see.Lookup(resource) - if result != nil { + result, err := see.Lookup(resource, flip) + if result == nil { //goland:noinspection GoLinter - fmt.Print(*result) + return fmt.Errorf("see failed with error %w", err) } - return fmt.Errorf("see failed with error %w", err) + fmt.Print(*result) + fmt.Print("\n") + + return err }, Flags: []cli.Flag{ &cli.StringFlag{ @@ -119,11 +124,18 @@ func main() { Required: true, Destination: &resource, }, + &cli.BoolFlag{ + Name: "flip", + Aliases: []string{"f"}, + Usage: "reverse the lookup", + Required: false, + Destination: &flip, + }, }, }, }, Name: "sato", - Usage: "Translate Cloudformation to Terraform", + Usage: "Translate Cloudformation or ARM to Terraform", Compiled: time.Time{}, Authors: []*cli.Author{{Name: "James Woolfenden", Email: "jim.wolf@duck.com"}}, Version: version.Version, diff --git a/src/arm/parse.go b/src/arm/parse.go index c719dc2..19821f3 100644 --- a/src/arm/parse.go +++ b/src/arm/parse.go @@ -433,7 +433,7 @@ func ReplaceResourceID(Match string, result map[string]interface{}) (string, err var resourceName *string if FindResourceType(result, arm) { - resourceName, err = see.Lookup(arm) + resourceName, err = see.Lookup(arm, false) if err != nil { log.Printf("no match found %s", arm) } @@ -447,7 +447,7 @@ func ReplaceResourceID(Match string, result map[string]interface{}) (string, err } } - resourceName, err = see.Lookup(arm) + resourceName, err = see.Lookup(arm, false) if err != nil { return "", err @@ -566,7 +566,7 @@ func ReplaceResourceID(Match string, result map[string]interface{}) (string, err log.Warn().Msgf("no match found %s", arm) } } - resourceName, err = see.Lookup(cf.Dequote(arm)) + resourceName, err = see.Lookup(cf.Dequote(arm), false) if err != nil { resourceName = toUnknownPointer() log.Warn().Msgf("no match found %s", arm) diff --git a/src/arm/resources.go b/src/arm/resources.go index a5aa9dc..7629858 100644 --- a/src/arm/resources.go +++ b/src/arm/resources.go @@ -30,7 +30,7 @@ func ParseResources(result map[string]interface{}, funcMap tftemplate.FuncMap, d myType := resource.(map[string]interface{}) myContent := lookup(myType["type"].(string)) - first, err := see.Lookup(myType["type"].(string)) + first, err := see.Lookup(myType["type"].(string), false) if err != nil { log.Warn().Err(err) diff --git a/src/see/lookup.go b/src/see/lookup.go index 407582a..fbd1fd3 100644 --- a/src/see/lookup.go +++ b/src/see/lookup.go @@ -6,7 +6,9 @@ import ( ) // Lookup converts from cf/arm to terraform resource name. -func Lookup(resource string) (*string, error) { +func Lookup(resource string, reverse bool) (*string, error) { + var result string + Lookup := map[string]string{ "aws::EFS::filesystem": "aws_efs_file_system", "aws::EFS::mounttarget": "aws_efs_mount_target", @@ -165,7 +167,13 @@ func Lookup(resource string) (*string, error) { "microsoft.storage/storageaccounts": "azurerm_storage_account", "microsoft.compute/availabilitysets": "azurerm_availability_set", } - result := Lookup[strings.TrimSuffix(strings.ToLower(resource), "/")] + + if reverse { + Reversed := reverseMap(Lookup) + result = Reversed[resource] + } else { + result = Lookup[strings.TrimSuffix(strings.ToLower(resource), "/")] + } var err error @@ -177,3 +185,11 @@ func Lookup(resource string) (*string, error) { return &result, err } + +func reverseMap(m map[string]string) map[string]string { + n := make(map[string]string, len(m)) + for k, v := range m { + n[v] = k + } + return n +} diff --git a/src/see/lookup_test.go b/src/see/lookup_test.go index 46125ab..15fe947 100644 --- a/src/see/lookup_test.go +++ b/src/see/lookup_test.go @@ -10,10 +10,12 @@ func TestLookup(t *testing.T) { type args struct { resource string + reverse bool } result := "aws_appautoscaling_target" myServiceBus := "azurerm_servicebus_namespace" + reverse := "aws::EFS::filesystem" tests := []struct { name string @@ -21,16 +23,17 @@ func TestLookup(t *testing.T) { want *string wantErr bool }{ - {name: "Pass", args: args{"AWS::ApplicationAutoScaling::ScalableTarget"}, want: &result, wantErr: false}, - {name: "Pass", args: args{"Microsoft.ServiceBus/namespaces/"}, want: &myServiceBus, wantErr: false}, - {name: "Fail", args: args{"AWS::Guff::Guffing"}, want: nil, wantErr: true}, + {name: "Pass", args: args{"AWS::ApplicationAutoScaling::ScalableTarget", false}, want: &result, wantErr: false}, + {name: "Pass", args: args{"Microsoft.ServiceBus/namespaces/", false}, want: &myServiceBus, wantErr: false}, + {name: "Fail", args: args{"AWS::Guff::Guffing", false}, want: nil, wantErr: true}, + {name: "Reverse", args: args{resource: "aws_efs_file_system", reverse: true}, want: &reverse, wantErr: false}, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() - got, err := Lookup(tt.args.resource) + got, err := Lookup(tt.args.resource, tt.args.reverse) if (err != nil) != tt.wantErr { t.Errorf("Lookup() error = %v, wantErr %v", err, tt.wantErr)