fix(schema): limit $ref resolution to lint command

Schema validation with $ref cross-file references only works when charts
are available as directories on the filesystem. The install, template, and
upgrade commands may work with archived charts (.tgz) that are loaded
directly into memory without filesystem extraction.

This change limits ChartDir setting to the lint command only. The lint
command already extracts archived charts to temporary directories before
validation, so $ref resolution works for both directory and archived charts
when linting.

For install/template/upgrade commands:
- Main schema validation continues to work
- Charts without $ref validate successfully
- Charts with $ref will fail .. maybe we could add a warning about $ref not being supported in these commands?

Changes:
- Remove ChartDir assignment from install and upgrade commands
- Update schema validation to use synthetic path when chartDir is empty
- Add test for linting archived chart with $ref
- Remove install/template/upgrade tests for $ref (not supported)

Signed-off-by: Benoit Tigeot <benoit.tigeot@lifen.fr>
pull/31274/head
Benoit Tigeot 4 weeks ago
parent 690730d3b9
commit dd0b8f40ba
No known key found for this signature in database
GPG Key ID: 8E6D4FC8AEBDA62C

@ -75,6 +75,10 @@ func TestLintChart(t *testing.T) {
name: "chart-with-schema-ref",
chartPath: "testdata/charts/chart-with-schema-ref",
},
{
name: "archived-chart-with-schema-ref",
chartPath: "testdata/charts/chart-with-schema-ref.tgz",
},
{
name: "chart-with-schema-negative",
chartPath: "testdata/charts/chart-with-schema-negative",

@ -86,20 +86,28 @@ func ValidateAgainstSchemaWithPath(ch chart.Charter, values map[string]any, char
var absChartPath string
if chartDir != "" {
var err error
absChartPath, err = filepath.Abs(chartDir)
} else {
absChartPath, err = filepath.Abs(chrt.ChartFullPath())
}
if err != nil {
return err
if err != nil {
return err
}
}
var sb strings.Builder
if chrt.Schema() != nil {
slog.Debug("chart name", "chart-name", chrt.Name())
schemaPath := filepath.Join(absChartPath, "values.schema.json")
err = ValidateAgainstSingleSchemaWithPath(values, chrt.Schema(), schemaPath)
var schemaPath string
if absChartPath != "" {
// Use the chart directory for $ref resolution
schemaPath = filepath.Join(absChartPath, "values.schema.json")
} else {
// No chart directory (e.g., chart loaded from .tgz archive).
// Use a synthetic path - $ref resolution will not work, but main schema validation will.
schemaPath = "/values.schema.json"
}
err := ValidateAgainstSingleSchemaWithPath(values, chrt.Schema(), schemaPath)
if err != nil {
fmt.Fprintf(&sb, "%s:\n", chrt.Name())
sb.WriteString(err.Error())
@ -126,7 +134,11 @@ func ValidateAgainstSchemaWithPath(ch chart.Charter, values map[string]any, char
continue
}
subchartPath := filepath.Join(absChartPath, "charts", sub.Name())
var subchartPath string
if absChartPath != "" {
subchartPath = filepath.Join(absChartPath, "charts", sub.Name())
}
// If absChartPath is empty (archived chart), pass empty string to disable $ref resolution for subcharts too
if err := ValidateAgainstSchemaWithPath(subchart, subchartValues, subchartPath); err != nil {
sb.WriteString(err.Error())
}

@ -247,7 +247,6 @@ func runInstall(args []string, client *action.Install, valueOpts *values.Options
if err != nil {
return nil, err
}
client.ChartDir = cp
slog.Debug("Chart path", "path", cp)

@ -231,11 +231,6 @@ func TestInstall(t *testing.T) {
cmd: "install schema testdata/testcharts/chart-with-schema-and-subchart --set lastname=doe --set subchart-with-schema.age=-25 --skip-schema-validation",
golden: "output/schema.txt",
},
{
name: "install with schema file containing $ref",
cmd: "install reftest testdata/testcharts/chart-with-schema-ref",
golden: "output/schema-ref.txt",
},
// Install deprecated chart
{
name: "install with warning about deprecated chart",

@ -166,11 +166,6 @@ func TestTemplateCmd(t *testing.T) {
cmd: fmt.Sprintf("template '%s' -f %s/extra_values.yaml", chartPath, chartPath),
golden: "output/template-subchart-cm-set-file.txt",
},
{
name: "template with schema file containing $ref",
cmd: "template reftest testdata/testcharts/chart-with-schema-ref",
golden: "output/template-schema-ref.txt",
},
}
runTestCmd(t, tests)
}

@ -1,7 +0,0 @@
NAME: reftest
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None

@ -1,8 +0,0 @@
Release "reftest" has been upgraded. Happy Helming!
NAME: reftest
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 2
DESCRIPTION: Upgrade complete
TEST SUITE: None

@ -1,3 +0,0 @@
apiVersion: v2
name: chart-with-schema-ref
version: 0.1.0

@ -1,4 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "string"
}

@ -1,7 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": { "$ref": "name.schema.json" }
}
}

@ -186,7 +186,6 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
if err != nil {
return err
}
client.ChartDir = chartPath
p := getter.All(settings)
vals, err := valueOpts.MergeValues(p)

@ -190,12 +190,6 @@ func TestUpgradeCmd(t *testing.T) {
golden: "output/upgrade-uninstalled-with-keep-history.txt",
rels: []*release.Release{relWithStatusMock("funny-bunny", 2, ch, rcommon.StatusUninstalled)},
},
{
name: "upgrade with schema file containing $ref",
cmd: "upgrade reftest testdata/testcharts/chart-with-schema-ref",
golden: "output/upgrade-schema-ref.txt",
rels: []*release.Release{relMock("reftest", 1, ch)},
},
}
runTestCmd(t, tests)
}

Loading…
Cancel
Save