func (check SchemaCheck) CheckContainer(container *corev1.Container) (bool, []jsonschema.ValError, error) {
	return check.CheckObject(container)
}
CheckContainer checks a container spec against the schema
package config
import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"strings"
	"text/template"
	"github.com/qri-io/jsonschema"
	"github.com/thoas/go-funk"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	k8sYaml "k8s.io/apimachinery/pkg/util/yaml"
)
type TargetKind string
const (
	TargetController TargetKind = "Controller"
	TargetContainer TargetKind = "Container"
	TargetPod TargetKind = "Pod"
)
var HandledTargets = []TargetKind{
	TargetController,
	TargetContainer,
	TargetPod,
}
type SchemaCheck struct {
	ID                      string                            `yaml:"id" json:"id"`
	Category                string                            `yaml:"category" json:"category"`
	SuccessMessage          string                            `yaml:"successMessage" json:"successMessage"`
	FailureMessage          string                            `yaml:"failureMessage" json:"failureMessage"`
	Controllers             includeExcludeList                `yaml:"controllers" json:"controllers"`
	Containers              includeExcludeList                `yaml:"containers" json:"containers"`
	Target                  TargetKind                        `yaml:"target" json:"target"`
	SchemaTarget            TargetKind                        `yaml:"schemaTarget" json:"schemaTarget"`
	Schema                  map[string]interface{}            `yaml:"schema" json:"schema"`
	SchemaString            string                            `yaml:"schemaString" json:"schemaString"`
	Validator               jsonschema.RootSchema             `yaml:"-" json:"-"`
	AdditionalSchemas       map[string]map[string]interface{} `yaml:"additionalSchemas" json:"additionalSchemas"`
	AdditionalSchemaStrings map[string]string                 `yaml:"additionalSchemaStrings" json:"additionalSchemaStrings"`
	AdditionalValidators    map[string]jsonschema.RootSchema  `yaml:"-" json:"-"`
}
type resourceMinimum string
type resourceMaximum string
func unmarshalYAMLOrJSON(raw []byte, dest interface{}) error {
	reader := bytes.NewReader(raw)
	d := k8sYaml.NewYAMLOrJSONDecoder(reader, 4096)
	for {
		if err := d.Decode(dest); err != nil {
			if err == io.EOF {
				break
			}
			return fmt.Errorf("Decoding schema check failed: %v", err)
		}
	}
	return nil
}
func ParseCheck(id string, rawBytes []byte) (SchemaCheck, error) {
	check := SchemaCheck{}
	err := unmarshalYAMLOrJSON(rawBytes, &check)
	if err != nil {
		return check, err
	}
	check.Initialize(id)
	return check, nil
}
func init() {
	jsonschema.RegisterValidator("resourceMinimum", newResourceMinimum)
	jsonschema.RegisterValidator("resourceMaximum", newResourceMaximum)
}
type includeExcludeList struct {
	Include []string `yaml:"include"`
	Exclude []string `yaml:"exclude"`
}
func newResourceMinimum() jsonschema.Validator {
	return new(resourceMinimum)
}
func newResourceMaximum() jsonschema.Validator {
	return new(resourceMaximum)
}
func (min resourceMinimum) Validate(path string, data interface{}, errs *[]jsonschema.ValError) {
	err := validateRange(path, string(min), data, true)
	if err != nil {
		*errs = append(*errs, *err...)
	}
}
func (max resourceMaximum) Validate(path string, data interface{}, errs *[]jsonschema.ValError) {
	err := validateRange(path, string(max), data, false)
	if err != nil {
		*errs = append(*errs, *err...)
	}
}
func parseQuantity(i interface{}) (resource.Quantity, *[]jsonschema.ValError) {
	resStr, ok := i.(string)
	if !ok {
		return resource.Quantity{}, &[]jsonschema.ValError{
			{Message: fmt.Sprintf("Resource quantity %v is not a string", i)},
		}
	}
	q, err := resource.ParseQuantity(resStr)
	if err != nil {
		return resource.Quantity{}, &[]jsonschema.ValError{
			{Message: fmt.Sprintf("Could not parse resource quantity: %s", resStr)},
		}
	}
	return q, nil
}
func validateRange(path string, limit interface{}, data interface{}, isMinimum bool) *[]jsonschema.ValError {
	limitQuantity, err := parseQuantity(limit)
	if err != nil {
		return err
	}
	actualQuantity, err := parseQuantity(data)
	if err != nil {
		return err
	}
	cmp := limitQuantity.Cmp(actualQuantity)
	if isMinimum {
		if cmp == 1 {
			return &[]jsonschema.ValError{
				{Message: fmt.Sprintf("%s quantity %v is > %v", path, actualQuantity, limitQuantity)},
			}
		}
	} else {
		if cmp == -1 {
			return &[]jsonschema.ValError{
				{Message: fmt.Sprintf("%s quantity %v is < %v", path, actualQuantity, limitQuantity)},
			}
		}
	}
	return nil
}
func (check *SchemaCheck) Initialize(id string) error {
	check.ID = id
	if check.SchemaString == "" {
		jsonBytes, err := json.Marshal(check.Schema)
		if err != nil {
			return err
		}
		check.SchemaString = string(jsonBytes)
	}
	if check.AdditionalSchemaStrings == nil {
		check.AdditionalSchemaStrings = make(map[string]string)
	}
	for kind, schema := range check.AdditionalSchemas {
		jsonBytes, err := json.Marshal(schema)
		if err != nil {
			return err
		}
		check.AdditionalSchemaStrings[kind] = string(jsonBytes)
	}
	check.Schema = map[string]interface{}{}
	check.AdditionalSchemas = map[string]map[string]interface{}{}
	return nil
}
func (check SchemaCheck) TemplateForResource(res interface{}) (*SchemaCheck, error) {
	newCheck := check  
	templateStrings := map[string]string{
		"": newCheck.SchemaString,
	}
	for kind, schema := range newCheck.AdditionalSchemaStrings {
		templateStrings[kind] = schema
	}
	newCheck.SchemaString = ""
	newCheck.AdditionalSchemaStrings = map[string]string{}
	for kind, tmplString := range templateStrings {
		tmpl := template.New(newCheck.ID)
		tmpl, err := tmpl.Parse(tmplString)
		if err != nil {
			return nil, err
		}
		w := bytes.Buffer{}
		err = tmpl.Execute(&w, res)
		if err != nil {
			return nil, err
		}
		if kind == "" {
			newCheck.SchemaString = w.String()
		} else {
			newCheck.AdditionalSchemaStrings[kind] = w.String()
		}
	}
	newCheck.AdditionalValidators = map[string]jsonschema.RootSchema{}
	for kind, schemaStr := range newCheck.AdditionalSchemaStrings {
		val := jsonschema.RootSchema{}
		err := unmarshalYAMLOrJSON([]byte(schemaStr), &val)
		if err != nil {
			return nil, err
		}
		newCheck.AdditionalValidators[kind] = val
	}
	err := unmarshalYAMLOrJSON([]byte(newCheck.SchemaString), &newCheck.Validator)
	if err != nil {
		return nil, err
	}
	return &newCheck, err
}
func (check SchemaCheck) CheckPod(pod *corev1.PodSpec) (bool, []jsonschema.ValError, error) {
	return check.CheckObject(pod)
}
func (check SchemaCheck) CheckController(bytes []byte) (bool, []jsonschema.ValError, error) {
	errs, err := check.Validator.ValidateBytes(bytes)
	return len(errs) == 0, errs, err
}