diff --git a/docs/configuring-kubelinter.md b/docs/configuring-kubelinter.md index 76bd22319..cb817fec1 100644 --- a/docs/configuring-kubelinter.md +++ b/docs/configuring-kubelinter.md @@ -51,11 +51,13 @@ checks: ## Ignore paths To ignore checks on files or directories under certain paths, add ignored paths to `ignorePaths`. +Ignore path uses [`**` match syntax](https://pkg.go.dev/github.com/bmatcuk/doublestar#Match) ```yaml checks: ignorePaths: - - ~/foo/bar - - ../baz + - ~/foo/bar/** + - /**/*/foo/** + - ../baz/** - /tmp/*.yaml ``` > Equivalent CLI flag is `--ignore-paths` diff --git a/e2etests/bats-tests.sh b/e2etests/bats-tests.sh index 35784801b..d29615db9 100755 --- a/e2etests/bats-tests.sh +++ b/e2etests/bats-tests.sh @@ -868,3 +868,11 @@ get_value_from() { [[ "${failing_resource}" == "bad-irsa-role" ]] [[ "${count}" == "2" ]] } + +@test "flag-ignore-paths" { + tmp="." + cmd="${KUBE_LINTER_BIN} lint --ignore-paths \"tests/**\" --ignore-paths \"e2etests/**\" ${tmp}" + run ${cmd} + print_info "${status}" "${output}" "${cmd}" "${tmp}" + [ "$status" -eq 0 ] +} diff --git a/e2etests/check-bats-tests.sh b/e2etests/check-bats-tests.sh index 27c74873b..283717746 100755 --- a/e2etests/check-bats-tests.sh +++ b/e2etests/check-bats-tests.sh @@ -4,7 +4,7 @@ run() { local tmp_write_dir=/tmp/kubelinter/$(date +'%d-%m-%Y-%H-%M') mkdir -p "${tmp_write_dir}" - grep "@test" e2etests/bats-tests.sh | grep -v 'template-' | cut -d'"' -f2 > ${tmp_write_dir}/batstests.log + grep "@test" e2etests/bats-tests.sh | grep -v 'flag-' | grep -v 'template-' | cut -d'"' -f2 > ${tmp_write_dir}/batstests.log ${KUBE_LINTER_BIN:-kube-linter} checks list --format json | jq -r '.[].name' > ${tmp_write_dir}/kubelinterchecks.log diff -c ${tmp_write_dir}/kubelinterchecks.log ${tmp_write_dir}/batstests.log || { echo >&2 "ERROR: The output of '${KUBE_LINTER_BIN} checks list' differs from the tests in 'e2etests/bats-tests.sh'. See above diff."; exit 1; } } diff --git a/pkg/configresolver/config_resolver.go b/pkg/configresolver/config_resolver.go index 3e304a9b3..0fe818bf8 100644 --- a/pkg/configresolver/config_resolver.go +++ b/pkg/configresolver/config_resolver.go @@ -1,16 +1,13 @@ package configresolver import ( - "path/filepath" - - "github.com/mitchellh/go-homedir" - "github.com/pkg/errors" "golang.stackrox.io/kube-linter/internal/defaultchecks" "golang.stackrox.io/kube-linter/internal/errorhelpers" "golang.stackrox.io/kube-linter/internal/set" "golang.stackrox.io/kube-linter/pkg/builtinchecks" "golang.stackrox.io/kube-linter/pkg/checkregistry" "golang.stackrox.io/kube-linter/pkg/config" + "golang.stackrox.io/kube-linter/pkg/pathutil" ) // LoadCustomChecksInto loads the custom checks from the config into the check registry. @@ -65,7 +62,7 @@ func GetIgnorePaths(cfg *config.Config) ([]string, error) { errorList := errorhelpers.NewErrorList("check ignore paths") ignorePaths := set.NewStringSet() for _, path := range cfg.Checks.IgnorePaths { - res, err := getIgnorePath(path) + res, err := pathutil.GetAbsolutPath(path) if err != nil { errorList.AddError(err) continue @@ -80,22 +77,3 @@ func GetIgnorePaths(cfg *config.Config) ([]string, error) { return i < j }), nil } - -func getIgnorePath(path string) (string, error) { - switch { - case path[0] == '~': - expandedPath, err := homedir.Expand(path) - if err != nil { - return "", errors.Wrapf(err, "could not expand path: %q", expandedPath) - } - return expandedPath, nil - case !filepath.IsAbs(path): - absPath, err := filepath.Abs(path) - if err != nil { - return "", errors.Wrapf(err, "could not expand non-absolute path: %q", absPath) - } - return absPath, nil - default: - return path, nil - } -} diff --git a/pkg/lintcontext/create_contexts.go b/pkg/lintcontext/create_contexts.go index ba4a9aa8f..901aa9c22 100644 --- a/pkg/lintcontext/create_contexts.go +++ b/pkg/lintcontext/create_contexts.go @@ -7,6 +7,8 @@ import ( "sort" "strings" + "golang.stackrox.io/kube-linter/pkg/pathutil" + "github.com/bmatcuk/doublestar/v4" "github.com/pkg/errors" "golang.stackrox.io/kube-linter/internal/set" @@ -53,10 +55,13 @@ fileOrDirsLoop: } for _, path := range ignorePaths { - // Useing doublestar to enable ** + // Using doublestar to enable ** // See https://github.com/golang/go/issues/11862 - globMatch, _ := doublestar.PathMatch(path, fileOrDir) - if strings.HasPrefix(fileOrDir, path) || globMatch { + globMatch, err := doublestar.PathMatch(path, fileOrDir) + if err != nil { + return nil, errors.Wrapf(err, "could not match pattern %s", path) + } + if globMatch { continue fileOrDirsLoop } } @@ -70,6 +75,20 @@ fileOrDirsLoop: return nil } + for _, path := range ignorePaths { + absPath, err := pathutil.GetAbsolutPath(currentPath) + if err != nil { + return errors.Wrapf(err, "could not get absolute path for %s", currentPath) + } + globMatch, err := doublestar.PathMatch(path, absPath) + if err != nil { + return errors.Wrapf(err, "could not match pattern %s", path) + } + if globMatch { + return nil + } + } + if !info.IsDir() { if strings.HasSuffix(strings.ToLower(currentPath), ".tgz") { ctx := newCtx(options) diff --git a/pkg/lintcontext/create_contexts_test.go b/pkg/lintcontext/create_contexts_test.go index 7f175eda9..33a917e0c 100644 --- a/pkg/lintcontext/create_contexts_test.go +++ b/pkg/lintcontext/create_contexts_test.go @@ -7,6 +7,8 @@ import ( "path/filepath" "testing" + "golang.stackrox.io/kube-linter/pkg/pathutil" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -16,11 +18,34 @@ const ( chartDirectory = "../../tests/testdata/mychart" renamedTarball = "../../tests/testdata/my-renamed-chart-0.1.0.tgz" renamedChartDir = "../../tests/testdata/my-renamed-chart" - mockIgnorePath = "../../tests/testdata/" + mockIgnorePath = "../../tests/testdata/**" mockGlobIgnorePath = "../../tests/**" mockPath = "mock path" ) +func TestCreateContextsWithIgnorePaths(t *testing.T) { + ignoredPaths := []string{ + "../../.golangci?yml", + "/**/*/testdata/**/*", + "/**/*/checks/**/*", + "/**/*/test_helper/**/*", + "../../pkg/**/*", + "../../.pre-commit-hooks*", + "../../.github/**", + } + ignoredAbsPaths := make([]string, 0, len(ignoredPaths)) + for _, p := range ignoredPaths { + abs, err := pathutil.GetAbsolutPath(p) + assert.NoError(t, err) + ignoredAbsPaths = append(ignoredAbsPaths, abs) + } + + testPath := "../../" + contexts, err := CreateContexts(ignoredAbsPaths, testPath) + assert.NoError(t, err) + checkEmptyLintContext(t, contexts) +} + func TestCreateContextsObjectPaths(t *testing.T) { bools := []bool{false, true} @@ -116,7 +141,7 @@ func createContextsAndVerifyPaths(t *testing.T, useTarball, useAbsolutePath, ren } func checkEmptyLintContext(t *testing.T, lintCtxs []LintContext) { - assert.Len(t, lintCtxs, 0, "expecting no lint context") + assert.Empty(t, lintCtxs, "expecting no lint context") } func verifyAndGetContext(t *testing.T, lintCtxs []LintContext) LintContext { diff --git a/pkg/pathutil/path.go b/pkg/pathutil/path.go new file mode 100644 index 000000000..d86c4b0bd --- /dev/null +++ b/pkg/pathutil/path.go @@ -0,0 +1,28 @@ +package pathutil + +import ( + "path/filepath" + + "github.com/mitchellh/go-homedir" + "github.com/pkg/errors" +) + +// GetAbsolutPath returns the absolute representation of given path. +func GetAbsolutPath(path string) (string, error) { + switch { + case path[0] == '~': + expandedPath, err := homedir.Expand(path) + if err != nil { + return "", errors.Wrapf(err, "could not expand path: %q", expandedPath) + } + return expandedPath, nil + case !filepath.IsAbs(path): + absPath, err := filepath.Abs(path) + if err != nil { + return "", errors.Wrapf(err, "could not expand non-absolute path: %q", absPath) + } + return absPath, nil + default: + return path, nil + } +}