jsonschema: warn and ignore unresolved URN $ref to match v3.18.4

- v3.18.5 switched jsonschema and began resolving external $ref
  at compile-time, exposing missing urn handling
  (“no URLLoader registered for urn:…”).
- Add urn scheme loader and pluggable URNResolver. If unresolved, log
  a warning and return a permissive true schema (back-compat).
- Apply to pkg/chart/v2 and internal/chart/v3 validators. Not sure about
  that

Note: external URNs need AddResource/Resolver (the CLI uses --map for
this). Warning may appear twice since both validators run.

Another strategy could be to add the option to import more "external
schema" explicitly but it is another PR. Something similar to `--map`
from jsonschema package
(santhosh-tekuri/jsonschema@ed65924).

Close: #31170

Signed-off-by: Benoit Tigeot <benoit.tigeot@lifen.fr>
pull/31240/head
Benoit Tigeot 3 weeks ago
parent fc22b6df31
commit 03bb62f63d
No known key found for this signature in database
GPG Key ID: 8E6D4FC8AEBDA62C

@ -127,6 +127,7 @@ func ValidateAgainstSingleSchema(values common.Values, schemaJSON []byte) (reter
"file": jsonschema.FileLoader{},
"http": newHTTPURLLoader(),
"https": newHTTPURLLoader(),
"urn": urnLoader{},
}
compiler := jsonschema.NewCompiler()
@ -149,6 +150,30 @@ func ValidateAgainstSingleSchema(values common.Values, schemaJSON []byte) (reter
return nil
}
// URNResolverFunc allows SDK to plug a URN resolver. It must return a
// schema document compatible with the validator (e.g., result of
// jsonschema.UnmarshalJSON).
type URNResolverFunc func(urn string) (any, error)
// URNResolver is the default resolver used by the URN loader. By default it
// returns a clear error.
var URNResolver URNResolverFunc = func(urn string) (any, error) {
return nil, fmt.Errorf("URN not resolved: %s", urn)
}
// urnLoader implements resolution for the urn: scheme by delegating to
// URNResolver. If unresolved, it logs a warning and returns a permissive
// boolean-true schema to avoid hard failures (back-compat behavior).
type urnLoader struct{}
func (l urnLoader) Load(urlStr string) (any, error) {
if doc, err := URNResolver(urlStr); err == nil && doc != nil {
return doc, nil
}
slog.Warn("unresolved URN reference ignored; using permissive schema", "urn", urlStr)
return jsonschema.UnmarshalJSON(strings.NewReader("true"))
}
// Note, JSONSchemaValidationError is used to wrap the error from the underlying
// validation package so that Helm has a clean interface and the validation package
// could be replaced without changing the Helm SDK API.

@ -286,3 +286,16 @@ func TestHTTPURLLoader_Load(t *testing.T) {
}
})
}
// Test that an unresolved URN $ref is soft-ignored and validation succeeds.
// it mimics the behavior of Helm 3.18.4
func TestValidateAgainstSingleSchema_UnresolvedURN_Ignored(t *testing.T) {
schema := []byte(`{
"$schema": "https://json-schema.org/draft-07/schema#",
"$ref": "urn:example:helm:schemas:v1:helm-schema-validation-conditions:v1/helmSchemaValidation-true"
}`)
vals := map[string]interface{}{"any": "value"}
if err := ValidateAgainstSingleSchema(vals, schema); err != nil {
t.Fatalf("expected no error when URN unresolved is ignored, got: %v", err)
}
}

Loading…
Cancel
Save