Skip to content

Commit 6801f4d

Browse files
benoittgtmattfarina
authored andcommitted
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). - Avoid having a duplicated warn logs when we Load the schema twice. Note: external URNs need AddResource/Resolver (the CLI uses --map for this). Close: #31170 Signed-off-by: Benoit Tigeot <[email protected]> (cherry picked from commit 3f0da15)
1 parent 2f619be commit 6801f4d

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

pkg/chartutil/jsonschema.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ import (
2121
"crypto/tls"
2222
"errors"
2323
"fmt"
24+
"log"
2425
"strings"
26+
"sync"
2527
"time"
2628

2729
"github.com/santhosh-tekuri/jsonschema/v6"
@@ -128,6 +130,7 @@ func ValidateAgainstSingleSchema(values Values, schemaJSON []byte) (reterr error
128130
"file": jsonschema.FileLoader{},
129131
"http": newHTTPURLLoader(),
130132
"https": newHTTPURLLoader(),
133+
"urn": urnLoader{},
131134
}
132135

133136
compiler := jsonschema.NewCompiler()
@@ -161,3 +164,32 @@ func (e JSONSchemaValidationError) Error() string {
161164

162165
return errStr + "\n"
163166
}
167+
168+
// URNResolverFunc allows SDK to plug a URN resolver. It must return a
169+
// schema document compatible with the validator (e.g., result of
170+
// jsonschema.UnmarshalJSON).
171+
type URNResolverFunc func(urn string) (any, error)
172+
173+
// URNResolver is the default resolver used by the URN loader. By default it
174+
// returns a clear error.
175+
var URNResolver URNResolverFunc = func(urn string) (any, error) {
176+
return nil, fmt.Errorf("URN not resolved: %s", urn)
177+
}
178+
179+
// urnLoader implements resolution for the urn: scheme by delegating to
180+
// URNResolver. If unresolved, it logs a warning and returns a permissive
181+
// boolean-true schema to avoid hard failures (back-compat behavior).
182+
type urnLoader struct{}
183+
184+
// warnedURNs ensures we log the unresolved-URN warning only once per URN.
185+
var warnedURNs sync.Map
186+
187+
func (l urnLoader) Load(urlStr string) (any, error) {
188+
if doc, err := URNResolver(urlStr); err == nil && doc != nil {
189+
return doc, nil
190+
}
191+
if _, loaded := warnedURNs.LoadOrStore(urlStr, struct{}{}); !loaded {
192+
log.Printf("WARNING: unresolved URN reference ignored; using permissive schema: %s", urlStr)
193+
}
194+
return jsonschema.UnmarshalJSON(strings.NewReader("true"))
195+
}

pkg/chartutil/jsonschema_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,3 +376,16 @@ func TestValidateAgainstSchema_InvalidSubchartValuesType_NoPanic(t *testing.T) {
376376
t.Fatalf("expected an error when subchart values have invalid type, got nil")
377377
}
378378
}
379+
380+
// Test that an unresolved URN $ref is soft-ignored and validation succeeds.
381+
// it mimics the behavior of Helm 3.18.4
382+
func TestValidateAgainstSingleSchema_UnresolvedURN_Ignored(t *testing.T) {
383+
schema := []byte(`{
384+
"$schema": "https://json-schema.org/draft-07/schema#",
385+
"$ref": "urn:example:helm:schemas:v1:helm-schema-validation-conditions:v1/helmSchemaValidation-true"
386+
}`)
387+
vals := map[string]interface{}{"any": "value"}
388+
if err := ValidateAgainstSingleSchema(vals, schema); err != nil {
389+
t.Fatalf("expected no error when URN unresolved is ignored, got: %v", err)
390+
}
391+
}

0 commit comments

Comments
 (0)