Replace xeipuuv/gojsonschema with santhosh-tekuri/jsonschema

Signed-off-by: Ferran Vidal <ferran.vidal.p@gmail.com>
pull/11340/head
Ferran Vidal 2 years ago
parent 26b785191b
commit a77b4f9855
No known key found for this signature in database

@ -1,4 +1,4 @@
Error: INSTALLATION FAILED: values don't meet the specifications of the schema(s) in the following chart(s): Error: INSTALLATION FAILED: values don't meet the specifications of the schema(s) in the following chart(s):
empty: empty:
- age: Must be greater than or equal to 0 - age: must be >= 0 but found -5

@ -1,5 +1,5 @@
Error: INSTALLATION FAILED: values don't meet the specifications of the schema(s) in the following chart(s): Error: INSTALLATION FAILED: values don't meet the specifications of the schema(s) in the following chart(s):
empty: empty:
- (root): employmentInfo is required - (root): missing properties: 'employmentInfo'
- age: Must be greater than or equal to 0 - age: must be >= 0 but found -5

@ -1,4 +1,4 @@
Error: INSTALLATION FAILED: values don't meet the specifications of the schema(s) in the following chart(s): Error: INSTALLATION FAILED: values don't meet the specifications of the schema(s) in the following chart(s):
subchart-with-schema: subchart-with-schema:
- age: Must be greater than or equal to 0 - age: must be >= 0 but found -25

@ -1,6 +1,6 @@
Error: INSTALLATION FAILED: values don't meet the specifications of the schema(s) in the following chart(s): Error: INSTALLATION FAILED: values don't meet the specifications of the schema(s) in the following chart(s):
chart-without-schema: chart-without-schema:
- (root): lastname is required - (root): missing properties: 'lastname'
subchart-with-schema: subchart-with-schema:
- (root): age is required - (root): missing properties: 'age'

@ -28,11 +28,11 @@ require (
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/rubenv/sql-migrate v1.5.2 github.com/rubenv/sql-migrate v1.5.2
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0 github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
github.com/xeipuuv/gojsonschema v1.2.0
golang.org/x/crypto v0.21.0 golang.org/x/crypto v0.21.0
golang.org/x/term v0.18.0 golang.org/x/term v0.18.0
golang.org/x/text v0.14.0 golang.org/x/text v0.14.0
@ -135,8 +135,6 @@ require (
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/cast v1.5.0 // indirect github.com/spf13/cast v1.5.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xlab/treeprint v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 // indirect github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 // indirect
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 // indirect github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 // indirect

@ -353,6 +353,8 @@ github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzF
github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is= github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= 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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
@ -382,13 +384,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
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/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

@ -22,9 +22,10 @@ import (
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/xeipuuv/gojsonschema"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
"github.com/santhosh-tekuri/jsonschema/v5"
"helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart"
) )
@ -73,21 +74,44 @@ func ValidateAgainstSingleSchema(values Values, schemaJSON []byte) (reterr error
if bytes.Equal(valuesJSON, []byte("null")) { if bytes.Equal(valuesJSON, []byte("null")) {
valuesJSON = []byte("{}") valuesJSON = []byte("{}")
} }
schemaLoader := gojsonschema.NewBytesLoader(schemaJSON)
valuesLoader := gojsonschema.NewBytesLoader(valuesJSON)
result, err := gojsonschema.Validate(schemaLoader, valuesLoader) var rawInterface interface{}
if err = yaml.Unmarshal(valuesJSON, &rawInterface); err != nil {
return err
}
schema, err := jsonschema.CompileString("values.schema.json", string(schemaJSON))
if err != nil { if err != nil {
return err return err
} }
if !result.Valid() { if err = schema.Validate(rawInterface); err != nil {
var sb strings.Builder var jsonschemaError *jsonschema.ValidationError
for _, desc := range result.Errors() { if errors.As(err, &jsonschemaError) {
sb.WriteString(fmt.Sprintf("- %s\n", desc)) return errors.New(processErrorMessage(jsonschemaError))
} }
return errors.New(sb.String())
return err
} }
return nil return nil
} }
func processErrorMessage(error *jsonschema.ValidationError) string {
var sb strings.Builder
if error.KeywordLocation != "" {
location := error.InstanceLocation
if location == "" {
location = "(root)"
}
sb.WriteString(fmt.Sprintf("- %s: %s\n", strings.TrimPrefix(location, "/"), error.Message))
}
for _, cause := range error.Causes {
sb.WriteString(processErrorMessage(cause))
}
return sb.String()
}

@ -20,6 +20,8 @@ import (
"os" "os"
"testing" "testing"
"github.com/stretchr/testify/assert"
"helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart"
) )
@ -40,26 +42,16 @@ func TestValidateAgainstSingleSchema(t *testing.T) {
func TestValidateAgainstInvalidSingleSchema(t *testing.T) { func TestValidateAgainstInvalidSingleSchema(t *testing.T) {
values, err := ReadValuesFile("./testdata/test-values.yaml") values, err := ReadValuesFile("./testdata/test-values.yaml")
if err != nil { assert.NoError(t, err)
t.Fatalf("Error reading YAML file: %s", err)
}
schema, err := os.ReadFile("./testdata/test-values-invalid.schema.json")
if err != nil {
t.Fatalf("Error reading YAML file: %s", err)
}
var errString string schema, err := os.ReadFile("./testdata/test-values-invalid.schema.json")
if err := ValidateAgainstSingleSchema(values, schema); err == nil { assert.NoError(t, err)
t.Fatalf("Expected an error, but got nil")
} else {
errString = err.Error()
}
expectedErrString := "unable to validate schema: runtime error: invalid " + assert.ErrorContains(
"memory address or nil pointer dereference" t,
if errString != expectedErrString { ValidateAgainstSingleSchema(values, schema),
t.Errorf("Error string :\n`%s`\ndoes not match expected\n`%s`", errString, expectedErrString) "does not validate with https://json-schema.org/draft/2020-12/schema#/type: expected object or boolean, but got number",
} )
} }
func TestValidateAgainstSingleSchemaNegative(t *testing.T) { func TestValidateAgainstSingleSchemaNegative(t *testing.T) {
@ -79,8 +71,8 @@ func TestValidateAgainstSingleSchemaNegative(t *testing.T) {
errString = err.Error() errString = err.Error()
} }
expectedErrString := `- (root): employmentInfo is required expectedErrString := `- (root): missing properties: 'employmentInfo'
- age: Must be greater than or equal to 0 - age: must be >= 0 but found -5
` `
if errString != expectedErrString { if errString != expectedErrString {
t.Errorf("Error string :\n`%s`\ndoes not match expected\n`%s`", errString, expectedErrString) t.Errorf("Error string :\n`%s`\ndoes not match expected\n`%s`", errString, expectedErrString)
@ -159,7 +151,7 @@ func TestValidateAgainstSchemaNegative(t *testing.T) {
} }
expectedErrString := `subchart: expectedErrString := `subchart:
- (root): age is required - (root): missing properties: 'age'
` `
if errString != expectedErrString { if errString != expectedErrString {
t.Errorf("Error string :\n`%s`\ndoes not match expected\n`%s`", errString, expectedErrString) t.Errorf("Error string :\n`%s`\ndoes not match expected\n`%s`", errString, expectedErrString)

@ -96,7 +96,7 @@ func TestValidateValuesFileSchemaFailure(t *testing.T) {
t.Fatal("expected values file to fail parsing") t.Fatal("expected values file to fail parsing")
} }
assert.Contains(t, err.Error(), "Expected: string, given: integer", "integer should be caught by schema") assert.Contains(t, err.Error(), "expected string, but got number", "integer should be caught by schema")
} }
func TestValidateValuesFileSchemaOverrides(t *testing.T) { func TestValidateValuesFileSchemaOverrides(t *testing.T) {
@ -129,7 +129,7 @@ func TestValidateValuesFile(t *testing.T) {
name: "value not overridden", name: "value not overridden",
yaml: "username: admin\npassword:", yaml: "username: admin\npassword:",
overrides: map[string]interface{}{"username": "anotherUser"}, overrides: map[string]interface{}{"username": "anotherUser"},
errorMessage: "Expected: string, given: null", errorMessage: "expected string, but got null",
}, },
{ {
name: "value overridden", name: "value overridden",

Loading…
Cancel
Save