mirror of
https://github.com/helm/helm.git
synced 2026-04-29 10:12:07 -04:00
Merge pull request #12743 from anessi/feat/skip-schema-validation
feat(helm): add --skip-schema-validation flag to helm 'install', 'uprade' and 'lint'
This commit is contained in:
commit
f0442777bb
16 changed files with 149 additions and 21 deletions
|
|
@ -197,6 +197,7 @@ func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Instal
|
|||
f.BoolVar(&client.Atomic, "atomic", false, "if set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used")
|
||||
f.BoolVar(&client.SkipCRDs, "skip-crds", false, "if set, no CRDs will be installed. By default, CRDs are installed if not already present")
|
||||
f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent")
|
||||
f.BoolVar(&client.SkipSchemaValidation, "skip-schema-validation", false, "if set, disables JSON schema validation")
|
||||
f.StringToStringVarP(&client.Labels, "labels", "l", nil, "Labels that would be added to release metadata. Should be divided by comma.")
|
||||
f.BoolVar(&client.EnableDNS, "enable-dns", false, "enable DNS lookups when rendering templates")
|
||||
f.BoolVar(&client.HideNotes, "hide-notes", false, "if set, do not show notes in install output. Does not affect presence in chart metadata")
|
||||
|
|
|
|||
|
|
@ -225,6 +225,12 @@ func TestInstall(t *testing.T) {
|
|||
wantError: true,
|
||||
golden: "output/subchart-schema-cli-negative.txt",
|
||||
},
|
||||
// Install, values from yaml, schematized with errors but skip schema validation, expect success
|
||||
{
|
||||
name: "install with schema file and schematized subchart, extra values from cli, skip schema validation",
|
||||
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",
|
||||
},
|
||||
// Install deprecated chart
|
||||
{
|
||||
name: "install with warning about deprecated chart",
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ func newLintCmd(out io.Writer) *cobra.Command {
|
|||
f.BoolVar(&client.Strict, "strict", false, "fail on lint warnings")
|
||||
f.BoolVar(&client.WithSubcharts, "with-subcharts", false, "lint dependent charts")
|
||||
f.BoolVar(&client.Quiet, "quiet", false, "print only warnings and errors")
|
||||
f.BoolVar(&client.SkipSchemaValidation, "skip-schema-validation", false, "if set, disables JSON schema validation")
|
||||
f.StringVar(&kubeVersion, "kube-version", "", "Kubernetes version used for capabilities and deprecation checks")
|
||||
addValueOptionsFlags(f, valueOpts)
|
||||
|
||||
|
|
|
|||
7
cmd/helm/testdata/testcharts/chart-with-schema-negative-skip-validation/Chart.yaml
vendored
Normal file
7
cmd/helm/testdata/testcharts/chart-with-schema-negative-skip-validation/Chart.yaml
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: v1
|
||||
description: Empty testing chart
|
||||
home: https://k8s.io/helm
|
||||
name: empty
|
||||
sources:
|
||||
- https://github.com/kubernetes/helm
|
||||
version: 0.1.0
|
||||
1
cmd/helm/testdata/testcharts/chart-with-schema-negative-skip-validation/templates/empty.yaml
vendored
Normal file
1
cmd/helm/testdata/testcharts/chart-with-schema-negative-skip-validation/templates/empty.yaml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
# This file is intentionally blank
|
||||
67
cmd/helm/testdata/testcharts/chart-with-schema-negative-skip-validation/values.schema.json
vendored
Normal file
67
cmd/helm/testdata/testcharts/chart-with-schema-negative-skip-validation/values.schema.json
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"addresses": {
|
||||
"description": "List of addresses",
|
||||
"items": {
|
||||
"properties": {
|
||||
"city": {
|
||||
"type": "string"
|
||||
},
|
||||
"number": {
|
||||
"type": "number"
|
||||
},
|
||||
"street": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"age": {
|
||||
"description": "Age",
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
},
|
||||
"employmentInfo": {
|
||||
"properties": {
|
||||
"salary": {
|
||||
"minimum": 0,
|
||||
"type": "number"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"salary"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"firstname": {
|
||||
"description": "First name",
|
||||
"type": "string"
|
||||
},
|
||||
"lastname": {
|
||||
"type": "string"
|
||||
},
|
||||
"likesCoffee": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"phoneNumbers": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"firstname",
|
||||
"lastname",
|
||||
"addresses",
|
||||
"employmentInfo"
|
||||
],
|
||||
"title": "Values",
|
||||
"type": "object"
|
||||
}
|
||||
14
cmd/helm/testdata/testcharts/chart-with-schema-negative-skip-validation/values.yaml
vendored
Normal file
14
cmd/helm/testdata/testcharts/chart-with-schema-negative-skip-validation/values.yaml
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
firstname: John
|
||||
lastname: Doe
|
||||
age: -5
|
||||
likesCoffee: true
|
||||
addresses:
|
||||
- city: Springfield
|
||||
street: Main
|
||||
number: 12345
|
||||
- city: New York
|
||||
street: Broadway
|
||||
number: 67890
|
||||
phoneNumbers:
|
||||
- "(888) 888-8888"
|
||||
- "(555) 555-5555"
|
||||
|
|
@ -145,6 +145,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
|
|||
instClient.DisableOpenAPIValidation = client.DisableOpenAPIValidation
|
||||
instClient.SubNotes = client.SubNotes
|
||||
instClient.HideNotes = client.HideNotes
|
||||
instClient.SkipSchemaValidation = client.SkipSchemaValidation
|
||||
instClient.Description = client.Description
|
||||
instClient.DependencyUpdate = client.DependencyUpdate
|
||||
instClient.Labels = client.Labels
|
||||
|
|
@ -274,6 +275,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
|
|||
f.BoolVar(&client.CleanupOnFail, "cleanup-on-fail", false, "allow deletion of new resources created in this upgrade when upgrade fails")
|
||||
f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent")
|
||||
f.BoolVar(&client.HideNotes, "hide-notes", false, "if set, do not show notes in upgrade output. Does not affect presence in chart metadata")
|
||||
f.BoolVar(&client.SkipSchemaValidation, "skip-schema-validation", false, "if set, disables JSON schema validation")
|
||||
f.StringToStringVarP(&client.Labels, "labels", "l", nil, "Labels that would be added to release metadata. Should be separated by comma. Original release labels will be merged with upgrade labels. You can unset label using null.")
|
||||
f.StringVar(&client.Description, "description", "", "add a custom description")
|
||||
f.BoolVar(&client.DependencyUpdate, "dependency-update", false, "update dependencies if they are missing before installing the chart")
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ type Install struct {
|
|||
SkipCRDs bool
|
||||
SubNotes bool
|
||||
HideNotes bool
|
||||
SkipSchemaValidation bool
|
||||
DisableOpenAPIValidation bool
|
||||
IncludeCRDs bool
|
||||
Labels map[string]string
|
||||
|
|
@ -298,7 +299,7 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
|
|||
IsInstall: !isUpgrade,
|
||||
IsUpgrade: isUpgrade,
|
||||
}
|
||||
valuesToRender, err := chartutil.ToRenderValues(chrt, vals, options, caps)
|
||||
valuesToRender, err := chartutil.ToRenderValuesWithSchemaValidation(chrt, vals, options, caps, i.SkipSchemaValidation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,11 +32,12 @@ import (
|
|||
//
|
||||
// It provides the implementation of 'helm lint'.
|
||||
type Lint struct {
|
||||
Strict bool
|
||||
Namespace string
|
||||
WithSubcharts bool
|
||||
Quiet bool
|
||||
KubeVersion *chartutil.KubeVersion
|
||||
Strict bool
|
||||
Namespace string
|
||||
WithSubcharts bool
|
||||
Quiet bool
|
||||
SkipSchemaValidation bool
|
||||
KubeVersion *chartutil.KubeVersion
|
||||
}
|
||||
|
||||
// LintResult is the result of Lint
|
||||
|
|
@ -59,7 +60,7 @@ func (l *Lint) Run(paths []string, vals map[string]interface{}) *LintResult {
|
|||
}
|
||||
result := &LintResult{}
|
||||
for _, path := range paths {
|
||||
linter, err := lintChart(path, vals, l.Namespace, l.KubeVersion)
|
||||
linter, err := lintChart(path, vals, l.Namespace, l.KubeVersion, l.SkipSchemaValidation)
|
||||
if err != nil {
|
||||
result.Errors = append(result.Errors, err)
|
||||
continue
|
||||
|
|
@ -86,7 +87,7 @@ func HasWarningsOrErrors(result *LintResult) bool {
|
|||
return len(result.Errors) > 0
|
||||
}
|
||||
|
||||
func lintChart(path string, vals map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion) (support.Linter, error) {
|
||||
func lintChart(path string, vals map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion, skipSchemaValidation bool) (support.Linter, error) {
|
||||
var chartPath string
|
||||
linter := support.Linter{}
|
||||
|
||||
|
|
@ -125,5 +126,5 @@ func lintChart(path string, vals map[string]interface{}, namespace string, kubeV
|
|||
return linter, errors.Wrap(err, "unable to check Chart.yaml file in chart")
|
||||
}
|
||||
|
||||
return lint.AllWithKubeVersion(chartPath, vals, namespace, kubeVersion), nil
|
||||
return lint.AllWithKubeVersionAndSchemaValidation(chartPath, vals, namespace, kubeVersion, skipSchemaValidation), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,9 +31,10 @@ var (
|
|||
|
||||
func TestLintChart(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
chartPath string
|
||||
err bool
|
||||
name string
|
||||
chartPath string
|
||||
err bool
|
||||
skipSchemaValidation bool
|
||||
}{
|
||||
{
|
||||
name: "decompressed-chart",
|
||||
|
|
@ -69,6 +70,11 @@ func TestLintChart(t *testing.T) {
|
|||
name: "chart-with-schema-negative",
|
||||
chartPath: "testdata/charts/chart-with-schema-negative",
|
||||
},
|
||||
{
|
||||
name: "chart-with-schema-negative-skip-validation",
|
||||
chartPath: "testdata/charts/chart-with-schema-negative",
|
||||
skipSchemaValidation: true,
|
||||
},
|
||||
{
|
||||
name: "pre-release-chart",
|
||||
chartPath: "testdata/charts/pre-release-chart-0.1.0-alpha.tgz",
|
||||
|
|
@ -77,7 +83,7 @@ func TestLintChart(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := lintChart(tt.chartPath, map[string]interface{}{}, namespace, nil)
|
||||
_, err := lintChart(tt.chartPath, map[string]interface{}{}, namespace, nil, tt.skipSchemaValidation)
|
||||
switch {
|
||||
case err != nil && !tt.err:
|
||||
t.Errorf("%s", err)
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@ type Upgrade struct {
|
|||
SubNotes bool
|
||||
// HideNotes determines whether notes are output during upgrade
|
||||
HideNotes bool
|
||||
// SkipSchemaValidation determines if JSON schema validation is disabled.
|
||||
SkipSchemaValidation bool
|
||||
// Description is the description of this operation
|
||||
Description string
|
||||
Labels map[string]string
|
||||
|
|
@ -258,7 +260,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin
|
|||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
valuesToRender, err := chartutil.ToRenderValues(chart, vals, options, caps)
|
||||
valuesToRender, err := chartutil.ToRenderValuesWithSchemaValidation(chart, vals, options, caps, u.SkipSchemaValidation)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,6 +135,13 @@ type ReleaseOptions struct {
|
|||
//
|
||||
// This takes both ReleaseOptions and Capabilities to merge into the render values.
|
||||
func ToRenderValues(chrt *chart.Chart, chrtVals map[string]interface{}, options ReleaseOptions, caps *Capabilities) (Values, error) {
|
||||
return ToRenderValuesWithSchemaValidation(chrt, chrtVals, options, caps, false)
|
||||
}
|
||||
|
||||
// ToRenderValuesWithSchemaValidation composes the struct from the data coming from the Releases, Charts and Values files
|
||||
//
|
||||
// This takes both ReleaseOptions and Capabilities to merge into the render values.
|
||||
func ToRenderValuesWithSchemaValidation(chrt *chart.Chart, chrtVals map[string]interface{}, options ReleaseOptions, caps *Capabilities, skipSchemaValidation bool) (Values, error) {
|
||||
if caps == nil {
|
||||
caps = DefaultCapabilities
|
||||
}
|
||||
|
|
@ -156,9 +163,11 @@ func ToRenderValues(chrt *chart.Chart, chrtVals map[string]interface{}, options
|
|||
return top, err
|
||||
}
|
||||
|
||||
if err := ValidateAgainstSchema(chrt, vals); err != nil {
|
||||
errFmt := "values don't meet the specifications of the schema(s) in the following chart(s):\n%s"
|
||||
return top, fmt.Errorf(errFmt, err.Error())
|
||||
if !skipSchemaValidation {
|
||||
if err := ValidateAgainstSchema(chrt, vals); err != nil {
|
||||
errFmt := "values don't meet the specifications of the schema(s) in the following chart(s):\n%s"
|
||||
return top, fmt.Errorf(errFmt, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
top["Values"] = vals
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ func TestToRenderValues(t *testing.T) {
|
|||
IsInstall: true,
|
||||
}
|
||||
|
||||
res, err := ToRenderValues(c, overrideValues, o, nil)
|
||||
res, err := ToRenderValuesWithSchemaValidation(c, overrideValues, o, nil, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,20 +24,25 @@ import (
|
|||
"helm.sh/helm/v3/pkg/lint/support"
|
||||
)
|
||||
|
||||
// All runs all of the available linters on the given base directory.
|
||||
// All runs all the available linters on the given base directory.
|
||||
func All(basedir string, values map[string]interface{}, namespace string, _ bool) support.Linter {
|
||||
return AllWithKubeVersion(basedir, values, namespace, nil)
|
||||
}
|
||||
|
||||
// AllWithKubeVersion runs all the available linters on the given base directory, allowing to specify the kubernetes version.
|
||||
func AllWithKubeVersion(basedir string, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion) support.Linter {
|
||||
return AllWithKubeVersionAndSchemaValidation(basedir, values, namespace, kubeVersion, false)
|
||||
}
|
||||
|
||||
// AllWithKubeVersionAndSchemaValidation runs all the available linters on the given base directory, allowing to specify the kubernetes version and if schema validation is enabled or not.
|
||||
func AllWithKubeVersionAndSchemaValidation(basedir string, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion, skipSchemaValidation bool) support.Linter {
|
||||
// Using abs path to get directory context
|
||||
chartDir, _ := filepath.Abs(basedir)
|
||||
|
||||
linter := support.Linter{ChartDir: chartDir}
|
||||
rules.Chartfile(&linter)
|
||||
rules.ValuesWithOverrides(&linter, values)
|
||||
rules.TemplatesWithKubeVersion(&linter, values, namespace, kubeVersion)
|
||||
rules.TemplatesWithSkipSchemaValidation(&linter, values, namespace, kubeVersion, skipSchemaValidation)
|
||||
rules.Dependencies(&linter)
|
||||
return linter
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,11 @@ func Templates(linter *support.Linter, values map[string]interface{}, namespace
|
|||
|
||||
// TemplatesWithKubeVersion lints the templates in the Linter, allowing to specify the kubernetes version.
|
||||
func TemplatesWithKubeVersion(linter *support.Linter, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion) {
|
||||
TemplatesWithSkipSchemaValidation(linter, values, namespace, kubeVersion, false)
|
||||
}
|
||||
|
||||
// TemplatesWithSkipSchemaValidation lints the templates in the Linter, allowing to specify the kubernetes version and if schema validation is enabled or not.
|
||||
func TemplatesWithSkipSchemaValidation(linter *support.Linter, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion, skipSchemaValidation bool) {
|
||||
fpath := "templates/"
|
||||
templatesPath := filepath.Join(linter.ChartDir, fpath)
|
||||
|
||||
|
|
@ -91,7 +96,7 @@ func TemplatesWithKubeVersion(linter *support.Linter, values map[string]interfac
|
|||
return
|
||||
}
|
||||
|
||||
valuesToRender, err := chartutil.ToRenderValues(chart, cvals, options, caps)
|
||||
valuesToRender, err := chartutil.ToRenderValuesWithSchemaValidation(chart, cvals, options, caps, skipSchemaValidation)
|
||||
if err != nil {
|
||||
linter.RunLinterRule(support.ErrorSev, fpath, err)
|
||||
return
|
||||
|
|
|
|||
Loading…
Reference in a new issue