mirror of
https://github.com/helm/helm.git
synced 2026-04-25 16:17:11 -04:00
Merge pull request #13283 from win-t/jsonschema
adding support for JSON Schema 2020
This commit is contained in:
commit
55a4fc121b
4 changed files with 124 additions and 0 deletions
1
go.mod
1
go.mod
|
|
@ -29,6 +29,7 @@ require (
|
|||
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/rubenv/sql-migrate v1.7.1
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/pflag v1.0.6
|
||||
github.com/stretchr/testify v1.10.0
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -67,6 +67,8 @@ github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN
|
|||
github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
|
||||
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
|
||||
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
||||
|
|
@ -297,6 +299,8 @@ github.com/rubenv/sql-migrate v1.7.1 h1:f/o0WgfO/GqNuVg+6801K/KW3WdDSupzSjDYODmi
|
|||
github.com/rubenv/sql-migrate v1.7.1/go.mod h1:Ob2Psprc0/3ggbM6wCzyYVFFuc6FyZrb2AS+ezLDFb4=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 h1:PKK9DyHxif4LZo+uQSgXNqs0jj5+xZwwfKHgph2lxBw=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
|
||||
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||
|
|
|
|||
|
|
@ -18,10 +18,12 @@ package util
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/santhosh-tekuri/jsonschema/v6"
|
||||
"github.com/xeipuuv/gojsonschema"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
|
|
@ -73,6 +75,11 @@ func ValidateAgainstSingleSchema(values Values, schemaJSON []byte) (reterr error
|
|||
if bytes.Equal(valuesJSON, []byte("null")) {
|
||||
valuesJSON = []byte("{}")
|
||||
}
|
||||
|
||||
if schemaIs2020(schemaJSON) {
|
||||
return validateUsingNewValidator(valuesJSON, schemaJSON)
|
||||
}
|
||||
|
||||
schemaLoader := gojsonschema.NewBytesLoader(schemaJSON)
|
||||
valuesLoader := gojsonschema.NewBytesLoader(valuesJSON)
|
||||
|
||||
|
|
@ -91,3 +98,35 @@ func ValidateAgainstSingleSchema(values Values, schemaJSON []byte) (reterr error
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateUsingNewValidator(valuesJSON, schemaJSON []byte) error {
|
||||
schema, err := jsonschema.UnmarshalJSON(bytes.NewReader(schemaJSON))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
values, err := jsonschema.UnmarshalJSON(bytes.NewReader(valuesJSON))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
compiler := jsonschema.NewCompiler()
|
||||
err = compiler.AddResource("file:///values.schema.json", schema)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
validator, err := compiler.Compile("file:///values.schema.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return validator.Validate(values)
|
||||
}
|
||||
|
||||
func schemaIs2020(schemaJSON []byte) bool {
|
||||
var partialSchema struct {
|
||||
Schema string `json:"$schema"`
|
||||
}
|
||||
_ = json.Unmarshal(schemaJSON, &partialSchema)
|
||||
return partialSchema.Schema == "https://json-schema.org/draft/2020-12/schema"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,21 @@ const subchartSchema = `{
|
|||
}
|
||||
`
|
||||
|
||||
const subchartSchema2020 = `{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "Values",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"contains": { "type": "string" },
|
||||
"unevaluatedItems": { "type": "number" }
|
||||
}
|
||||
},
|
||||
"required": ["data"]
|
||||
}
|
||||
`
|
||||
|
||||
func TestValidateAgainstSchema(t *testing.T) {
|
||||
subchartJSON := []byte(subchartSchema)
|
||||
subchart := &chart.Chart{
|
||||
|
|
@ -165,3 +180,68 @@ func TestValidateAgainstSchemaNegative(t *testing.T) {
|
|||
t.Errorf("Error string :\n`%s`\ndoes not match expected\n`%s`", errString, expectedErrString)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateAgainstSchema2020(t *testing.T) {
|
||||
subchartJSON := []byte(subchartSchema2020)
|
||||
subchart := &chart.Chart{
|
||||
Metadata: &chart.Metadata{
|
||||
Name: "subchart",
|
||||
},
|
||||
Schema: subchartJSON,
|
||||
}
|
||||
chrt := &chart.Chart{
|
||||
Metadata: &chart.Metadata{
|
||||
Name: "chrt",
|
||||
},
|
||||
}
|
||||
chrt.AddDependency(subchart)
|
||||
|
||||
vals := map[string]interface{}{
|
||||
"name": "John",
|
||||
"subchart": map[string]interface{}{
|
||||
"data": []any{"hello", 12},
|
||||
},
|
||||
}
|
||||
|
||||
if err := ValidateAgainstSchema(chrt, vals); err != nil {
|
||||
t.Errorf("Error validating Values against Schema: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateAgainstSchema2020Negative(t *testing.T) {
|
||||
subchartJSON := []byte(subchartSchema2020)
|
||||
subchart := &chart.Chart{
|
||||
Metadata: &chart.Metadata{
|
||||
Name: "subchart",
|
||||
},
|
||||
Schema: subchartJSON,
|
||||
}
|
||||
chrt := &chart.Chart{
|
||||
Metadata: &chart.Metadata{
|
||||
Name: "chrt",
|
||||
},
|
||||
}
|
||||
chrt.AddDependency(subchart)
|
||||
|
||||
vals := map[string]interface{}{
|
||||
"name": "John",
|
||||
"subchart": map[string]interface{}{
|
||||
"data": []any{12},
|
||||
},
|
||||
}
|
||||
|
||||
var errString string
|
||||
if err := ValidateAgainstSchema(chrt, vals); err == nil {
|
||||
t.Fatalf("Expected an error, but got nil")
|
||||
} else {
|
||||
errString = err.Error()
|
||||
}
|
||||
|
||||
expectedErrString := `subchart:
|
||||
jsonschema validation failed with 'file:///values.schema.json#'
|
||||
- at '/data': no items match contains schema
|
||||
- at '/data/0': got number, want string`
|
||||
if errString != expectedErrString {
|
||||
t.Errorf("Error string :\n`%s`\ndoes not match expected\n`%s`", errString, expectedErrString)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue