From 332f4886d5c78a7abaeb64ce5e29f6ded53bcdbe Mon Sep 17 00:00:00 2001 From: yxxhero <11087727+yxxhero@users.noreply.github.com> Date: Mon, 6 Feb 2023 05:55:37 +0800 Subject: [PATCH] add lint ci (#127) * add lint ci Signed-off-by: yxxhero * fix lint Signed-off-by: yxxhero * fix lint issues Signed-off-by: yxxhero --------- Signed-off-by: yxxhero Co-authored-by: Yusuke Kuoka --- .github/workflows/lint.yaml | 30 ++ .golangci.yaml | 360 ++++++++++++++++++ cmd/vals/main.go | 38 +- cmd/vals/main_test.go | 3 +- io.go | 4 +- io_test.go | 1 - pkg/awsclicompat/session.go | 3 +- pkg/azureclicompat/workload.go | 5 +- pkg/config/config.go | 2 - pkg/expansion/expand_match.go | 4 +- pkg/expansion/maputil.go | 3 + pkg/providers/awskms/awskms.go | 2 +- pkg/providers/awssecrets/awssecrets.go | 13 +- pkg/providers/azurekeyvault/azurekeyvault.go | 5 +- .../azurekeyvault/azurekeyvault_test.go | 2 - pkg/providers/envsubst/envsubst.go | 3 +- pkg/providers/file/file.go | 9 +- pkg/providers/gcpsecrets/gcpsecrets.go | 3 +- pkg/providers/gcs/gcs.go | 19 +- pkg/providers/gitlab/gitlab.go | 11 +- pkg/providers/googlesheets/googlesheets.go | 16 +- pkg/providers/s3/s3.go | 7 +- pkg/providers/s3/s3_test.go | 10 +- pkg/providers/sops/sops.go | 6 +- pkg/providers/ssm/ssm.go | 8 +- pkg/providers/ssm/ssm_test.go | 1 + pkg/providers/tfstate/tfstate.go | 13 +- pkg/providers/vault/kv_helper.go | 5 +- pkg/providers/vault/vault.go | 24 +- vals.go | 12 +- vals_awssecrets_test.go | 6 +- vals_ssm_test.go | 3 +- vals_vault_test.go | 14 +- 33 files changed, 542 insertions(+), 103 deletions(-) create mode 100644 .github/workflows/lint.yaml create mode 100644 .golangci.yaml diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..ee7a046 --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,30 @@ +name: Lint + +on: + push: + branches: [ main ] + paths-ignore: [ '**.md' ] + pull_request: + branches: [ main ] + paths-ignore: [ '**.md' ] + +env: + GO_VERSION: 1.20 + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/setup-go@v3 + with: + go-version: '1.20' + + - name: Checkout code + uses: actions/checkout@v3 + + - name: Golangci lint + uses: golangci/golangci-lint-action@v3 + with: + version: v1.51.0 diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000..348c6ad --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,360 @@ +# This file contains all available configuration options +# with their default values. + +# options for analysis running +run: + # default concurrency is a available CPU number + # concurrency: 4 + + # timeout for analysis, e.g. 30s, 5m, default is 1m + timeout: 30m + + # exit code when at least one issue was found, default is 1 + issues-exit-code: 1 + + # include test files or not, default is true + tests: true + + # list of build tags, all linters use it. Default is empty list. + # build-tags: + # - mytag + + # which dirs to skip: issues from them won't be reported; + # can use regexp here: generated.*, regexp is applied on full path; + # default value is empty list, but default dirs are skipped independently + # from this option's value (see skip-dirs-use-default). + # skip-dirs: + # - src/external_libs + # - autogenerated_by_my_lib + + # default is true. Enables skipping of directories: + # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ + skip-dirs-use-default: true + + # which files to skip: they will be analyzed, but issues from them + # won't be reported. Default value is empty list, but there is + # no need to include all autogenerated files, we confidently recognize + # autogenerated files. If it's not please let us know. + # skip-files: + # - ".*\\.my\\.go$" + # - lib/bad.go + + # by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules": + # If invoked with -mod=readonly, the go command is disallowed from the implicit + # automatic updating of go.mod described above. Instead, it fails when any changes + # to go.mod are needed. This setting is most useful to check that go.mod does + # not need updates, such as in a continuous integration and testing system. + # If invoked with -mod=vendor, the go command assumes that the vendor + # directory holds the correct copies of dependencies and ignores + # the dependency descriptions in go.mod. + # modules-download-mode: readonly|release|vendor + +# output configuration options +output: + # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number" + format: line-number + + # print lines of code with issue, default is true + print-issued-lines: true + + # print linter name in the end of issue text, default is true + print-linter-name: true + +# all available settings of specific linters +linters-settings: + gci: + sections: + - standard + - default + - prefix(github.com/helmfile/vals) + + errcheck: + # report about not checking of errors in type assetions: `a := b.(MyStruct)`; + # default is false: such cases aren't reported by default. + check-type-assertions: false + + # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; + # default is false: such cases aren't reported by default. + check-blank: false + + # [deprecated] comma-separated list of pairs of the form pkg:regex + # the regex is used to ignore names within pkg. (default "fmt:.*"). + # see https://github.com/kisielk/errcheck#the-deprecated-method for details + # ignore: fmt:.* + + # path to a file containing a list of functions to exclude from checking + # see https://github.com/kisielk/errcheck#excluding-functions for details + # exclude: /path/to/file.txt + + # Disable error checking, as errorcheck detects more errors and is more configurable. + gosec: + exclude: + - "G104" + + govet: + # report about shadowed variables + check-shadowing: false + + # settings per analyzer + settings: + printf: # analyzer name, run `go tool vet help` to see all analyzers + funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf + + # enable or disable analyzers by name + # enable: + # - atomicalign + # enable-all: false + # disable: + # - shadow + # disable-all: false + golint: + # minimal confidence for issues, default is 0.8 + min-confidence: 0.8 + gofmt: + # simplify code: gofmt with `-s` option, true by default + simplify: true + goimports: + # put imports beginning with prefix after 3rd-party packages; + # it's a comma-separated list of prefixes + # local-prefixes: github.com/org/project + gocyclo: + # minimal code complexity to report, 30 by default (but we recommend 10-20) + min-complexity: 30 + gocognit: + # minimal code complexity to report, 30 by default (but we recommend 10-20) + min-complexity: 100 + maligned: + # print struct with more effective memory layout or not, false by default + suggest-new: true + dupl: + # tokens count to trigger issue, 150 by default + threshold: 100 + goconst: + # minimal length of string constant, 3 by default + min-len: 3 + # minimal occurrences count to trigger, 3 by default + min-occurrences: 8 + # depguard: + # list-type: blacklist + # include-go-root: false + # packages: + # - github.com/sirupsen/logrus + # packages-with-error-messages: + # # specify an error message to output when a blacklisted package is used + # github.com/sirupsen/logrus: "logging is allowed only by logutils.Log" + misspell: + # Correct spellings using locale preferences for US or UK. + # Default is to use a neutral variety of English. + # Setting locale to US will correct the British spelling of 'colour' to 'color'. + locale: US + ignore-words: + - GitLab + lll: + # max line length, lines longer will be reported. Default is 120. + # '\t' is counted as 1 character by default, and can be changed with the tab-width option + line-length: 120 + # tab width in spaces. Default to 1. + tab-width: 1 + unused: + # treat code as a program (not a library) and report unused exported identifiers; default is false. + # XXX: if you enable this setting, unused will report a lot of false-positives in text editors: + # if it's called for subdir of a project it can't find funcs usages. All text editor integrations + # with golangci-lint call it on a directory with the changed file. + check-exported: false + unparam: + # Inspect exported functions, default is false. Set to true if no external program/library imports your code. + # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: + # if it's called for subdir of a project it can't find external interfaces. All text editor integrations + # with golangci-lint call it on a directory with the changed file. + check-exported: false + nakedret: + # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 + max-func-lines: 30 + prealloc: + # XXX: we don't recommend using this linter before doing performance profiling. + # For most programs usage of prealloc will be a premature optimization. + + # Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them. + # True by default. + simple: true + range-loops: true # Report preallocation suggestions on range loops, true by default + for-loops: false # Report preallocation suggestions on for loops, false by default + gocritic: + # Which checks should be enabled; can't be combined with 'disabled-checks'; + # See https://go-critic.github.io/overview#checks-overview + # To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run` + # By default list of stable checks is used. + # enabled-checks: + # - rangeValCopy + + # Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty + # disabled-checks: + # - regexpMust + + # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks. + # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags". + # enabled-tags: + # - performance + + settings: # settings passed to gocritic + captLocal: # must be valid enabled check name + paramsOnly: true + # rangeValCopy: + # sizeThreshold: 32 + godox: + # report any comments starting with keywords, this is useful for TODO or FIXME comments that + # might be left in the code accidentally and should be resolved before merging + keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting + - TODO + - BUG + - FIXME + - NOTE + - OPTIMIZE # marks code that should be optimized before merging + - HACK # marks hack-arounds that should be removed before merging + dogsled: + # checks assignments with too many blank identifiers; default is 2 + max-blank-identifiers: 2 + + whitespace: + multi-if: false # Enforces newlines (or comments) after every multi-line if statement + multi-func: false # Enforces newlines (or comments) after every multi-line function signature + wsl: + # If true append is only allowed to be cuddled if appending value is + # matching variables, fields or types on line above. Default is true. + strict-append: true + # Allow calls and assignments to be cuddled as long as the lines have any + # matching variables, fields or types. Default is true. + allow-assign-and-call: true + # Allow multiline assignments to be cuddled. Default is true. + allow-multiline-assign: true + # Allow declarations (var) to be cuddled. + allow-cuddle-declarations: false + # Allow trailing comments in ending of blocks + allow-trailing-comment: false + # Force newlines in end of case at this limit (0 = never). + force-case-trailing-whitespace: 0 + revive: + ignore-generated-header: true + severity: warning + funlen: + # Checks the number of lines in a function. + # If lower than 0, disable the check. + # Default: 60 + lines: 280 + # Checks the number of statements in a function. + # If lower than 0, disable the check. + # Default: 40 + statements: 140 + +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + disable-all: true + enable: + - bodyclose + - depguard + - usestdlibvars + - reassign + - errcheck + - funlen + - gocognit + - goconst + - gofmt + - goimports + - revive + - gosimple + - govet + - ineffassign + - misspell + - nakedret + - exportloopref + - staticcheck + - typecheck + - unconvert + - unparam + - unused + - whitespace + - gci + # - gocritic + # - godox + # - gosec + # - interfacer + # - stylecheck + # - dogsled + # - dupl + # don't enable: + # - deadcode + # - gochecknoglobals + # - gochecknoinits + # - gocyclo + # - lll + # - maligned + # - prealloc + # - varcheck + +issues: + # List of regexps of issue texts to exclude, empty list by default. + # But independently from this option we use default exclude patterns, + # it can be disabled by `exclude-use-default: false`. To list all + # excluded by default patterns execute `golangci-lint run --help` + # exclude: + # - abcdef + + # Excluding configuration per-path, per-linter, per-text and per-source + exclude-rules: + # Exclude some linters from running on tests files. + - path: _test\.go + linters: + - gocyclo + - errcheck + - dupl + - gosec + - funlen + + # Exclude known linters from partially hard-vendored code, + # which is impossible to exclude via "nolint" comments. + # - path: internal/hmac/ + # text: "weak cryptographic primitive" + # linters: + # - gosec + + # Exclude some staticcheck messages + # - linters: + # - staticcheck + # text: "SA9003:" + + # Exclude lll issues for long lines with go:generate + - linters: + - lll + source: "^//go:generate " + + # Independently from option `exclude` we use default exclude patterns, + # it can be disabled by this option. To list all + # excluded by default patterns execute `golangci-lint run --help`. + # Default value for this option is true. + exclude-use-default: false + + # Maximum issues count per one linter. Set to 0 to disable. Default is 50. + max-issues-per-linter: 0 + + # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. + max-same-issues: 0 + + # Show only new issues: if there are unstaged changes or untracked files, + # only those changes are analyzed, else only changes in HEAD~ are analyzed. + # It's a super-useful option for integration of golangci-lint into existing + # large codebase. It's not practical to fix all existing issues at the moment + # of integration: much better don't allow issues in new code. + # Default is false. + new: false + + # Show only new issues created after git revision `REV` + # This should be passed as flag during individual CI jobs. + # new-from-rev: REV + + # Show only new issues created in git patch with set file path. + # new-from-patch: path/to/patch/file \ No newline at end of file diff --git a/cmd/vals/main.go b/cmd/vals/main.go index 466816c..6bb7cb8 100644 --- a/cmd/vals/main.go +++ b/cmd/vals/main.go @@ -6,9 +6,10 @@ import ( "fmt" "os" + "gopkg.in/yaml.v3" + "github.com/helmfile/vals" "github.com/helmfile/vals/pkg/log" - "gopkg.in/yaml.v3" ) var ( @@ -91,7 +92,10 @@ func main() { o := evalCmd.String("o", "yaml", "Output type which is either \"yaml\" or \"json\"") evalCmd.BoolVar(&log.Silent, "s", false, "Silent mode") e := evalCmd.Bool("exclude-secret", false, "Leave secretref+ as-is and only replace ref+") - evalCmd.Parse(os.Args[2:]) + err := evalCmd.Parse(os.Args[2:]) + if err != nil { + fatal("%v", err) + } nodes := readNodesOrFail(f) @@ -117,7 +121,10 @@ func main() { case CmdGet: getCmd := flag.NewFlagSet(CmdGet, flag.ExitOnError) getCmd.BoolVar(&log.Silent, "s", false, "Silent mode") - getCmd.Parse(os.Args[2:]) + err := getCmd.Parse(os.Args[2:]) + if err != nil { + fatal("%v", err) + } code := getCmd.Arg(0) if code == "" { @@ -129,15 +136,21 @@ func main() { fatal("%v", err) } - os.Stdout.WriteString(v) + _, err = os.Stdout.WriteString(v) + if err != nil { + fatal("%v", err) + } case CmdExec: execCmd := flag.NewFlagSet(CmdExec, flag.ExitOnError) f := execCmd.String("f", "", "YAML/JSON file to be loaded to set envvars") - execCmd.Parse(os.Args[2:]) + err := execCmd.Parse(os.Args[2:]) + if err != nil { + fatal("%v", err) + } m := readOrFail(f) - err := vals.Exec(m, execCmd.Args()) + err = vals.Exec(m, execCmd.Args()) if err != nil { fatal("%v", err) } @@ -145,7 +158,10 @@ func main() { execEnv := flag.NewFlagSet(CmdEnv, flag.ExitOnError) f := execEnv.String("f", "", "YAML/JSON file to be loaded to set envvars") export := execEnv.Bool("export", false, "Prepend 'export' to each line") - execEnv.Parse(os.Args[2:]) + err := execEnv.Parse(os.Args[2:]) + if err != nil { + fatal("%v", err) + } m := readOrFail(f) @@ -163,7 +179,10 @@ func main() { evalCmd := flag.NewFlagSet(CmdKsDecode, flag.ExitOnError) f := evalCmd.String("f", "", "YAML/JSON file to be decoded") o := evalCmd.String("o", "yaml", "Output type which is either \"yaml\" or \"json\"") - evalCmd.Parse(os.Args[2:]) + err := evalCmd.Parse(os.Args[2:]) + if err != nil { + fatal("%v", err) + } nodes := readNodesOrFail(f) @@ -194,8 +213,7 @@ func KsDecode(node yaml.Node) (*yaml.Node, error) { return nil, fmt.Errorf("unexpected kind of node: expected %d, got %d", yaml.DocumentNode, node.Kind) } - var res yaml.Node - res = node + var res yaml.Node = node var kk yaml.Node var vv yaml.Node diff --git a/cmd/vals/main_test.go b/cmd/vals/main_test.go index b23d4af..054bc11 100644 --- a/cmd/vals/main_test.go +++ b/cmd/vals/main_test.go @@ -2,8 +2,9 @@ package main import ( "bytes" - "gopkg.in/yaml.v3" "testing" + + "gopkg.in/yaml.v3" ) func TestKsDecode(t *testing.T) { diff --git a/io.go b/io.go index f90cb54..887a507 100644 --- a/io.go +++ b/io.go @@ -20,7 +20,9 @@ func Inputs(f string) ([]yaml.Node, error) { return nil, err } reader = fp - defer fp.Close() + defer func() { + _ = fp.Close() + }() } else { return nil, fmt.Errorf("Nothing to eval: No file specified") } diff --git a/io_test.go b/io_test.go index 6916d96..2e6d981 100644 --- a/io_test.go +++ b/io_test.go @@ -74,7 +74,6 @@ func Test_InputOutput(t *testing.T) { if bufRoundTrip.String() != tt.input { t.Errorf("Expected %q, got %q", tt.input, bufRoundTrip.String()) } - }) } } diff --git a/pkg/awsclicompat/session.go b/pkg/awsclicompat/session.go index cd919a6..4df5fb6 100644 --- a/pkg/awsclicompat/session.go +++ b/pkg/awsclicompat/session.go @@ -1,10 +1,11 @@ package awsclicompat import ( + "os" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials/stscreds" "github.com/aws/aws-sdk-go/aws/session" - "os" ) // NewSession creates a new AWS session for the given AWS region and AWS PROFILE. diff --git a/pkg/azureclicompat/workload.go b/pkg/azureclicompat/workload.go index 2f1db86..a3cb0e7 100644 --- a/pkg/azureclicompat/workload.go +++ b/pkg/azureclicompat/workload.go @@ -4,12 +4,12 @@ import ( "context" "errors" "fmt" + "os" "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential" - "os" ) // WorkloadIdentityClient !! Warning - A regrettable hack !! @@ -77,6 +77,9 @@ func (c *WorkloadIdentityClient) GetToken( cred, confidential.WithAuthority(c.authorityUrl), ) + if err != nil { + return azcore.AccessToken{}, err + } result, err := client.AcquireTokenByCredential(ctx, opts.Scopes) if err != nil { diff --git a/pkg/config/config.go b/pkg/config/config.go index 41d7936..5cad76f 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -140,8 +140,6 @@ func (m MapConfig) Map(path ...string) map[string]interface{} { default: return nil } - - panic("invalid state") } func Map(m map[string]interface{}) MapConfig { diff --git a/pkg/expansion/expand_match.go b/pkg/expansion/expand_match.go index 7010683..0ea8eb2 100644 --- a/pkg/expansion/expand_match.go +++ b/pkg/expansion/expand_match.go @@ -60,9 +60,9 @@ func (e *ExpandRegexMatch) InMap(target map[string]interface{}) (map[string]inte return nil, err } - switch ret.(type) { + switch ret := ret.(type) { case map[string]interface{}: - return ret.(map[string]interface{}), nil + return ret, nil default: return nil, fmt.Errorf("unexpected type: %v: %T", ret, ret) } diff --git a/pkg/expansion/maputil.go b/pkg/expansion/maputil.go index 374e090..2f8a23c 100644 --- a/pkg/expansion/maputil.go +++ b/pkg/expansion/maputil.go @@ -75,6 +75,9 @@ func ModifyStringValues(v interface{}, f func(path string) (interface{}, error)) var deleted []string for k, v := range typed_v { ok, err := merge(extends, k, v) + if err != nil { + return nil, err + } if ok { deleted = append(deleted, k) continue diff --git a/pkg/providers/awskms/awskms.go b/pkg/providers/awskms/awskms.go index 7995af2..eb48365 100644 --- a/pkg/providers/awskms/awskms.go +++ b/pkg/providers/awskms/awskms.go @@ -3,9 +3,9 @@ package awskms import ( "encoding/base64" + "github.com/aws/aws-sdk-go/service/kms" "gopkg.in/yaml.v3" - "github.com/aws/aws-sdk-go/service/kms" "github.com/helmfile/vals/pkg/api" "github.com/helmfile/vals/pkg/awsclicompat" ) diff --git a/pkg/providers/awssecrets/awssecrets.go b/pkg/providers/awssecrets/awssecrets.go index cc0e319..f0b91a4 100644 --- a/pkg/providers/awssecrets/awssecrets.go +++ b/pkg/providers/awssecrets/awssecrets.go @@ -5,13 +5,13 @@ import ( "fmt" "strings" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/secretsmanager" + "gopkg.in/yaml.v3" + "github.com/helmfile/vals/pkg/api" "github.com/helmfile/vals/pkg/awsclicompat" "github.com/helmfile/vals/pkg/log" - "gopkg.in/yaml.v3" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/secretsmanager" ) type provider struct { @@ -69,7 +69,6 @@ func (p *provider) GetString(key string) (string, error) { } func (p *provider) GetStringMap(key string) (map[string]interface{}, error) { - yamlStr, err := p.GetString(key) if err == nil { m := map[string]interface{}{} @@ -101,9 +100,7 @@ func (p *provider) GetStringMap(key string) (map[string]interface{}, error) { var suffixes []string switch f := f.(type) { case []string: - for _, v := range f { - suffixes = append(suffixes, v) - } + suffixes = append(suffixes, f...) case []interface{}: for _, v := range f { suffixes = append(suffixes, fmt.Sprintf("%v", v)) diff --git a/pkg/providers/azurekeyvault/azurekeyvault.go b/pkg/providers/azurekeyvault/azurekeyvault.go index 4d9357c..b3eea16 100644 --- a/pkg/providers/azurekeyvault/azurekeyvault.go +++ b/pkg/providers/azurekeyvault/azurekeyvault.go @@ -3,13 +3,14 @@ package azurekeyvault import ( "context" "fmt" + "strings" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets" - "strings" + "gopkg.in/yaml.v3" "github.com/helmfile/vals/pkg/api" "github.com/helmfile/vals/pkg/azureclicompat" - "gopkg.in/yaml.v3" ) type provider struct { diff --git a/pkg/providers/azurekeyvault/azurekeyvault_test.go b/pkg/providers/azurekeyvault/azurekeyvault_test.go index 6910371..eade311 100644 --- a/pkg/providers/azurekeyvault/azurekeyvault_test.go +++ b/pkg/providers/azurekeyvault/azurekeyvault_test.go @@ -8,7 +8,6 @@ import ( ) func Test_parseKey(t *testing.T) { - testcases := []struct { key string want secretSpec @@ -66,7 +65,6 @@ func Test_parseKey(t *testing.T) { for i := range testcases { tc := testcases[i] t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { - got, err := parseKey(tc.key) if err != nil { if err.Error() != tc.wantErr { diff --git a/pkg/providers/envsubst/envsubst.go b/pkg/providers/envsubst/envsubst.go index 25b2119..84cf167 100644 --- a/pkg/providers/envsubst/envsubst.go +++ b/pkg/providers/envsubst/envsubst.go @@ -4,8 +4,9 @@ import ( "strings" envSubst "github.com/a8m/envsubst" - "github.com/helmfile/vals/pkg/api" "gopkg.in/yaml.v3" + + "github.com/helmfile/vals/pkg/api" ) type provider struct { diff --git a/pkg/providers/file/file.go b/pkg/providers/file/file.go index f589ec7..85b3403 100644 --- a/pkg/providers/file/file.go +++ b/pkg/providers/file/file.go @@ -1,11 +1,12 @@ package file import ( - "io/ioutil" + "os" "strings" - "github.com/helmfile/vals/pkg/api" "gopkg.in/yaml.v3" + + "github.com/helmfile/vals/pkg/api" ) type provider struct { @@ -18,7 +19,7 @@ func New(cfg api.StaticConfig) *provider { func (p *provider) GetString(key string) (string, error) { key = strings.TrimSuffix(key, "/") - bs, err := ioutil.ReadFile(key) + bs, err := os.ReadFile(key) if err != nil { return "", err } @@ -27,7 +28,7 @@ func (p *provider) GetString(key string) (string, error) { func (p *provider) GetStringMap(key string) (map[string]interface{}, error) { key = strings.TrimSuffix(key, "/") - bs, err := ioutil.ReadFile(key) + bs, err := os.ReadFile(key) if err != nil { return nil, err } diff --git a/pkg/providers/gcpsecrets/gcpsecrets.go b/pkg/providers/gcpsecrets/gcpsecrets.go index 6884b66..fba71f6 100644 --- a/pkg/providers/gcpsecrets/gcpsecrets.go +++ b/pkg/providers/gcpsecrets/gcpsecrets.go @@ -8,9 +8,10 @@ import ( "strings" sm "cloud.google.com/go/secretmanager/apiv1" - "github.com/helmfile/vals/pkg/api" smpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1" "gopkg.in/yaml.v3" + + "github.com/helmfile/vals/pkg/api" ) // Format: ref+gcpsecrets://project/mykey[?version=VERSION][&fallback=value=valuewhenkeyisnotfound][&optional=true]#/yaml_or_json_key/in/secret diff --git a/pkg/providers/gcs/gcs.go b/pkg/providers/gcs/gcs.go index cd6aba6..def342c 100644 --- a/pkg/providers/gcs/gcs.go +++ b/pkg/providers/gcs/gcs.go @@ -3,16 +3,15 @@ package gcs import ( "context" "fmt" - "io/ioutil" + "io" "strconv" - - "cloud.google.com/go/storage" - "strings" "time" - "github.com/helmfile/vals/pkg/api" + "cloud.google.com/go/storage" "gopkg.in/yaml.v3" + + "github.com/helmfile/vals/pkg/api" ) type provider struct { @@ -52,7 +51,9 @@ func (p *provider) GetString(key string) (string, error) { if err != nil { return "", fmt.Errorf("storage.NewClient: %v", err) } - defer client.Close() + defer func() { + _ = client.Close() + }() ctx, cancel := context.WithTimeout(ctx, time.Second*10) defer cancel() @@ -81,9 +82,11 @@ func (p *provider) GetString(key string) (string, error) { } } - defer rc.Close() + defer func() { + _ = rc.Close() + }() - slurp, err := ioutil.ReadAll(rc) + slurp, err := io.ReadAll(rc) if err != nil { return "", err } diff --git a/pkg/providers/gitlab/gitlab.go b/pkg/providers/gitlab/gitlab.go index 3393c6b..5bb423d 100644 --- a/pkg/providers/gitlab/gitlab.go +++ b/pkg/providers/gitlab/gitlab.go @@ -9,8 +9,9 @@ import ( "os" "strings" - "github.com/helmfile/vals/pkg/api" "gopkg.in/yaml.v3" + + "github.com/helmfile/vals/pkg/api" ) type gitlabSecret struct { @@ -69,7 +70,7 @@ func (p *provider) GetString(key string) (string, error) { TLSClientConfig: &tls.Config{InsecureSkipVerify: p.SSLVerify}, } client := &http.Client{Transport: tr} - req, err := http.NewRequest("GET", url, nil) + req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { return "", err } @@ -82,7 +83,10 @@ func (p *provider) GetString(key string) (string, error) { if err != nil { return "", err } - defer res.Body.Close() + + defer func() { + _ = res.Body.Close() + }() var g gitlabSecret err = json.NewDecoder(res.Body).Decode(&g) @@ -94,7 +98,6 @@ func (p *provider) GetString(key string) (string, error) { } func (p *provider) GetStringMap(key string) (map[string]interface{}, error) { - secretMap := map[string]interface{}{} secretString, err := p.GetString(key) diff --git a/pkg/providers/googlesheets/googlesheets.go b/pkg/providers/googlesheets/googlesheets.go index bf20286..2fd87f2 100644 --- a/pkg/providers/googlesheets/googlesheets.go +++ b/pkg/providers/googlesheets/googlesheets.go @@ -8,12 +8,12 @@ import ( "os" "strings" - "github.com/helmfile/vals/pkg/api" - "golang.org/x/oauth2" "golang.org/x/oauth2/google" "google.golang.org/api/option" "google.golang.org/api/sheets/v4" + + "github.com/helmfile/vals/pkg/api" ) type provider struct { @@ -84,7 +84,10 @@ func tokenFromFile(file string) (*oauth2.Token, error) { if err != nil { return nil, err } - defer f.Close() + defer func() { + _ = f.Close() + }() + tok := &oauth2.Token{} err = json.NewDecoder(f).Decode(tok) return tok, err @@ -97,9 +100,10 @@ func saveToken(path string, token *oauth2.Token) error { if err != nil { return fmt.Errorf("unable to cache oauth token: %w", err) } - defer f.Close() - json.NewEncoder(f).Encode(token) - return nil + defer func() { + _ = f.Close() + }() + return json.NewEncoder(f).Encode(token) } func newServiceAccountClient(serviceAccountJSONKey []byte, scope ...string) (*http.Client, error) { diff --git a/pkg/providers/s3/s3.go b/pkg/providers/s3/s3.go index 6a332e3..f9f13a5 100644 --- a/pkg/providers/s3/s3.go +++ b/pkg/providers/s3/s3.go @@ -2,16 +2,17 @@ package s3 import ( "fmt" - "io/ioutil" + "io" "strings" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/s3" "github.com/aws/aws-sdk-go/service/s3/s3iface" + "gopkg.in/yaml.v3" + "github.com/helmfile/vals/pkg/api" "github.com/helmfile/vals/pkg/awsclicompat" "github.com/helmfile/vals/pkg/log" - "gopkg.in/yaml.v3" ) type provider struct { @@ -60,7 +61,7 @@ func (p *provider) GetString(key string) (string, error) { log.Debugf("s3: successfully retrieved object for key=%s", key) - all, err := ioutil.ReadAll(out.Body) + all, err := io.ReadAll(out.Body) if err != nil { return "", fmt.Errorf("reading s3 object body: %w", err) } diff --git a/pkg/providers/s3/s3_test.go b/pkg/providers/s3/s3_test.go index 4d3595f..0332579 100644 --- a/pkg/providers/s3/s3_test.go +++ b/pkg/providers/s3/s3_test.go @@ -3,14 +3,16 @@ package s3 import ( "errors" "fmt" + "io" + "strings" + "testing" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/s3" "github.com/aws/aws-sdk-go/service/s3/s3iface" "github.com/google/go-cmp/cmp" + "github.com/helmfile/vals/pkg/config" - "io/ioutil" - "strings" - "testing" ) type mockedS3 struct { @@ -23,7 +25,7 @@ type mockedS3 struct { func Output(b string) *s3.GetObjectOutput { return &s3.GetObjectOutput{ - Body: ioutil.NopCloser(strings.NewReader(b)), + Body: io.NopCloser(strings.NewReader(b)), } } diff --git a/pkg/providers/sops/sops.go b/pkg/providers/sops/sops.go index 9ad70c9..18f807d 100644 --- a/pkg/providers/sops/sops.go +++ b/pkg/providers/sops/sops.go @@ -4,11 +4,11 @@ import ( "encoding/base64" "fmt" - "github.com/helmfile/vals/pkg/api" - "github.com/helmfile/vals/pkg/log" + "go.mozilla.org/sops/v3/decrypt" "gopkg.in/yaml.v3" - "go.mozilla.org/sops/v3/decrypt" + "github.com/helmfile/vals/pkg/api" + "github.com/helmfile/vals/pkg/log" ) type provider struct { diff --git a/pkg/providers/ssm/ssm.go b/pkg/providers/ssm/ssm.go index 775df38..7f7f870 100644 --- a/pkg/providers/ssm/ssm.go +++ b/pkg/providers/ssm/ssm.go @@ -6,14 +6,14 @@ import ( "strconv" "strings" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ssm" "github.com/aws/aws-sdk-go/service/ssm/ssmiface" + "gopkg.in/yaml.v3" + "github.com/helmfile/vals/pkg/api" "github.com/helmfile/vals/pkg/awsclicompat" "github.com/helmfile/vals/pkg/log" - "gopkg.in/yaml.v3" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/ssm" ) type provider struct { diff --git a/pkg/providers/ssm/ssm_test.go b/pkg/providers/ssm/ssm_test.go index e0fb231..76a6c5a 100644 --- a/pkg/providers/ssm/ssm_test.go +++ b/pkg/providers/ssm/ssm_test.go @@ -10,6 +10,7 @@ import ( "github.com/aws/aws-sdk-go/service/ssm" "github.com/aws/aws-sdk-go/service/ssm/ssmiface" "github.com/google/go-cmp/cmp" + "github.com/helmfile/vals/pkg/config" ) diff --git a/pkg/providers/tfstate/tfstate.go b/pkg/providers/tfstate/tfstate.go index 4723e7a..888cdb3 100644 --- a/pkg/providers/tfstate/tfstate.go +++ b/pkg/providers/tfstate/tfstate.go @@ -6,9 +6,9 @@ import ( "strings" "sync" - "github.com/helmfile/vals/pkg/api" - "github.com/fujiwara/tfstate-lookup/tfstate" + + "github.com/helmfile/vals/pkg/api" ) type provider struct { @@ -63,8 +63,13 @@ func (p *provider) ReadTFState(f, k string) (*tfstate.TFState, error) { if p.awsProfile != "" { v := os.Getenv("AWS_PROFILE") - os.Setenv("AWS_PROFILE", p.awsProfile) - defer os.Setenv("AWS_PROFILE", v) + err := os.Setenv("AWS_PROFILE", p.awsProfile) + if err != nil { + return nil, fmt.Errorf("setting AWS_PROFILE envvar: %w", err) + } + defer func() { + _ = os.Setenv("AWS_PROFILE", v) + }() } switch p.backend { diff --git a/pkg/providers/vault/kv_helper.go b/pkg/providers/vault/kv_helper.go index dda10d5..e852ab1 100644 --- a/pkg/providers/vault/kv_helper.go +++ b/pkg/providers/vault/kv_helper.go @@ -22,7 +22,9 @@ func kvPreflightVersionRequest(client *api.Client, path string) (string, int, er r := client.NewRequest("GET", "/v1/sys/internal/ui/mounts/"+path) resp, err := client.RawRequest(r) if resp != nil { - defer resp.Body.Close() + defer func() { + _ = resp.Body.Close() + }() } if err != nil { // If we get a 404 we are using an older version of vault, default to @@ -82,4 +84,3 @@ func addPrefixToVKVPath(p, mountPath, apiPrefix string) string { return path.Join(mountPath, apiPrefix, p) } } - diff --git a/pkg/providers/vault/vault.go b/pkg/providers/vault/vault.go index f9594ae..083d910 100644 --- a/pkg/providers/vault/vault.go +++ b/pkg/providers/vault/vault.go @@ -2,15 +2,15 @@ package vault import ( "fmt" - "io/ioutil" + "io" "os" "path/filepath" "strings" + vault "github.com/hashicorp/vault/api" + "github.com/helmfile/vals/pkg/api" "github.com/helmfile/vals/pkg/log" - - vault "github.com/hashicorp/vault/api" ) const ( @@ -39,11 +39,6 @@ type provider struct { Version string } -type appRoleLogin struct { - RoleID string `json:"role_id,omitempty"` - SecretID string `json:"secret_id,omitempty"` -} - func New(cfg api.StaticConfig) *provider { p := &provider{} p.Proto = cfg.String("proto") @@ -173,7 +168,9 @@ func (p *provider) ensureClient() (*vault.Client, error) { cfg.Address = p.Address } if strings.Contains(p.Address, "127.0.0.1") { - cfg.ConfigureTLS(&vault.TLSConfig{Insecure: true}) + if err := cfg.ConfigureTLS(&vault.TLSConfig{Insecure: true}); err != nil { + return nil, err + } } cli, err := vault.NewClient(cfg) if err != nil { @@ -220,7 +217,6 @@ func (p *provider) ensureClient() (*vault.Client, error) { } } } else if p.AuthMethod == "approle" { - data := map[string]interface{}{ "role_id": p.RoleId, "secret_id": p.SecretId, @@ -245,11 +241,13 @@ func (p *provider) ensureClient() (*vault.Client, error) { cli.SetToken(resp.Auth.ClientToken) } else if p.AuthMethod == "kubernetes" { fd, err := os.Open(kubernetesJwtTokenPath) - defer fd.Close() + defer func() { + _ = fd.Close() + }() if err != nil { return nil, fmt.Errorf("unable to read file containing service account token: %w", err) } - jwt, err := ioutil.ReadAll(fd) + jwt, err := io.ReadAll(fd) if err != nil { return nil, fmt.Errorf("unable to read file containing service account token: %w", err) } @@ -282,7 +280,7 @@ func (p *provider) ensureClient() (*vault.Client, error) { } func (p *provider) readTokenFile(path string) (string, error) { - buff, err := ioutil.ReadFile(path) + buff, err := os.ReadFile(path) if err != nil { return "", err } diff --git a/vals.go b/vals.go index 80da4df..d611ae3 100644 --- a/vals.go +++ b/vals.go @@ -10,12 +10,11 @@ import ( "strings" "sync" - "github.com/helmfile/vals/pkg/config" - "github.com/helmfile/vals/pkg/providers/googlesheets" - "github.com/helmfile/vals/pkg/providers/s3" - lru "github.com/hashicorp/golang-lru" + "gopkg.in/yaml.v3" + "github.com/helmfile/vals/pkg/api" + "github.com/helmfile/vals/pkg/config" "github.com/helmfile/vals/pkg/expansion" "github.com/helmfile/vals/pkg/providers/awskms" "github.com/helmfile/vals/pkg/providers/awssecrets" @@ -26,13 +25,14 @@ import ( "github.com/helmfile/vals/pkg/providers/gcpsecrets" "github.com/helmfile/vals/pkg/providers/gcs" "github.com/helmfile/vals/pkg/providers/gitlab" + "github.com/helmfile/vals/pkg/providers/googlesheets" + "github.com/helmfile/vals/pkg/providers/s3" "github.com/helmfile/vals/pkg/providers/sops" "github.com/helmfile/vals/pkg/providers/ssm" "github.com/helmfile/vals/pkg/providers/tfstate" "github.com/helmfile/vals/pkg/providers/vault" "github.com/helmfile/vals/pkg/stringmapprovider" "github.com/helmfile/vals/pkg/stringprovider" - "gopkg.in/yaml.v3" ) const ( @@ -120,6 +120,7 @@ func New(opts Options) (*Runtime, error) { return r, nil } +// nolint func (r *Runtime) prepare() (*expansion.ExpandRegexMatch, error) { var err error @@ -487,6 +488,7 @@ func Get(code string) (string, error) { return runtime.Get(code) } +// nolint func Load(conf api.StaticConfig, opt ...Option) (map[string]interface{}, error) { ctx := &ctx{} for _, o := range opt { diff --git a/vals_awssecrets_test.go b/vals_awssecrets_test.go index 5a3b5a7..e522dd2 100644 --- a/vals_awssecrets_test.go +++ b/vals_awssecrets_test.go @@ -2,13 +2,16 @@ package vals import ( "fmt" + "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/secretsmanager" + "github.com/helmfile/vals/pkg/awsclicompat" config2 "github.com/helmfile/vals/pkg/config" - "testing" ) +// nolint func TestValues_AWSSecrets_String(t *testing.T) { client := secretsmanager.New(awsclicompat.NewSession("", "")) @@ -114,6 +117,7 @@ func TestValues_AWSSecrets_String(t *testing.T) { } } +// nolint func TestValues_AWSSecrets_Map(t *testing.T) { // TODO // Pre-requisite: diff --git a/vals_ssm_test.go b/vals_ssm_test.go index c500fe2..3d66c95 100644 --- a/vals_ssm_test.go +++ b/vals_ssm_test.go @@ -2,8 +2,9 @@ package vals import ( "fmt" - config2 "github.com/helmfile/vals/pkg/config" "testing" + + config2 "github.com/helmfile/vals/pkg/config" ) func TestValues_SSM_String(t *testing.T) { diff --git a/vals_vault_test.go b/vals_vault_test.go index aedaa2a..ea4e1db 100644 --- a/vals_vault_test.go +++ b/vals_vault_test.go @@ -3,14 +3,14 @@ package vals import ( "context" "fmt" - config2 "github.com/helmfile/vals/pkg/config" - "io/ioutil" "os" "os/exec" "testing" "github.com/google/go-cmp/cmp" "github.com/hashicorp/vault/api" + + config2 "github.com/helmfile/vals/pkg/config" ) type Conn struct { @@ -91,10 +91,10 @@ func TestValues_Vault_EvalTemplate(t *testing.T) { addr, stop := SetupVaultKV( t, map[string]map[string]interface{}{ - "mykv/foo": map[string]interface{}{ + "mykv/foo": { "mykey": "myvalue", }, - "mykv/objs": map[string]interface{}{ + "mykv/objs": { "myyaml": `yamlkey1: yamlval1 `, "myjson": `{"jsonkey1":"jsonval1"} @@ -537,12 +537,12 @@ func TestValues_Vault_Map_YAML(t *testing.T) { // // vault write mykv/yamltest myyaml="$(cat myyaml.yaml)" myjson="$(cat myjson.json)" - yamlContent, err := ioutil.ReadFile("myyaml.yaml") + yamlContent, err := os.ReadFile("myyaml.yaml") if err != nil { t.Fatalf("%v", err) } - jsonContent, err := ioutil.ReadFile("myjson.json") + jsonContent, err := os.ReadFile("myjson.json") if err != nil { t.Fatalf("%v", err) } @@ -550,7 +550,7 @@ func TestValues_Vault_Map_YAML(t *testing.T) { addr, stop := SetupVaultKV( t, map[string]map[string]interface{}{ - "mykv/yamltest": map[string]interface{}{ + "mykv/yamltest": { "myyaml": string(yamlContent), "myjson": string(jsonContent), },