diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4b2a0f9..7df65b9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -36,6 +36,5 @@ ] } }, - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. "remoteUser": "vscode" } \ No newline at end of file diff --git a/.github/workflows/dev.yaml b/.github/workflows/dev.yaml index 1e98a2c..31a98a6 100644 --- a/.github/workflows/dev.yaml +++ b/.github/workflows/dev.yaml @@ -49,6 +49,20 @@ jobs: labels: ['wip'] }) + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: ^1.17 + cache: false + + - name: Run Lint + uses: golangci/golangci-lint-action@v3 + codespell: runs-on: ubuntu-latest steps: @@ -67,7 +81,7 @@ jobs: unit_test: runs-on: ${{ matrix.os }} - needs: [setup_pr, codespell] + needs: [setup_pr, lint, codespell] strategy: fail-fast: false matrix: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 72a0b32..858a22a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,6 +9,20 @@ permissions: contents: read jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: ^1.17 + cache: false + + - name: Run Lint + uses: golangci/golangci-lint-action@v3 + codespell: runs-on: ubuntu-latest steps: @@ -104,7 +118,7 @@ jobs: permissions: contents: write pull-requests: write - needs: [codespell, integration_test] + needs: [lint, codespell, integration_test] outputs: release_created: ${{ steps.release.outputs.release_created }} steps: diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..38c8ef1 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,43 @@ +run: + timeout: 60m + +issues: + max-per-linter: 0 + max-same-issues: 0 + +linters: + disable-all: true + enable: + - asciicheck + - bidichk + - errcheck + - gocritic + - gofmt + - goimports + - gosimple + - govet + - ineffassign + - nakedret + - misspell + #- nolintlint + #- nlreturn + - reassign + - staticcheck + - typecheck + - unused + - unconvert + - unparam + - vet + - vetshadow + # - wastedassign # disabled because of generics + # - whitespace # Disabled for performance reasons - Ignores cache and takes 12+ minutes to run on the repo for _any_ change + +linters-settings: + errcheck: + ignore: github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema:ForceNew|Set,fmt:.*,io:Close + misspell: + ignore-words: + - hdinsight + - exportfs + nakedret: + max-func-lines: 40 \ No newline at end of file diff --git a/.golintci.yml b/.golintci.yml deleted file mode 100644 index b668bd5..0000000 --- a/.golintci.yml +++ /dev/null @@ -1,30 +0,0 @@ -run: - timeout: 5m - issues-exit-code: 1 - tests: true - skip-dirs-use-default: true - modules-download-mode: readonly - -linters: - enable: - - bodyclose # ensure HTTP response bodies are successfully closed. - - contextcheck # check we are passing context an inherited context. - - gofmt # checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification. - - errname # checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. - - errcheck # a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases. - - errorlint # used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - - godot # check if comments end in a period. - - misspell # finds commonly misspelled English words in comments. - - nilerr # checks that there is no simultaneous return of nil error and an invalid value. - - tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes. - - unparam # reports unused function parameters. - - whitespace # detection of leading and trailing whitespace. - -linters-settings: - errcheck: - exclude-functions: - # fine to ignore in errcheck as tfproviderlint covers this - - (*github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.ResourceData).Set - -output: - format: colored-line-number \ No newline at end of file diff --git a/GNUmakefile b/GNUmakefile index d198c32..9a8028c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,4 +1,4 @@ -TEST?=$$(go list ./...) +TEST?=$$(go list ./... |grep -v 'vendor'|grep -v 'examples') GOFMT_FILES?=$$(find . -name '*.go') WEBSITE_REPO=github.com/hashicorp/terraform-website PKG_NAME=cloud66 @@ -6,6 +6,17 @@ VERSION=$(shell git describe --tags --always) default: build +tools: + @echo "==> installing required tooling..." + @sh "$(CURDIR)/scripts/gogetcookie.sh" + go install github.com/client9/misspell/cmd/misspell@latest + go install github.com/bflad/tfproviderlint/cmd/tfproviderlint@latest + go install github.com/bflad/tfproviderdocs@latest + go install github.com/katbyte/terrafmt@latest + go install golang.org/x/tools/cmd/goimports@latest + go install mvdan.cc/gofumpt@latest + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$(go env GOPATH || $$GOPATH)/bin v1.51.1 + build: vet fmt go install @@ -16,7 +27,8 @@ test: fmt testacc: fmt TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m -covermode atomic -coverprofile=covprofile -lint: tools terraform-provider-lint golangci-lint +lint: + golangci-lint run ./... vet: @echo "==> Running go vet ." diff --git a/cloud66/data_source_stack.go b/cloud66/data_source_stack.go index 740ae2e..e71bdfe 100644 --- a/cloud66/data_source_stack.go +++ b/cloud66/data_source_stack.go @@ -51,7 +51,7 @@ func dataSourceCloud66StackRead(d *schema.ResourceData, meta interface{}) error stackEnv := d.Get("environment").(string) var stack api.Stack - if stackID != "" { + if stackID != "" { //nolint:golint,gocritic stackResp, err := client.FindStackByUid(stackID) if stackResp != nil { stack = *stackResp diff --git a/cloud66/provider_test.go b/cloud66/provider_test.go index 9d165f4..6d871bf 100644 --- a/cloud66/provider_test.go +++ b/cloud66/provider_test.go @@ -39,8 +39,6 @@ func TestProvider_impl(t *testing.T) { var _ *schema.Provider = Provider() } -type preCheckFunc = func(*testing.T) - func generateRandomResourceName() string { return acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) } @@ -139,7 +137,7 @@ func testAccCloud66Stack(uid string, name string) { } func testAccCloud66Servers(uid string) { - data := fmt.Sprintf(` + data := ` { "response": [ { @@ -199,7 +197,7 @@ func testAccCloud66Servers(uid string) { "pages": 1 } } -`) +` httpmock.RegisterResponder("GET", "https://app.cloud66.com/api/3/stacks/"+uid+"/servers.json", httpmock.NewStringResponder(200, data)) } @@ -239,7 +237,7 @@ func testAccCloud66SslCertificateLetsEncrypt(stackID string, uid string) { } }`, sslData) deleteSslResponse := fmt.Sprintf(`{"response": %[1]s}`, sslData) - createSslResponse := fmt.Sprintf(` + createSslResponse := ` { "response": { "uuid": null, @@ -259,7 +257,7 @@ func testAccCloud66SslCertificateLetsEncrypt(stackID string, uid string) { "key": null, "intermediate_certificate": null } - }`) + }` httpmock.RegisterResponder("POST", "https://app.cloud66.com/api/3/stacks/"+stackID+"/ssl_certificates.json", httpmock.NewStringResponder(200, createSslResponse)) httpmock.RegisterResponder("GET", "https://app.cloud66.com/api/3/stacks/"+stackID+"/ssl_certificates.json", httpmock.NewStringResponder(200, listSslResponse)) @@ -302,7 +300,7 @@ func testAccCloud66SslCertificateManual(stackID string, uid string) { } }`, sslData) deleteSslResponse := fmt.Sprintf(`{"response": %[1]s}`, sslData) - createSslResponse := fmt.Sprintf(` + createSslResponse := ` { "response": { "uuid": null, @@ -322,7 +320,7 @@ func testAccCloud66SslCertificateManual(stackID string, uid string) { "key": null, "intermediate_certificate": null } - }`) + }` httpmock.RegisterResponder("POST", "https://app.cloud66.com/api/3/stacks/"+stackID+"/ssl_certificates.json", httpmock.NewStringResponder(200, createSslResponse)) httpmock.RegisterResponder("GET", "https://app.cloud66.com/api/3/stacks/"+stackID+"/ssl_certificates.json", httpmock.NewStringResponder(200, listSslResponse)) @@ -356,7 +354,7 @@ func testAccCloud66EnvVariable(stackID string, key string, value string) { "pages": 1 } }`, envVarData) - createEnvVarResponse := fmt.Sprint(` + createEnvVarResponse := ` { "response": { "id": 3360669, @@ -371,7 +369,7 @@ func testAccCloud66EnvVariable(stackID string, key string, value string) { "finished_message": null, "finished_result": null } - }`) + }` updateEnvVarResponse := createEnvVarResponse deleteEnvVarResponse := createEnvVarResponse @@ -382,7 +380,7 @@ func testAccCloud66EnvVariable(stackID string, key string, value string) { } func testAccCloud66FirewallRequest(stackID string) { - firewallData := fmt.Sprintf(` + firewallData := ` { "id": 168806136, "from_ip": "0.0.0.0/0", @@ -397,7 +395,7 @@ func testAccCloud66FirewallRequest(stackID string) { "comments": null, "created_at": "2022-04-13T04:21:46Z", "updated_at": "2022-04-13T04:21:46Z" - }`) + }` listFirewallResponse := fmt.Sprintf(` { @@ -412,7 +410,7 @@ func testAccCloud66FirewallRequest(stackID string) { "pages": 1 } }`, firewallData) - createFirewallResponse := fmt.Sprint(` + createFirewallResponse := ` { "response": { "id": 3360669, @@ -427,7 +425,7 @@ func testAccCloud66FirewallRequest(stackID string) { "finished_message": null, "finished_result": null } - }`) + }` getFirewallResponse := fmt.Sprintf(`{ "response": %[1]s }`, firewallData) httpmock.RegisterResponder("POST", "https://app.cloud66.com/api/3/stacks/"+stackID+"/firewalls.json", httpmock.NewStringResponder(200, createFirewallResponse)) diff --git a/cloud66/resource_cloud66_env_variable.go b/cloud66/resource_cloud66_env_variable.go index 09b8818..335f7c1 100644 --- a/cloud66/resource_cloud66_env_variable.go +++ b/cloud66/resource_cloud66_env_variable.go @@ -136,7 +136,7 @@ func resourceCloud66EnvVariableImport(d *schema.ResourceData, meta interface{}) d.Set("stack_id", stackID) d.SetId(key) - resourceCloud66EnvVariableRead(d, meta) + resourceCloud66EnvVariableRead(d, meta) //nolint:golint,errcheck return []*schema.ResourceData{d}, nil } diff --git a/cloud66/resource_cloud66_firewall.go b/cloud66/resource_cloud66_firewall.go index fb7e051..148bbd2 100644 --- a/cloud66/resource_cloud66_firewall.go +++ b/cloud66/resource_cloud66_firewall.go @@ -43,7 +43,7 @@ func resourceCloud66FirewallCreate(d *schema.ResourceData, meta interface{}) err fromIp := d.Get("from_ip").(string) fromGroupId := d.Get("from_group_id").(int) fromServerId := d.Get("from_server_id").(int) - if fromIp != "" { + if fromIp != "" { //nolint:golint,gocritic newRecord.FromIp = fromIp } else if fromGroupId != 0 { newRecord.FromGroupId = fromGroupId @@ -54,7 +54,7 @@ func resourceCloud66FirewallCreate(d *schema.ResourceData, meta interface{}) err toIp := d.Get("to_ip").(string) toGroupId := d.Get("to_group_id").(int) toServerId := d.Get("to_server_id").(int) - if toIp != "" { + if toIp != "" { //nolint:golint,gocritic newRecord.ToIp = toIp } else if toGroupId != 0 { newRecord.ToGroupId = toGroupId @@ -127,7 +127,7 @@ func resourceCloud66FirewallImport(d *schema.ResourceData, meta interface{}) ([] d.Set("stack_id", stackID) d.SetId(id) - resourceCloud66FirewallRead(d, meta) + resourceCloud66FirewallRead(d, meta) //nolint:golint,errcheck return []*schema.ResourceData{d}, nil } diff --git a/cloud66/resource_cloud66_ssl_certificate.go b/cloud66/resource_cloud66_ssl_certificate.go index fd58dd0..7ad2805 100644 --- a/cloud66/resource_cloud66_ssl_certificate.go +++ b/cloud66/resource_cloud66_ssl_certificate.go @@ -208,7 +208,7 @@ func resourceCloud66SslCertificateImport(d *schema.ResourceData, meta interface{ d.Set("sha256_fingerprint", sha256Fingerprint) d.SetId(stackID) - resourceCloud66SslCertificateRead(d, meta) + resourceCloud66SslCertificateRead(d, meta) //nolint:golint,errcheck return []*schema.ResourceData{d}, nil } diff --git a/cloud66/schema_cloud66_firewall.go b/cloud66/schema_cloud66_firewall.go index 442c45e..d05eebb 100644 --- a/cloud66/schema_cloud66_firewall.go +++ b/cloud66/schema_cloud66_firewall.go @@ -23,24 +23,27 @@ type Firewall struct { } func (firewall *Firewall) Protocol() string { - if firewall.ProtocolCode == "1" { + switch firewall.ProtocolCode { + case "1": return "tcp" - } else if firewall.ProtocolCode == "2" { + case "2": return "udp" - } else if firewall.ProtocolCode == "3" { + case "3": return "icmp" - } else { + default: return firewall.ProtocolCode } } func (firewall *Firewall) SetProtocol(protocol string) { - if protocol == "tcp" { + switch protocol { + case "tcp": firewall.ProtocolCode = "1" - } else if protocol == "udp" { + case "udp": firewall.ProtocolCode = "2" - } else if protocol == "icmp" { + case "icmp": firewall.ProtocolCode = "3" + default: } }