diff --git a/acceptance.bats b/acceptance.bats index 99548b5..dccc9ae 100755 --- a/acceptance.bats +++ b/acceptance.bats @@ -15,13 +15,13 @@ @test "Pass when parsing a Kubernetes file with string and integer quantities" { run bin/kubeconform -verbose fixtures/quantity.yaml [ "$status" -eq 0 ] - [ "$output" = "fixtures/quantity.yaml - LimitRange is valid" ] + [ "$output" = "fixtures/quantity.yaml - LimitRange mem-limit-range is valid" ] } @test "Pass when parsing a valid Kubernetes config file with null arrays" { run bin/kubeconform -verbose fixtures/null_string.yaml [ "$status" -eq 0 ] - [ "$output" = "fixtures/null_string.yaml - Service is valid" ] + [ "$output" = "fixtures/null_string.yaml - Service frontend is valid" ] } @test "Pass when parsing a multi-document config file" { @@ -43,7 +43,7 @@ @test "Return relevant error for non-existent file" { run bin/kubeconform fixtures/not-here [ "$status" -eq 1 ] - [ "$output" = "fixtures/not-here - failed validation: open fixtures/not-here: no such file or directory" ] + [ "$output" = "fixtures/not-here - failed validation: open fixtures/not-here: no such file or directory" ] } @test "Fail when parsing a config with additional properties and strict set" { diff --git a/cmd/kubeconform/main.go b/cmd/kubeconform/main.go index 82f0fb8..2839ba9 100644 --- a/cmd/kubeconform/main.go +++ b/cmd/kubeconform/main.go @@ -20,9 +20,9 @@ import ( ) type validationResult struct { - filename, kind, version string - err error - skipped bool + filename, kind, version, Name string + err error + skipped bool } func resourcesFromReader(r io.Reader) ([][]byte, error) { @@ -70,7 +70,7 @@ func ValidateStream(r io.Reader, regs []registry.Registry, k8sVersion string, c for _, rawResource := range rawResources { var sig resource.Signature if sig, err = resource.SignatureFromBytes(rawResource); err != nil { - validationResults = append(validationResults, validationResult{kind: sig.Kind, version: sig.Version, err: fmt.Errorf("error while parsing: %s", err)}) + validationResults = append(validationResults, validationResult{kind: sig.Kind, version: sig.Version, Name: sig.Name, err: fmt.Errorf("error while parsing: %s", err)}) continue } @@ -79,7 +79,7 @@ func ValidateStream(r io.Reader, regs []registry.Registry, k8sVersion string, c } if skip(sig) { - validationResults = append(validationResults, validationResult{kind: sig.Kind, version: sig.Version, err: nil, skipped: true}) + validationResults = append(validationResults, validationResult{kind: sig.Kind, version: sig.Version, Name: sig.Name, err: nil, skipped: true}) continue } @@ -95,7 +95,7 @@ func ValidateStream(r io.Reader, regs []registry.Registry, k8sVersion string, c if !ok { schema, err = downloadSchema(regs, sig.Kind, sig.Version, k8sVersion) if err != nil { - validationResults = append(validationResults, validationResult{kind: sig.Kind, version: sig.Version, err: err, skipped: false}) + validationResults = append(validationResults, validationResult{kind: sig.Kind, version: sig.Version, Name: sig.Name, err: err, skipped: false}) continue } @@ -106,14 +106,14 @@ func ValidateStream(r io.Reader, regs []registry.Registry, k8sVersion string, c if schema == nil { if ignoreMissingSchemas { - validationResults = append(validationResults, validationResult{kind: sig.Kind, version: sig.Version, err: nil, skipped: true}) + validationResults = append(validationResults, validationResult{kind: sig.Kind, version: sig.Version, Name: sig.Name, err: nil, skipped: true}) } else { - validationResults = append(validationResults, validationResult{kind: sig.Kind, version: sig.Version, err: fmt.Errorf("could not find schema for %s", sig.Kind), skipped: false}) + validationResults = append(validationResults, validationResult{kind: sig.Kind, version: sig.Version, Name: sig.Name, err: fmt.Errorf("could not find schema for %s", sig.Kind), skipped: false}) } } err = validator.Validate(rawResource, schema) - validationResults = append(validationResults, validationResult{kind: sig.Kind, version: sig.Version, err: err}) + validationResults = append(validationResults, validationResult{kind: sig.Kind, version: sig.Version, Name: sig.Name, err: err}) } return validationResults @@ -162,7 +162,7 @@ func processResults(o output.Output, validationResults chan []validationResult, success = false } - if err := o.Write(result.filename, result.kind, result.version, result.err, result.skipped); err != nil { + if err := o.Write(result.filename, result.kind, result.Name, result.version, result.err, result.skipped); err != nil { fmt.Fprint(os.Stderr, "failed writing log\n") } } diff --git a/pkg/output/json.go b/pkg/output/json.go index d5abe86..0612219 100644 --- a/pkg/output/json.go +++ b/pkg/output/json.go @@ -9,6 +9,7 @@ import ( type result struct { Filename string `json:"filename"` Kind string `json:"kind"` + Name string `json:"name"` Version string `json:"version"` Status string `json:"status"` Msg string `json:"msg"` @@ -37,7 +38,7 @@ func JSON(w io.Writer, withSummary bool, verbose bool) Output { } // JSON.Write will only write when JSON.Flush has been called -func (o *jsono) Write(filename, kind, version string, err error, skipped bool) error { +func (o *jsono) Write(filename, kind, name, version string, err error, skipped bool) error { msg, st := "", "" s := status(err, skipped) @@ -60,7 +61,7 @@ func (o *jsono) Write(filename, kind, version string, err error, skipped bool) e } if o.verbose || (s != VALID && s != SKIPPED) { - o.results = append(o.results, result{Filename: filename, Kind: kind, Version: version, Status: st, Msg: msg}) + o.results = append(o.results, result{Filename: filename, Kind: kind, Name: name, Version: version, Status: st, Msg: msg}) } return nil diff --git a/pkg/output/json_test.go b/pkg/output/json_test.go index aaf02bb..b0f0cf2 100644 --- a/pkg/output/json_test.go +++ b/pkg/output/json_test.go @@ -7,9 +7,9 @@ import ( func TestJSONWrite(t *testing.T) { type result struct { - fileName, kind, version string - err error - skipped bool + fileName, kind, name, version string + err error + skipped bool } for _, testCase := range []struct { @@ -28,6 +28,7 @@ func TestJSONWrite(t *testing.T) { { "deployment.yml", "Deployment", + "my-app", "apps/v1", nil, false, @@ -46,6 +47,7 @@ func TestJSONWrite(t *testing.T) { { "deployment.yml", "Deployment", + "my-app", "apps/v1", nil, false, @@ -70,6 +72,7 @@ func TestJSONWrite(t *testing.T) { { "deployment.yml", "Deployment", + "my-app", "apps/v1", nil, false, @@ -80,6 +83,7 @@ func TestJSONWrite(t *testing.T) { { "filename": "deployment.yml", "kind": "Deployment", + "name": "my-app", "version": "apps/v1", "status": "VALID", "msg": "" @@ -99,7 +103,7 @@ func TestJSONWrite(t *testing.T) { o := JSON(w, testCase.withSummary, testCase.verbose) for _, res := range testCase.res { - o.Write(res.fileName, res.kind, res.version, res.err, res.skipped) + o.Write(res.fileName, res.kind, res.name, res.version, res.err, res.skipped) } o.Flush() diff --git a/pkg/output/output.go b/pkg/output/output.go index d56403e..446395c 100644 --- a/pkg/output/output.go +++ b/pkg/output/output.go @@ -13,7 +13,7 @@ const ( ) type Output interface { - Write(filename, kind, version string, err error, skipped bool) error + Write(filename, kind, name, version string, err error, skipped bool) error Flush() error } diff --git a/pkg/output/text.go b/pkg/output/text.go index a7cd2b5..1fcd9c2 100644 --- a/pkg/output/text.go +++ b/pkg/output/text.go @@ -29,7 +29,7 @@ func Text(w io.Writer, withSummary, verbose bool) Output { } } -func (o *text) Write(filename, kind, version string, reserr error, skipped bool) error { +func (o *text) Write(filename, kind, name, version string, reserr error, skipped bool) error { o.Lock() defer o.Unlock() @@ -39,18 +39,18 @@ func (o *text) Write(filename, kind, version string, reserr error, skipped bool) switch status(reserr, skipped) { case VALID: if o.verbose { - _, err = fmt.Fprintf(o.w, "%s - %s is valid\n", filename, kind) + _, err = fmt.Fprintf(o.w, "%s - %s %s is valid\n", filename, kind, name) } o.nValid++ case INVALID: - _, err = fmt.Fprintf(o.w, "%s - %s is invalid: %s\n", filename, kind, reserr) + _, err = fmt.Fprintf(o.w, "%s - %s %s is invalid: %s\n", filename, kind, name, reserr) o.nInvalid++ case ERROR: - _, err = fmt.Fprintf(o.w, "%s - %s failed validation: %s\n", filename, kind, reserr) + _, err = fmt.Fprintf(o.w, "%s - %s %s failed validation: %s\n", filename, kind, name, reserr) o.nErrors++ case SKIPPED: if o.verbose { - _, err = fmt.Fprintf(o.w, "%s - %s skipped\n", filename, kind) + _, err = fmt.Fprintf(o.w, "%s - %s %s skipped\n", filename, name, kind) } o.nSkipped++ } diff --git a/pkg/output/text_test.go b/pkg/output/text_test.go index 21fc1e7..82628b7 100644 --- a/pkg/output/text_test.go +++ b/pkg/output/text_test.go @@ -7,9 +7,9 @@ import ( func TestTextWrite(t *testing.T) { type result struct { - fileName, kind, version string - err error - skipped bool + fileName, kind, name, version string + err error + skipped bool } for _, testCase := range []struct { @@ -28,6 +28,7 @@ func TestTextWrite(t *testing.T) { { "deployment.yml", "Deployment", + "my-app", "apps/v1", nil, false, @@ -43,6 +44,7 @@ func TestTextWrite(t *testing.T) { { "deployment.yml", "Deployment", + "my-app", "apps/v1", nil, false, @@ -58,12 +60,13 @@ func TestTextWrite(t *testing.T) { { "deployment.yml", "Deployment", + "my-app", "apps/v1", nil, false, }, }, - `deployment.yml - Deployment is valid + `deployment.yml - Deployment my-app is valid Summary: 1 resource found in 1 file - Valid: 1, Invalid: 0, Errors: 0 Skipped: 0 `, }, @@ -72,7 +75,7 @@ Summary: 1 resource found in 1 file - Valid: 1, Invalid: 0, Errors: 0 Skipped: 0 o := Text(w, testCase.withSummary, testCase.verbose) for _, res := range testCase.res { - o.Write(res.fileName, res.kind, res.version, res.err, res.skipped) + o.Write(res.fileName, res.kind, res.name, res.version, res.err, res.skipped) } o.Flush() diff --git a/pkg/resource/signature.go b/pkg/resource/signature.go index d85b7d8..299c733 100644 --- a/pkg/resource/signature.go +++ b/pkg/resource/signature.go @@ -5,7 +5,7 @@ import ( ) type Signature struct { - Kind, Version, Namespace string + Kind, Version, Namespace, Name string } // SignatureFromBytes returns key identifying elements from a []byte representing the resource @@ -14,10 +14,11 @@ func SignatureFromBytes(res []byte) (Signature, error) { APIVersion string `yaml:"apiVersion"` Kind string `yaml:"kind"` Metadata struct { + Name string `yaml:"Name"` Namespace string `yaml:"Namespace"` } `yaml:"Metadata"` }{} err := yaml.Unmarshal(res, &resource) - return Signature{Kind: resource.Kind, Version: resource.APIVersion, Namespace: resource.Metadata.Namespace}, err + return Signature{Kind: resource.Kind, Version: resource.APIVersion, Namespace: resource.Metadata.Namespace, Name: resource.Metadata.Name}, err }