diff --git a/cmd/helm/lint.go b/cmd/helm/lint.go index a7aac172a..5a27ccb89 100644 --- a/cmd/helm/lint.go +++ b/cmd/helm/lint.go @@ -120,6 +120,7 @@ func newLintCmd(out io.Writer) *cobra.Command { f := cmd.Flags() f.BoolVar(&client.Strict, "strict", false, "fail on lint warnings") f.BoolVar(&client.WithSubcharts, "with-subcharts", false, "lint dependent charts") + f.StringArrayVarP(&client.APIVersions, "api-versions", "a", []string{}, "Kubernetes api versions used for Capabilities.APIVersions") addValueOptionsFlags(f, valueOpts) return cmd diff --git a/cmd/helm/lint_test.go b/cmd/helm/lint_test.go index 3501ccf87..5f5dc8afe 100644 --- a/cmd/helm/lint_test.go +++ b/cmd/helm/lint_test.go @@ -33,6 +33,11 @@ func TestLintCmdWithSubchartsFlag(t *testing.T) { cmd: fmt.Sprintf("lint --with-subcharts %s", testChart), golden: "output/lint-chart-with-bad-subcharts-with-subcharts.txt", wantError: true, + }, { + name: "lint good chart using --api-versions flag", + cmd: "lint --api-versions networking.k8s.io/v1 testdata/testcharts/chart-with-api-versions", + golden: "output/lint-chart-with-api-versions.txt", + wantError: false, }} runTestCmd(t, tests) } diff --git a/cmd/helm/testdata/output/lint-chart-with-api-versions.txt b/cmd/helm/testdata/output/lint-chart-with-api-versions.txt new file mode 100644 index 000000000..7a9a78fac --- /dev/null +++ b/cmd/helm/testdata/output/lint-chart-with-api-versions.txt @@ -0,0 +1,5 @@ +==> Linting testdata/testcharts/chart-with-api-versions +[INFO] Chart.yaml: icon is recommended +[INFO] values.yaml: file does not exist + +1 chart(s) linted, 0 chart(s) failed diff --git a/cmd/helm/testdata/testcharts/chart-with-api-versions/Chart.yaml b/cmd/helm/testdata/testcharts/chart-with-api-versions/Chart.yaml new file mode 100644 index 000000000..395d24f6a --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-with-api-versions/Chart.yaml @@ -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 diff --git a/cmd/helm/testdata/testcharts/chart-with-api-versions/templates/check-capabilities.tpl b/cmd/helm/testdata/testcharts/chart-with-api-versions/templates/check-capabilities.tpl new file mode 100644 index 000000000..d157aea2e --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-with-api-versions/templates/check-capabilities.tpl @@ -0,0 +1,3 @@ +{{- if not (.Capabilities.APIVersions.Has "networking.k8s.io/v1") }} + {{ fail "ERROR: APIVersion networking.k8s.io/v1 not found" }} +{{- end -}} \ No newline at end of file diff --git a/pkg/action/lint.go b/pkg/action/lint.go index bdb93dcc2..e5ed53eb3 100644 --- a/pkg/action/lint.go +++ b/pkg/action/lint.go @@ -36,6 +36,7 @@ type Lint struct { Strict bool Namespace string WithSubcharts bool + APIVersions []string } // LintResult is the result of Lint @@ -58,7 +59,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.Strict) + linter, err := lintChart(path, vals, l.Namespace, l.Strict, l.APIVersions) if err != nil { result.Errors = append(result.Errors, err) continue @@ -75,7 +76,7 @@ func (l *Lint) Run(paths []string, vals map[string]interface{}) *LintResult { return result } -func lintChart(path string, vals map[string]interface{}, namespace string, strict bool) (support.Linter, error) { +func lintChart(path string, vals map[string]interface{}, namespace string, strict bool, apiVersions []string) (support.Linter, error) { var chartPath string linter := support.Linter{} @@ -114,5 +115,5 @@ func lintChart(path string, vals map[string]interface{}, namespace string, stric return linter, errors.Wrap(err, "unable to check Chart.yaml file in chart") } - return lint.All(chartPath, vals, namespace, strict), nil + return lint.All(chartPath, vals, namespace, strict, apiVersions), nil } diff --git a/pkg/action/lint_test.go b/pkg/action/lint_test.go index 1828461f3..151f84808 100644 --- a/pkg/action/lint_test.go +++ b/pkg/action/lint_test.go @@ -78,7 +78,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, strict) + _, err := lintChart(tt.chartPath, map[string]interface{}{}, namespace, strict, nil) switch { case err != nil && !tt.err: t.Errorf("%s", err) diff --git a/pkg/lint/lint.go b/pkg/lint/lint.go index 67e76bd3d..dfb1730f6 100644 --- a/pkg/lint/lint.go +++ b/pkg/lint/lint.go @@ -24,14 +24,14 @@ import ( ) // All runs all of the available linters on the given base directory. -func All(basedir string, values map[string]interface{}, namespace string, strict bool) support.Linter { +func All(basedir string, values map[string]interface{}, namespace string, strict bool, apiVersions []string) 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.Templates(&linter, values, namespace, strict) + rules.Templates(&linter, values, namespace, strict, apiVersions) rules.Dependencies(&linter) return linter } diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 61425f92e..af272492b 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -45,7 +45,7 @@ var ( ) // Templates lints the templates in the Linter. -func Templates(linter *support.Linter, values map[string]interface{}, namespace string, strict bool) { +func Templates(linter *support.Linter, values map[string]interface{}, namespace string, strict bool, apiVersions []string) { fpath := "templates/" templatesPath := filepath.Join(linter.ChartDir, fpath) @@ -80,7 +80,10 @@ func Templates(linter *support.Linter, values map[string]interface{}, namespace if err != nil { return } - valuesToRender, err := chartutil.ToRenderValues(chart, cvals, options, nil) + + caps := chartutil.DefaultCapabilities + caps.APIVersions = chartutil.VersionSet(apiVersions) + valuesToRender, err := chartutil.ToRenderValues(chart, cvals, options, caps) if err != nil { linter.RunLinterRule(support.ErrorSev, fpath, err) return