From 3c6d3e351c88e8621e70b7ee5b8f811cd37ca0a8 Mon Sep 17 00:00:00 2001 From: Yann Hamon Date: Sat, 30 May 2020 07:02:48 +0200 Subject: [PATCH] skipKinds + better error logging --- go.mod | 1 + go.sum | 33 ++++++++++++++ main.go | 92 ++++++++++++++++++++++++++++++++-------- pkg/registry/registry.go | 4 +- 4 files changed, 110 insertions(+), 20 deletions(-) diff --git a/go.mod b/go.mod index 2676f7c..a720985 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/yannh/kubeconform go 1.14 require ( + github.com/instrumenta/kubeval v0.0.0-20200515185822-7721cbec724c github.com/xeipuuv/gojsonschema v1.2.0 gopkg.in/yaml.v2 v2.3.0 sigs.k8s.io/yaml v1.2.0 diff --git a/go.sum b/go.sum index 99f502b..8f3d7fa 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,50 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357 h1:Rem2+U35z1QtPQc6r+WolF7yXiefXqDKyk+lN2pE164= +github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v0.0.0-20180717150148-3d5d8f294aa0 h1:j30noezaCfvNLcdMYSvHLv81DxYRSt1grlpseG67vhU= +github.com/hashicorp/go-multierror v0.0.0-20180717150148-3d5d8f294aa0/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= +github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/instrumenta/kubeval v0.0.0-20200515185822-7721cbec724c h1:tF3B96upB2wECZMXZxrAMLiVUgT22sNNxhuOhrcg28s= +github.com/instrumenta/kubeval v0.0.0-20200515185822-7721cbec724c/go.mod h1:cD+P/oZrBwOnaIHXrqvKPuN353KPxGomnsXSXf8pFJs= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.1.0 h1:v2XXALHHh6zHfYTJ+cSkwtyffnaOyR1MXaA91mTrb8o= +github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mitchellh/mapstructure v0.0.0-20180715050151-f15292f7a699/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/pelletier/go-toml v0.0.0-20180724185102-c2dbbc24a979/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spf13/afero v1.1.1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/cobra v0.0.0-20180820174524-ff0d02e85550 h1:LB9SHuuXO8gnsHtexOQSpsJrrAHYA35lvHUaE74kznU= +github.com/spf13/cobra v0.0.0-20180820174524-ff0d02e85550/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/jwalterweatherman v0.0.0-20180814060501-14d3d4c51834/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20180821114517-d929dcbb1086 h1:iU+nPfqRqK8ShQqnpZLv8cZ9oklo6NFUcmX1JT5Rudg= +github.com/spf13/pflag v0.0.0-20180821114517-d929dcbb1086/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.1.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v0.0.0-20180816142147-da425ebb7609/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +golang.org/x/sys v0.0.0-20180821044426-4ea2f632f6e9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.0.0-20180810153555-6e3c4e7365dd/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/main.go b/main.go index 875da7e..67950f3 100644 --- a/main.go +++ b/main.go @@ -1,11 +1,13 @@ package main import ( + "flag" "fmt" "io" "io/ioutil" "log" "os" + "strings" "github.com/yannh/kubeconform/pkg/cache" "github.com/yannh/kubeconform/pkg/registry" @@ -13,17 +15,27 @@ import ( "github.com/yannh/kubeconform/pkg/validator" ) -func validateFile(f io.Reader, regs []*registry.KubernetesRegistry, k8sVersion string) error { +type validationResult struct { + err error + skipped bool +} + +// filter returns true if the file should be skipped +// Returning an array, this Reader might container multiple resources +func validateFile(f io.Reader, regs []*registry.KubernetesRegistry, k8sVersion string, skip func(signature resource.Signature)bool) []validationResult { rawResource, err := ioutil.ReadAll(f) if err != nil { - return fmt.Errorf("failed reading file: %s", err) + return []validationResult{{err: fmt.Errorf("failed reading file: %s", err)}} } sig, err := resource.SignatureFromBytes(rawResource) if err != nil { - return fmt.Errorf("error while parsing: %s", err) + return []validationResult{{err: fmt.Errorf("error while parsing: %s", err)}} } + if skip(sig) { + return []validationResult{{err: nil, skipped: true}} + } var schema []byte for _, reg := range regs { @@ -34,38 +46,82 @@ func validateFile(f io.Reader, regs []*registry.KubernetesRegistry, k8sVersion s } } if err != nil { - return fmt.Errorf("failed downloading schema for resource") + return []validationResult{{err: fmt.Errorf("error while downloading schema for resource: %s", err)}} } if err = validator.Validate(rawResource, schema); err != nil { - return err + return []validationResult{{err: err}} } + return []validationResult{{err: nil}} +} + + + +type arrayFiles []string + +func (i *arrayFiles) String() string { + return "my string representation" +} + +func (i *arrayFiles) Set(value string) error { + *i = append(*i, value) return nil } + + func realMain() int { const k8sVersion = "1.18.0" - filename := "fixtures/valid_1.yaml" - f, err := os.Open(filename) - if err != nil { - log.Fatalf("failed opening %s", filename) - return 1 + var files arrayFiles + var skipKinds string + flag.Var(&files, "file", "file to validate (can be specified multiple times)") + flag.StringVar(&skipKinds, "skipKinds", "", "comma-separated list of kinds to ignore") + flag.Parse() + + filter := func(signature resource.Signature) bool { + kinds := strings.Split(skipKinds, ",") + for _, kind := range kinds { + if signature.Kind == kind { + return true + } + } + return false } - defer f.Close() - r := registry.NewKubernetesRegistry() - if err = validateFile(f, []*registry.KubernetesRegistry{r}, k8sVersion); err != nil { - if _, ok := err.(validator.InvalidResourceError); ok { - log.Printf("invalid resource: %s", err) + for _, filename := range files { + f, err := os.Open(filename) + if err != nil { + log.Fatalf("failed opening %s\n", filename) return 1 } - log.Printf("failed validating resource: %s", err) - return 1 + defer f.Close() + + r := registry.NewKubernetesRegistry(false) + res := validateFile(f, []*registry.KubernetesRegistry{r}, k8sVersion, filter) + for _, resourceValidation := range res { + if resourceValidation.skipped { + log.Printf("skipping resource\n") + continue + } + + if resourceValidation.err != nil { + if _, ok := resourceValidation.err.(validator.InvalidResourceError); ok { + log.Printf("invalid resource: %s\n", resourceValidation.err) + } else { + log.Printf("failed validating resource: %s\n", resourceValidation.err) + } + continue + } + + if resourceValidation.err == nil && !resourceValidation.skipped{ + log.Printf("file %s is valid\n", filename) + } + } + } - log.Printf("resource is valid: %s", filename) return 0 } diff --git a/pkg/registry/registry.go b/pkg/registry/registry.go index 27ca339..4476c67 100644 --- a/pkg/registry/registry.go +++ b/pkg/registry/registry.go @@ -20,10 +20,10 @@ type KubernetesRegistry struct { strict bool } -func NewKubernetesRegistry() *KubernetesRegistry { +func NewKubernetesRegistry(strict bool) *KubernetesRegistry { return &KubernetesRegistry{ baseURL: "https://kubernetesjsonschema.dev", - strict: false, + strict: strict, } }