From 3acea942907729e76e51b39a5c2986fc8ad48597 Mon Sep 17 00:00:00 2001 From: Yury Tsarev Date: Mon, 13 Sep 2021 12:11:08 +0200 Subject: [PATCH 1/3] Return non-zero exit status on no valid objects Instead of printing the warning and return 0 exit status return Error and exit with 1 Reasoning: our kube-linter pipelines where silently failing for a while without any notice because of 0 exit status See https://github.com/k8gb-io/k8gb/pull/615#issuecomment-918000074 Signed-off-by: Yury Tsarev --- pkg/command/lint/command.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/command/lint/command.go b/pkg/command/lint/command.go index f52737746..94bb4a7e9 100644 --- a/pkg/command/lint/command.go +++ b/pkg/command/lint/command.go @@ -95,8 +95,7 @@ func Command() *cobra.Command { } } if !atLeastOneObjectFound { - fmt.Fprintln(os.Stderr, "Warning: no valid objects found.") - return nil + return errors.New("no valid objects found") } result, err := run.Run(lintCtxs, checkRegistry, enabledChecks) if err != nil { From 56d3f90f089d8023085612441d108849aebb788f Mon Sep 17 00:00:00 2001 From: Jirka Kremser Date: Tue, 14 Dec 2021 20:13:10 +0000 Subject: [PATCH 2/3] Add fail-if-no-objects-found switch Signed-off-by: Jirka Kremser --- pkg/command/lint/command.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pkg/command/lint/command.go b/pkg/command/lint/command.go index 94bb4a7e9..dec9d04ba 100644 --- a/pkg/command/lint/command.go +++ b/pkg/command/lint/command.go @@ -44,6 +44,7 @@ var ( // Command is the command for the lint command. func Command() *cobra.Command { var configPath string + var failIfNoObjects bool var verbose bool format := flagutil.NewEnumFlag("Output format", formatters.GetEnabledFormatters(), common.PlainFormat) @@ -95,7 +96,12 @@ func Command() *cobra.Command { } } if !atLeastOneObjectFound { - return errors.New("no valid objects found") + msg := "no valid objects found" + if failIfNoObjects { + return errors.New(msg) + } + fmt.Fprintf(os.Stderr, "Warning: %s.\n", msg) + return nil } result, err := run.Run(lintCtxs, checkRegistry, enabledChecks) if err != nil { @@ -119,6 +125,7 @@ func Command() *cobra.Command { } c.Flags().StringVar(&configPath, "config", "", "Path to config file") + c.Flags().BoolVarP(&failIfNoObjects, "fail-if-no-objects-found", "", false, "Return non-zero exit code if no valid objects are found or failed to parse") c.Flags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose logging") c.Flags().Var(format, "format", format.Usage()) From b790a6cb4687ed30979ac38c8afecec36c3326a7 Mon Sep 17 00:00:00 2001 From: Jirka Kremser Date: Tue, 14 Dec 2021 20:54:45 +0000 Subject: [PATCH 3/3] Add testcase for 'fail-if-no-objects-found' switch Signed-off-by: Jirka Kremser --- e2etests/sanity_test.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/e2etests/sanity_test.go b/e2etests/sanity_test.go index c7caebf7f..20e48fc69 100644 --- a/e2etests/sanity_test.go +++ b/e2etests/sanity_test.go @@ -1,13 +1,16 @@ +//go:build e2e // +build e2e package e2etests import ( + "fmt" "io/ioutil" "os" "os/exec" "path/filepath" "regexp" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -49,3 +52,29 @@ func TestKubeLinterWithBuiltInChecksDoesntCrashOnHelmChartsRepo(t *testing.T) { assert.Equal(t, 1, exitErr.ExitCode(), "unexpected exit code: %d; output from kube-linter: %v", exitErr.ExitCode(), outAsStr) assert.True(t, expectedOutRegex.MatchString(outAsStr), "unexpected output: %s", outAsStr) } + +func TestKubeLinterExitsWithNonZeroCodeOnEmptyDir(t *testing.T) { + kubeLinterBin := os.Getenv(kubeLinterBinEnv) + + tmpDir, err := ioutil.TempDir("", "") + require.NoError(t, err) + defer func() { + require.NoError(t, os.RemoveAll(tmpDir)) + }() + kubeLinterOut, err := exec.Command(kubeLinterBin, "lint", tmpDir, "--fail-if-no-objects-found").CombinedOutput() + + // error is expected + require.Error(t, err) + exitErr, ok := err.(*exec.ExitError) + require.True(t, ok) + outAsStr := string(kubeLinterOut) + assert.Equal(t, 1, exitErr.ExitCode(), "unexpected exit code: %d; output from kube-linter: %v", exitErr.ExitCode(), outAsStr) + msg := "no valid objects found" + assert.True(t, strings.Contains(outAsStr, fmt.Sprintf("Error: %s", msg)), "unexpected output, it should contain: %s", outAsStr) + + // without the switch only warning is printed to stderr + kubeLinterOut, err = exec.Command(kubeLinterBin, "lint", tmpDir).CombinedOutput() + require.NoError(t, err) + outAsStr = string(kubeLinterOut) + assert.True(t, strings.Contains(outAsStr, fmt.Sprintf("Warning: %s", msg)), "unexpected output, it should contain: %s", outAsStr) +}