Properly close streams after processing them

This commit is contained in:
Yann Hamon 2020-11-15 10:19:09 +01:00
parent 6f2fe33bc0
commit 22e82c4922

View file

@ -32,18 +32,21 @@ type Result struct {
type Validator interface { type Validator interface {
ValidateResource(res resource.Resource) Result ValidateResource(res resource.Resource) Result
Validate(filename string, r io.Reader) []Result Validate(filename string, r io.ReadCloser) []Result
ValidateWithContext(ctx context.Context, filename string, r io.ReadCloser) []Result
} }
// Opts contains a set of options for the validator.
type Opts struct { type Opts struct {
SkipTLS bool SkipTLS bool // skip TLS validation when downloading from an HTTP Schema Registry
SkipKinds map[string]bool SkipKinds map[string]bool // List of resource Kinds to ignore
RejectKinds map[string]bool RejectKinds map[string]bool // List of resource Kinds to reject
KubernetesVersion string KubernetesVersion string // Kubernetes Version - has to match one in https://github.com/instrumenta/kubernetes-json-schema
Strict bool Strict bool // thros an error if resources contain undocumented fields
IgnoreMissingSchemas bool IgnoreMissingSchemas bool // skip a resource if no schema for that resource can be found
} }
// New returns a new Validator
func New(schemaLocations []string, opts Opts) Validator { func New(schemaLocations []string, opts Opts) Validator {
// Default to kubernetesjsonschema.dev // Default to kubernetesjsonschema.dev
if schemaLocations == nil || len(schemaLocations) == 0 { if schemaLocations == nil || len(schemaLocations) == 0 {
@ -81,6 +84,8 @@ type v struct {
regs []registry.Registry regs []registry.Registry
} }
// ValidateResource validates a single resource. This allows to validate
// large resource streams using multiple Go Routines.
func (val *v) ValidateResource(res resource.Resource) Result { func (val *v) ValidateResource(res resource.Resource) Result {
skip := func(signature resource.Signature) bool { skip := func(signature resource.Signature) bool {
isSkipKind, ok := val.opts.SkipKinds[signature.Kind] isSkipKind, ok := val.opts.SkipKinds[signature.Kind]
@ -163,7 +168,9 @@ func (val *v) ValidateResource(res resource.Resource) Result {
return Result{Resource: res, Status: Invalid, Err: fmt.Errorf("%s", msg)} return Result{Resource: res, Status: Invalid, Err: fmt.Errorf("%s", msg)}
} }
func (val *v) ValidateWithContext(ctx context.Context, filename string, r io.Reader) []Result { // ValidateWithContext validates resources found in r
// filename should be a name for the stream, such as a filename or stdin
func (val *v) ValidateWithContext(ctx context.Context, filename string, r io.ReadCloser) []Result {
validationResults := []Result{} validationResults := []Result{}
resourcesChan, _ := resource.FromStream(ctx, filename, r) resourcesChan, _ := resource.FromStream(ctx, filename, r)
for { for {
@ -183,10 +190,13 @@ func (val *v) ValidateWithContext(ctx context.Context, filename string, r io.Rea
} }
} }
r.Close()
return validationResults return validationResults
} }
func (val *v) Validate(filename string, r io.Reader) []Result { // Validate validates resources found in r
// filename should be a name for the stream, such as a filename or stdin
func (val *v) Validate(filename string, r io.ReadCloser) []Result {
return val.ValidateWithContext(context.Background(), filename, r) return val.ValidateWithContext(context.Background(), filename, r)
} }