diff --git a/pkg/chart/common/util/jsonschema.go b/pkg/chart/common/util/jsonschema.go index acd2ca100..827ce4128 100644 --- a/pkg/chart/common/util/jsonschema.go +++ b/pkg/chart/common/util/jsonschema.go @@ -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. diff --git a/pkg/chart/common/util/jsonschema_test.go b/pkg/chart/common/util/jsonschema_test.go index b34f9d514..f50cc81a6 100644 --- a/pkg/chart/common/util/jsonschema_test.go +++ b/pkg/chart/common/util/jsonschema_test.go @@ -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) + } +}