From 21d0ee5e38013a79d1f0c93a61ee4b45f690c92f Mon Sep 17 00:00:00 2001 From: B-Souty Date: Thu, 3 Sep 2020 15:04:39 +0200 Subject: [PATCH] Add option to error on failed validation --- docs/index.md | 1 + kubeval/config.go | 5 +++++ kubeval/output.go | 17 ++++++++++++----- main.go | 12 ++++++------ 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/docs/index.md b/docs/index.md index 4e4001f..92a71bc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -146,6 +146,7 @@ Usage: Flags: -d, --directories strings A comma-separated list of directories to recursively search for YAML documents + --error-on-validation-failure Log an error if resource fails validation when outputting to stdout --exit-on-error Immediately stop execution when the first error is encountered -f, --filename string filename to be displayed when testing manifests read from stdin (default "stdin") --force-color Force colored output even if stdout is not a TTY diff --git a/kubeval/config.go b/kubeval/config.go index a9240a8..68b448d 100644 --- a/kubeval/config.go +++ b/kubeval/config.go @@ -45,6 +45,10 @@ type Config struct { // for resource definitions without an available schema IgnoreMissingSchemas bool + // ErrorOnValidationFailure tells kubeval whether to produce an error instead + // of a warning when a resource fails to validate when using STDOUT + ErrorOnValidationFailure bool + // ExitOnError tells kubeval whether to halt processing upon the // first error encountered or to continue, aggregating all errors ExitOnError bool @@ -84,6 +88,7 @@ func NewDefaultConfig() *Config { // AddKubevalFlags adds the default flags for kubeval to cmd func AddKubevalFlags(cmd *cobra.Command, config *Config) *cobra.Command { cmd.Flags().StringVarP(&config.DefaultNamespace, "default-namespace", "n", "default", "Namespace to assume in resources if no namespace is set in metadata:namespace") + cmd.Flags().BoolVar(&config.ErrorOnValidationFailure, "error-on-validation-failure", false, "Log an error if resource fails validation when outputting to stdout") cmd.Flags().BoolVar(&config.ExitOnError, "exit-on-error", false, "Immediately stop execution when the first error is encountered") cmd.Flags().BoolVar(&config.IgnoreMissingSchemas, "ignore-missing-schemas", false, "Skip validation for resource definitions without a schema") cmd.Flags().BoolVar(&config.OpenShift, "openshift", false, "Use OpenShift schemas instead of upstream Kubernetes") diff --git a/kubeval/output.go b/kubeval/output.go index 911b03e..3a28927 100644 --- a/kubeval/output.go +++ b/kubeval/output.go @@ -36,31 +36,38 @@ func validOutputs() []string { } } -func GetOutputManager(outFmt string) outputManager { +func GetOutputManager(outFmt string, strictValidation bool) outputManager { switch outFmt { case outputSTD: - return newSTDOutputManager() + return newSTDOutputManager(strictValidation) case outputJSON: return newDefaultJSONOutputManager() case outputTAP: return newDefaultTAPOutputManager() default: - return newSTDOutputManager() + return newSTDOutputManager(strictValidation) } } // STDOutputManager reports `kubeval` results to stdout. type STDOutputManager struct { + strictValidation bool } // newSTDOutputManager instantiates a new instance of STDOutputManager. -func newSTDOutputManager() *STDOutputManager { - return &STDOutputManager{} +func newSTDOutputManager(strictValidation bool) *STDOutputManager { + return &STDOutputManager{ + strictValidation: strictValidation, + } } func (s *STDOutputManager) Put(result ValidationResult) error { if len(result.Errors) > 0 { for _, desc := range result.Errors { + if s.strictValidation { + err := fmt.Errorf("%s contains an invalid %s %s - %s", result.FileName, result.Kind, fmt.Sprintf("(%s)", result.QualifiedName()), desc.String()) + return err + } kLog.Warn(result.FileName, "contains an invalid", result.Kind, fmt.Sprintf("(%s)", result.QualifiedName()), "-", desc.String()) } } else if result.Kind == "" { diff --git a/main.go b/main.go index cd24086..833dfe8 100644 --- a/main.go +++ b/main.go @@ -24,10 +24,10 @@ import ( ) var ( - version = "dev" - commit = "none" - date = "unknown" - directories = []string{} + version = "dev" + commit = "none" + date = "unknown" + directories = []string{} ignoredPathPatterns = []string{} // forceColor tells kubeval to use colored output even if @@ -59,7 +59,7 @@ var RootCmd = &cobra.Command{ success := true windowsStdinIssue := false - outputManager := kubeval.GetOutputManager(config.OutputFormat) + outputManager := kubeval.GetOutputManager(config.OutputFormat, config.ErrorOnValidationFailure) stat, err := os.Stdin.Stat() if err != nil { @@ -242,7 +242,7 @@ func init() { RootCmd.Flags().StringSliceVarP(&directories, "directories", "d", []string{}, "A comma-separated list of directories to recursively search for YAML documents") RootCmd.Flags().StringSliceVarP(&ignoredPathPatterns, "ignored-path-patterns", "i", []string{}, "A comma-separated list of regular expressions specifying paths to ignore") RootCmd.Flags().StringSliceVarP(&ignoredPathPatterns, "ignored-filename-patterns", "", []string{}, "An alias for ignored-path-patterns") - + viper.SetEnvPrefix("KUBEVAL") viper.AutomaticEnv() viper.BindPFlag("schema_location", RootCmd.Flags().Lookup("schema-location"))