From 2786a84a4c8670011fa98b70ed97ab5ea8e624e7 Mon Sep 17 00:00:00 2001 From: Yann Hamon Date: Sat, 30 May 2020 15:49:02 +0200 Subject: [PATCH] add -dir parameter --- Makefile | 2 +- bin/.gitignore | 1 + main.go | 66 ++++++++++++++++++++++++++++--------------- pkg/fsutils/main.go | 32 +++++++++++++++++++++ pkg/validator/main.go | 13 +++++---- 5 files changed, 84 insertions(+), 30 deletions(-) create mode 100644 bin/.gitignore create mode 100644 pkg/fsutils/main.go diff --git a/Makefile b/Makefile index a938083..e797614 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ #!/usr/bin/make -f all: - go build + go build -o bin/kubeconform diff --git a/bin/.gitignore b/bin/.gitignore new file mode 100644 index 0000000..0533ef3 --- /dev/null +++ b/bin/.gitignore @@ -0,0 +1 @@ +kubeconform diff --git a/main.go b/main.go index 000b30d..fa0d289 100644 --- a/main.go +++ b/main.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/yannh/kubeconform/pkg/cache" + "github.com/yannh/kubeconform/pkg/fsutils" "github.com/yannh/kubeconform/pkg/registry" "github.com/yannh/kubeconform/pkg/resource" "github.com/yannh/kubeconform/pkg/validator" @@ -72,9 +73,10 @@ func (i *arrayFiles) Set(value string) error { func realMain() int { - var files arrayFiles + var files, dirs arrayFiles var skipKinds, k8sVersion string flag.Var(&files, "file", "file to validate (can be specified multiple times)") + flag.Var(&dirs, "dir", "directory to validate (can be specified multiple times)") flag.StringVar(&k8sVersion, "k8sversion", "1.18.0", "version of Kubernetes to test against") flag.StringVar(&skipKinds, "skipKinds", "", "comma-separated list of kinds to ignore") flag.Parse() @@ -89,36 +91,54 @@ func realMain() int { return false } - for _, filename := range files { - f, err := os.Open(filename) - if err != nil { - log.Fatalf("failed opening %s\n", filename) - return 1 - } - defer f.Close() + fileBatches := make(chan []string) - r := registry.NewKubernetesRegistry(false) - res := validateFile(f, []*registry.KubernetesRegistry{r}, k8sVersion, filter) - for _, resourceValidation := range res { - if resourceValidation.skipped { - log.Printf("skipping resource\n") + go func() { + for _, dir := range dirs { + if err := fsutils.FindYamlInDir(dir, fileBatches, 10); err != nil { + log.Printf("failed processing folder %s: %s", dir, err) + } + } + + for _, filename := range files { + fileBatches <- []string{filename} + } + + close(fileBatches) + }() + + r := registry.NewKubernetesRegistry(false) + + for fileBatch := range fileBatches { + for _, filename := range fileBatch { + f, err := os.Open(filename) + if err != nil { + log.Printf("failed opening %s\n", filename) 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) + res := validateFile(f, []*registry.KubernetesRegistry{r}, k8sVersion, filter) + f.Close() + for _, resourceValidation := range res { + if resourceValidation.skipped { + log.Printf("skipping resource\n") + continue } - continue - } - if resourceValidation.err == nil && !resourceValidation.skipped{ - log.Printf("file %s is valid\n", filename) + 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 in file %s: %s\n", filename, resourceValidation.err) + } + continue + } + + if resourceValidation.err == nil && !resourceValidation.skipped{ + log.Printf("file %s is valid\n", filename) + } } } - } return 0 diff --git a/pkg/fsutils/main.go b/pkg/fsutils/main.go new file mode 100644 index 0000000..8af08c0 --- /dev/null +++ b/pkg/fsutils/main.go @@ -0,0 +1,32 @@ +package fsutils + +import ( + "os" + "path/filepath" + "strings" +) + +func FindYamlInDir(dir string, fileBatches chan<- []string, batchSize int) error { + files := []string{} + + err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if !info.IsDir() && (strings.HasSuffix(info.Name(), ".yaml") || strings.HasSuffix(info.Name(), ".yml")) { + files = append(files, path) + if len(files) > batchSize { + fileBatches <- files + files = nil + } + } + return nil + }) + + if len(files) > 0 { + fileBatches <- files + } + + return err +} \ No newline at end of file diff --git a/pkg/validator/main.go b/pkg/validator/main.go index 6a604a4..c506f8f 100644 --- a/pkg/validator/main.go +++ b/pkg/validator/main.go @@ -18,12 +18,13 @@ func (f ValidFormat) IsFormat(input interface{}) bool { return true } -func init () { - gojsonschema.FormatCheckers.Add("int64", ValidFormat{}) - gojsonschema.FormatCheckers.Add("byte", ValidFormat{}) - gojsonschema.FormatCheckers.Add("int32", ValidFormat{}) - gojsonschema.FormatCheckers.Add("int-or-string", ValidFormat{}) -} +// From kubeval - let's see if absolutely necessary +// func init () { +// gojsonschema.FormatCheckers.Add("int64", ValidFormat{}) +// gojsonschema.FormatCheckers.Add("byte", ValidFormat{}) +// gojsonschema.FormatCheckers.Add("int32", ValidFormat{}) +// gojsonschema.FormatCheckers.Add("int-or-string", ValidFormat{}) +// } func Validate(rawResource []byte, rawSchema []byte) error { schemaLoader := gojsonschema.NewBytesLoader(rawSchema)