cache Schema unmarshalling, cache schema download failures (WIP)

This commit is contained in:
Yann Hamon 2020-05-30 21:40:54 +02:00
parent 87f1a0531e
commit 30a6fe69b1
4 changed files with 22 additions and 25 deletions

19
main.go
View file

@ -3,6 +3,7 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/xeipuuv/gojsonschema"
"github.com/yannh/kubeconform/pkg/output" "github.com/yannh/kubeconform/pkg/output"
"io" "io"
"io/ioutil" "io/ioutil"
@ -40,7 +41,7 @@ func validateFile(f io.Reader, regs []registry.Registry, k8sVersion string, skip
return []validationResult{{err: nil, skipped: true}} return []validationResult{{err: nil, skipped: true}}
} }
var schema []byte var schema *gojsonschema.Schema
for _, reg := range regs { for _, reg := range regs {
downloadSchema := cache.WithCache(reg.DownloadSchema) downloadSchema := cache.WithCache(reg.DownloadSchema)
schema, err = downloadSchema(sig.Kind, sig.Version, k8sVersion) schema, err = downloadSchema(sig.Kind, sig.Version, k8sVersion)
@ -70,8 +71,6 @@ func (i *arrayFiles) Set(value string) error {
return nil return nil
} }
func realMain() int { func realMain() int {
var files, dirs, schemas arrayFiles var files, dirs, schemas arrayFiles
var skipKinds, k8sVersion, outputFormat string var skipKinds, k8sVersion, outputFormat string
@ -98,14 +97,14 @@ func realMain() int {
log.Fatalf("-output must be text or json") log.Fatalf("-output must be text or json")
} }
splitKinds := strings.Split(skipKinds, ",")
kinds := map[string]bool {}
for _, kind := range splitKinds {
kinds[kind] = true
}
filter := func(signature resource.Signature) bool { filter := func(signature resource.Signature) bool {
kinds := strings.Split(skipKinds, ",") isSkipKind, ok := kinds[signature.Kind]
for _, kind := range kinds { return ok && isSkipKind
if signature.Kind == kind {
return true
}
}
return false
} }
registries := []registry.Registry{} registries := []registry.Registry{}

14
pkg/cache/main.go vendored
View file

@ -2,18 +2,19 @@ package cache
import ( import (
"fmt" "fmt"
"github.com/xeipuuv/gojsonschema"
"sync" "sync"
) )
var mu sync.Mutex var mu sync.Mutex
var schemas map[string][]byte var schemas map[string]*gojsonschema.Schema
func init () { func init () {
schemas = map[string][]byte {} schemas = map[string]*gojsonschema.Schema{}
} }
func WithCache(downloadSchema func(string, string, string) ([]byte, error)) (func (string, string, string) ([]byte, error)) { func WithCache(downloadSchema func(string, string, string) (*gojsonschema.Schema, error)) (func (string, string, string) (*gojsonschema.Schema, error)) {
return func(resourceKind, resourceAPIVersion, k8sVersion string) ([]byte, error) { return func(resourceKind, resourceAPIVersion, k8sVersion string) (*gojsonschema.Schema, error) {
cacheKey := fmt.Sprintf("%s-%s-%s", resourceKind, resourceAPIVersion, k8sVersion) cacheKey := fmt.Sprintf("%s-%s-%s", resourceKind, resourceAPIVersion, k8sVersion)
mu.Lock() mu.Lock()
cachedSchema, ok := schemas[cacheKey]; cachedSchema, ok := schemas[cacheKey];
@ -23,14 +24,11 @@ func WithCache(downloadSchema func(string, string, string) ([]byte, error)) (fun
} }
schema, err := downloadSchema(resourceKind, resourceAPIVersion, k8sVersion) schema, err := downloadSchema(resourceKind, resourceAPIVersion, k8sVersion)
if err != nil {
return schema, err
}
mu.Lock() mu.Lock()
schemas[cacheKey] = schema schemas[cacheKey] = schema
mu.Unlock() mu.Unlock()
return schema, nil return schema, err
} }
} }

View file

@ -1,9 +1,11 @@
package registry package registry
import "github.com/xeipuuv/gojsonschema"
type Manifest struct { type Manifest struct {
Kind, Version string Kind, Version string
} }
type Registry interface { type Registry interface {
DownloadSchema(resourceKind, resourceAPIVersion, k8sVersion string) ([]byte, error) DownloadSchema(resourceKind, resourceAPIVersion, k8sVersion string) (*gojsonschema.Schema, error)
} }

View file

@ -26,15 +26,13 @@ func (f ValidFormat) IsFormat(input interface{}) bool {
// gojsonschema.FormatCheckers.Add("int-or-string", ValidFormat{}) // gojsonschema.FormatCheckers.Add("int-or-string", ValidFormat{})
// } // }
func Validate(rawResource []byte, rawSchema []byte) error { func Validate(rawResource []byte, schema *gojsonschema.Schema) error {
schemaLoader := gojsonschema.NewBytesLoader(rawSchema) if schema == nil {
schema, err := gojsonschema.NewSchema(schemaLoader) return nil
if err != nil {
return err
} }
var resource map[string]interface{} var resource map[string]interface{}
if err = yaml.Unmarshal(rawResource, &resource); err != nil { if err := yaml.Unmarshal(rawResource, &resource); err != nil {
return fmt.Errorf("error unmarshalling resource: %s", err) return fmt.Errorf("error unmarshalling resource: %s", err)
} }
resourceLoader := gojsonschema.NewGoLoader(resource) resourceLoader := gojsonschema.NewGoLoader(resource)