better errors

This commit is contained in:
Yann Hamon 2020-05-30 05:34:21 +02:00
parent 96e35cb926
commit 79c9197f38
5 changed files with 59 additions and 30 deletions

1
go.mod
View file

@ -5,4 +5,5 @@ go 1.14
require ( require (
github.com/xeipuuv/gojsonschema v1.2.0 github.com/xeipuuv/gojsonschema v1.2.0
gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v2 v2.3.0
sigs.k8s.io/yaml v1.2.0
) )

4
go.sum
View file

@ -1,4 +1,5 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@ -9,5 +10,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=

63
main.go
View file

@ -1,6 +1,8 @@
package main package main
import ( import (
"fmt"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
@ -10,6 +12,35 @@ import (
"github.com/yannh/kubeconform/pkg/validator" "github.com/yannh/kubeconform/pkg/validator"
) )
func validateFile(f io.Reader, regs []*registry.KubernetesRegistry, k8sVersion string) error {
rawResource, err := ioutil.ReadAll(f)
if err != nil {
return fmt.Errorf("failed reading file: %s", err)
}
sig, err := resource.SignatureFromBytes(rawResource)
if err != nil {
return fmt.Errorf("error while parsing: %s", err)
}
var schema []byte
for _, reg := range regs {
schema, err = reg.DownloadSchema(sig.Kind, sig.Version, k8sVersion)
if err == nil {
break
}
}
if err != nil {
return fmt.Errorf("failed downloading schema for resource")
}
if err = validator.Validate(rawResource, schema); err != nil {
return err
}
return nil
}
func realMain() int { func realMain() int {
const k8sVersion = "1.18.0" const k8sVersion = "1.18.0"
filename := "fixtures/valid_1.yaml" filename := "fixtures/valid_1.yaml"
@ -21,35 +52,17 @@ func realMain() int {
} }
defer f.Close() defer f.Close()
rawResource, err := ioutil.ReadAll(f)
if err != nil {
log.Printf("failed reading file %s", filename)
return 1
}
sig, err := resource.SignatureFromBytes(rawResource)
if err != nil {
log.Printf("failed parsing %s", filename)
return 1
}
r := registry.NewKubernetesRegistry() r := registry.NewKubernetesRegistry()
schema, err := r.DownloadSchema(sig.Kind, sig.Version, k8sVersion) if err = validateFile(f, []*registry.KubernetesRegistry{r}, k8sVersion); err != nil {
if _, ok := err.(validator.InvalidResourceError); ok {
if err != nil { log.Printf("invalid resource: %s", err)
log.Printf("error downloading Schema: %s", err) return 1
}
log.Printf("failed validating resource: %s", err)
return 1 return 1
} }
err = validator.Validate(rawResource, schema) log.Printf("resource is valid: %s", filename)
if err != nil {
log.Printf("failed validating: %s", err)
return 1
}
log.Printf("resource is valid!: %s", schema)
return 0 return 0
} }

View file

@ -1,7 +1,7 @@
package resource package resource
import ( import (
yaml "gopkg.in/yaml.v2" "sigs.k8s.io/yaml"
) )
type Signature struct { type Signature struct {

View file

@ -3,8 +3,14 @@ package validator
import ( import (
"fmt" "fmt"
"github.com/xeipuuv/gojsonschema" "github.com/xeipuuv/gojsonschema"
"sigs.k8s.io/yaml"
) )
type InvalidResourceError struct { err string }
func (r InvalidResourceError) Error() string{
return r.err
}
// ValidFormat is a type for quickly forcing // ValidFormat is a type for quickly forcing
// new formats on the gojsonschema loader // new formats on the gojsonschema loader
type ValidFormat struct{} type ValidFormat struct{}
@ -19,22 +25,27 @@ func init () {
gojsonschema.FormatCheckers.Add("int-or-string", ValidFormat{}) gojsonschema.FormatCheckers.Add("int-or-string", ValidFormat{})
} }
func Validate(resource interface{}, rawSchema []byte) error { func Validate(rawResource []byte, rawSchema []byte) error {
schemaLoader := gojsonschema.NewBytesLoader(rawSchema) schemaLoader := gojsonschema.NewBytesLoader(rawSchema)
schema, err := gojsonschema.NewSchema(schemaLoader) schema, err := gojsonschema.NewSchema(schemaLoader)
if err != nil { if err != nil {
return err return err
} }
documentLoader := gojsonschema.NewGoLoader(resource) var resource map[string]interface{}
results, err := schema.Validate(documentLoader) if err = yaml.Unmarshal(rawResource, &resource); err != nil {
return fmt.Errorf("error unmarshalling resource: %s", err)
}
resourceLoader := gojsonschema.NewGoLoader(resource)
results, err := schema.Validate(resourceLoader)
if err != nil { if err != nil {
// This error can only happen if the Object to validate is poorly formed. There's no hope of saving this one // This error can only happen if the Object to validate is poorly formed. There's no hope of saving this one
return fmt.Errorf("problem validating schema. Check JSON formatting: %s", err) return fmt.Errorf("problem validating schema. Check JSON formatting: %s", err)
} }
if !results.Valid() { if !results.Valid() {
return fmt.Errorf("resource does not conform to schema") return InvalidResourceError{err: fmt.Sprintf("resource does not conform to schema: %+v", results) }
} }
return nil return nil