diff --git a/acceptance.bats b/acceptance.bats index b046d01..6f01335 100755 --- a/acceptance.bats +++ b/acceptance.bats @@ -19,7 +19,7 @@ } @test "Pass when parsing a valid Kubernetes config YAML file with generate name" { - run bin/kubeconform fixtures/generate_name.yaml + run bin/kubeconform -verbose fixtures/generate_name.yaml [ "$status" -eq 0 ] [ "$output" = "fixtures/generate_name.yaml - Job pi-{{ generateName }} is valid" ] } @@ -58,6 +58,12 @@ [ "$output" = "fixtures/not-here - failed validation: open fixtures/not-here: no such file or directory" ] } +@test "Pass when parsing a blank config file" { + run bin/kubeconform -summary fixtures/blank.yaml + [ "$status" -eq 0 ] + [ "$output" = "Summary: 0 resource found in 1 file - Valid: 0, Invalid: 0, Errors: 0 Skipped: 0" ] +} + @test "Fail when parsing a config with additional properties and strict set" { run bin/kubeconform -strict -k8sversion 1.16.0 fixtures/extra_property.yaml [ "$status" -eq 1 ] diff --git a/cmd/kubeconform/main.go b/cmd/kubeconform/main.go index 2839ba9..1dcf969 100644 --- a/cmd/kubeconform/main.go +++ b/cmd/kubeconform/main.go @@ -65,7 +65,12 @@ func ValidateStream(r io.Reader, regs []registry.Registry, k8sVersion string, c return []validationResult{{err: fmt.Errorf("failed reading file: %s", err)}} } + validationResults := []validationResult{} + if len(rawResources) == 0 { + // In case a file has no resources, we want to capture that the file was parsed - and therefore send a message with an empty resource and no error + validationResults = append(validationResults, validationResult{kind: "", version: "", Name: "", err: nil, skipped: false}) + } for _, rawResource := range rawResources { var sig resource.Signature @@ -75,6 +80,7 @@ func ValidateStream(r io.Reader, regs []registry.Registry, k8sVersion string, c } if sig.Kind == "" { + validationResults = append(validationResults, validationResult{kind: "", version: "", Name: "", err: nil, skipped: false}) continue // We skip resoures that don't have a Kind defined } diff --git a/pkg/output/json.go b/pkg/output/json.go index 0612219..84ea906 100644 --- a/pkg/output/json.go +++ b/pkg/output/json.go @@ -41,7 +41,7 @@ func JSON(w io.Writer, withSummary bool, verbose bool) Output { func (o *jsono) Write(filename, kind, name, version string, err error, skipped bool) error { msg, st := "", "" - s := status(err, skipped) + s := status(kind, name, err, skipped) switch s { case VALID: @@ -58,9 +58,10 @@ func (o *jsono) Write(filename, kind, name, version string, err error, skipped b case SKIPPED: st = "SKIPPED" o.nSkipped++ + case EMPTY: } - if o.verbose || (s != VALID && s != SKIPPED) { + if o.verbose || (s != VALID && s != SKIPPED && s != EMPTY ) { o.results = append(o.results, result{Filename: filename, Kind: kind, Name: name, Version: version, Status: st, Msg: msg}) } diff --git a/pkg/output/output.go b/pkg/output/output.go index 446395c..d5c0a4f 100644 --- a/pkg/output/output.go +++ b/pkg/output/output.go @@ -10,6 +10,7 @@ const ( INVALID ERROR SKIPPED + EMPTY ) type Output interface { @@ -17,7 +18,11 @@ type Output interface { Flush() error } -func status(err error, skipped bool) int { +func status(kind, name string, err error, skipped bool) int { + if name == "" && kind == "" && err == nil && skipped == false { + return EMPTY + } + if skipped { return SKIPPED } diff --git a/pkg/output/text.go b/pkg/output/text.go index 25171e8..079b886 100644 --- a/pkg/output/text.go +++ b/pkg/output/text.go @@ -36,7 +36,7 @@ func (o *text) Write(filename, kind, name, version string, reserr error, skipped var err error o.files[filename] = true - switch status(reserr, skipped) { + switch status(kind, name, reserr, skipped) { case VALID: if o.verbose { _, err = fmt.Fprintf(o.w, "%s - %s %s is valid\n", filename, kind, name) @@ -57,6 +57,7 @@ func (o *text) Write(filename, kind, name, version string, reserr error, skipped _, err = fmt.Fprintf(o.w, "%s - %s %s skipped\n", filename, name, kind) } o.nSkipped++ + case EMPTY: } return err