Skip to content

Commit

Permalink
Adds qualified names to output
Browse files Browse the repository at this point in the history
This assists with finding issues in large collections of manifests.
This is especially useful when used in conjunction with kustomize where the manifests are transformed and piped.
  • Loading branch information
dmarkwat committed Apr 1, 2020
1 parent 8d013ec commit d793c7b
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 3 deletions.
25 changes: 25 additions & 0 deletions kubeval/kubeval.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,26 @@ type ValidationResult struct {
APIVersion string
ValidatedAgainstSchema bool
Errors []gojsonschema.ResultError
ResourceName string
ResourceNamespace string
}

// VersionKind returns a string representation of this result's apiVersion and kind
func (v *ValidationResult) VersionKind() string {
return v.APIVersion + "/" + v.Kind
}

// QualifiedName returns a string of the [namespace.]name of the k8s resource
func (v *ValidationResult) QualifiedName() string {
if v.ResourceName == "" {
return "unknown"
} else if v.ResourceNamespace == "" {
return v.ResourceName
} else {
return fmt.Sprintf("%s.%s", v.ResourceNamespace, v.ResourceName)
}
}

func determineSchemaURL(baseURL, kind, apiVersion string, config *Config) string {
// We have both the upstream Kubernetes schemas and the OpenShift schemas available
// the tool can toggle between then using the config.OpenShift boolean flag and here we
Expand Down Expand Up @@ -108,6 +121,18 @@ func validateResource(data []byte, schemaCache map[string]*gojsonschema.Schema,
return result, nil
}

name, err := getStringAt(body, []string{"metadata", "name"})
if err != nil {
return result, fmt.Errorf("%s: %s", result.FileName, err.Error())
}
result.ResourceName = name

namespace, err := getStringAt(body, []string{"metadata", "namespace"})
if err != nil {
result.ResourceNamespace = "default"
}
result.ResourceNamespace = namespace

kind, err := getString(body, "kind")
if err != nil {
return result, fmt.Errorf("%s: %s", result.FileName, err.Error())
Expand Down
6 changes: 3 additions & 3 deletions kubeval/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ func newSTDOutputManager() *STDOutputManager {
func (s *STDOutputManager) Put(result ValidationResult) error {
if len(result.Errors) > 0 {
for _, desc := range result.Errors {
kLog.Warn(result.FileName, "contains an invalid", result.Kind, "-", desc.String())
kLog.Warn(result.FileName, "contains an invalid", result.Kind, "(", result.QualifiedName(), ")", "-", desc.String())
}
} else if result.Kind == "" {
kLog.Success(result.FileName, "contains an empty YAML document")
} else if !result.ValidatedAgainstSchema {
kLog.Warn(result.FileName, "containing a", result.Kind, "was not validated against a schema")
kLog.Warn(result.FileName, "containing a", result.Kind, "(", result.QualifiedName(), ")", "was not validated against a schema")
} else {
kLog.Success(result.FileName, "contains a valid", result.Kind)
kLog.Success(result.FileName, "contains a valid", result.Kind, "(", result.QualifiedName(), ")")
}

return nil
Expand Down
27 changes: 27 additions & 0 deletions kubeval/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,35 @@ import (
"bytes"
"fmt"
"runtime"
"strings"
)

func getStringAt(body map[string]interface{}, path []string) (string, error) {
obj := body
visited := []string{}
var last interface{} = body
for _, key := range path {
visited = append(visited, key)

typed, ok := last.(map[string]interface{})
if !ok {
return "", fmt.Errorf("Expected object at key '%s'", strings.Join(visited, "."))
}
obj = typed

value, found := obj[key]
if !found {
return "", fmt.Errorf("Missing '%s' key", strings.Join(visited, "."))
}
last = value
}
typed, ok := last.(string)
if !ok {
return "", fmt.Errorf("Expected string value for key '%s'", strings.Join(visited, "."))
}
return typed, nil
}

func getString(body map[string]interface{}, key string) (string, error) {
value, found := body[key]
if !found {
Expand Down

0 comments on commit d793c7b

Please sign in to comment.