From ae058a6622c4450a4094118c9d162b78257cb9ab Mon Sep 17 00:00:00 2001 From: bartem Date: Mon, 7 Aug 2023 11:17:05 +0300 Subject: [PATCH 1/4] fix(helm): add --name flag to 'helm lint' When 'helm lint Chart.yaml --name my-release' is run, this will properly handle configs from values.yaml Closes #12275 Signed-off-by: bartem bartem@ozon.ru Signed-off-by: bartem --- cmd/helm/lint.go | 1 + go.sum | 4 ++-- pkg/action/lint.go | 7 ++++--- pkg/action/lint_test.go | 3 ++- pkg/lint/lint.go | 4 ++-- pkg/lint/lint_test.go | 15 ++++++++------- pkg/lint/rules/template.go | 4 ++-- pkg/lint/rules/template_test.go | 15 ++++++++------- 8 files changed, 29 insertions(+), 24 deletions(-) diff --git a/cmd/helm/lint.go b/cmd/helm/lint.go index 73a37b6fe..d00389a2b 100644 --- a/cmd/helm/lint.go +++ b/cmd/helm/lint.go @@ -134,6 +134,7 @@ func newLintCmd(out io.Writer) *cobra.Command { } f := cmd.Flags() + f.StringVar(&client.ReleaseName, "name", "test-release", "release name") 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") diff --git a/go.sum b/go.sum index 02d9b7dbb..ecc4f5b54 100644 --- a/go.sum +++ b/go.sum @@ -536,7 +536,7 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0 h1:Eos8ADtH0+TRyP9FIkHvEOPZpKm7msAYC9Wrmo4U2Zk= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -714,7 +714,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0 h1:oKAr788FVQcOkc+Kev5Ecm71RFbDMgW99eZQMH92H8w= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/action/lint.go b/pkg/action/lint.go index e71cfe733..43dfdfe78 100644 --- a/pkg/action/lint.go +++ b/pkg/action/lint.go @@ -33,6 +33,7 @@ import ( // It provides the implementation of 'helm lint'. type Lint struct { Strict bool + ReleaseName string Namespace string WithSubcharts bool Quiet bool @@ -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.ReleaseName, l.Namespace, l.Strict) if err != nil { result.Errors = append(result.Errors, err) continue @@ -85,7 +86,7 @@ func HasWarningsOrErrors(result *LintResult) bool { return len(result.Errors) > 0 } -func lintChart(path string, vals map[string]interface{}, namespace string, strict bool) (support.Linter, error) { +func lintChart(path string, vals map[string]interface{}, name, namespace string, strict bool) (support.Linter, error) { var chartPath string linter := support.Linter{} @@ -124,5 +125,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, name, namespace, strict), nil } diff --git a/pkg/action/lint_test.go b/pkg/action/lint_test.go index ff69407ca..7b37e2f8b 100644 --- a/pkg/action/lint_test.go +++ b/pkg/action/lint_test.go @@ -22,6 +22,7 @@ import ( var ( values = make(map[string]interface{}) + defaultName = "test-release" namespace = "testNamespace" strict = false chart1MultipleChartLint = "testdata/charts/multiplecharts-lint-chart-1" @@ -78,7 +79,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{}{}, defaultName, namespace, strict) switch { case err != nil && !tt.err: t.Errorf("%s", err) diff --git a/pkg/lint/lint.go b/pkg/lint/lint.go index 67e76bd3d..c611a78dc 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{}, name, namespace string, strict 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.Templates(&linter, values, namespace, strict) + rules.Templates(&linter, values, name, namespace, strict) rules.Dependencies(&linter) return linter } diff --git a/pkg/lint/lint_test.go b/pkg/lint/lint_test.go index 5516ec668..ee2a47b4f 100644 --- a/pkg/lint/lint_test.go +++ b/pkg/lint/lint_test.go @@ -27,6 +27,7 @@ import ( var values map[string]interface{} +const defaultName = "test-release" const namespace = "testNamespace" const strict = false @@ -38,7 +39,7 @@ const subChartValuesDir = "rules/testdata/withsubchart" const malformedTemplate = "rules/testdata/malformed-template" func TestBadChart(t *testing.T) { - m := All(badChartDir, values, namespace, strict).Messages + m := All(badChartDir, values, defaultName, namespace, strict).Messages if len(m) != 8 { t.Errorf("Number of errors %v", len(m)) t.Errorf("All didn't fail with expected errors, got %#v", m) @@ -82,7 +83,7 @@ func TestBadChart(t *testing.T) { } func TestInvalidYaml(t *testing.T) { - m := All(badYamlFileDir, values, namespace, strict).Messages + m := All(badYamlFileDir, values, defaultName, namespace, strict).Messages if len(m) != 1 { t.Fatalf("All didn't fail with expected errors, got %#v", m) } @@ -92,7 +93,7 @@ func TestInvalidYaml(t *testing.T) { } func TestBadValues(t *testing.T) { - m := All(badValuesFileDir, values, namespace, strict).Messages + m := All(badValuesFileDir, values, defaultName, namespace, strict).Messages if len(m) < 1 { t.Fatalf("All didn't fail with expected errors, got %#v", m) } @@ -102,7 +103,7 @@ func TestBadValues(t *testing.T) { } func TestGoodChart(t *testing.T) { - m := All(goodChartDir, values, namespace, strict).Messages + m := All(goodChartDir, values, defaultName, namespace, strict).Messages if len(m) != 0 { t.Error("All returned linter messages when it shouldn't have") for i, msg := range m { @@ -126,7 +127,7 @@ func TestHelmCreateChart(t *testing.T) { // Note: we test with strict=true here, even though others have // strict = false. - m := All(createdChart, values, namespace, true).Messages + m := All(createdChart, values, defaultName, namespace, true).Messages if ll := len(m); ll != 1 { t.Errorf("All should have had exactly 1 error. Got %d", ll) for i, msg := range m { @@ -140,7 +141,7 @@ func TestHelmCreateChart(t *testing.T) { // lint ignores import-values // See https://github.com/helm/helm/issues/9658 func TestSubChartValuesChart(t *testing.T) { - m := All(subChartValuesDir, values, namespace, strict).Messages + m := All(subChartValuesDir, values, defaultName, namespace, strict).Messages if len(m) != 0 { t.Error("All returned linter messages when it shouldn't have") for i, msg := range m { @@ -156,7 +157,7 @@ func TestMalformedTemplate(t *testing.T) { ch := make(chan int, 1) var m []support.Message go func() { - m = All(malformedTemplate, values, namespace, strict).Messages + m = All(malformedTemplate, values, defaultName, namespace, strict).Messages ch <- 1 }() select { diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 000f7ebcf..0aee7cb93 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{}, name, namespace string, strict bool) { fpath := "templates/" templatesPath := filepath.Join(linter.ChartDir, fpath) @@ -66,7 +66,7 @@ func Templates(linter *support.Linter, values map[string]interface{}, namespace } options := chartutil.ReleaseOptions{ - Name: "test-release", + Name: name, Namespace: namespace, } diff --git a/pkg/lint/rules/template_test.go b/pkg/lint/rules/template_test.go index f3aa641f2..eed221598 100644 --- a/pkg/lint/rules/template_test.go +++ b/pkg/lint/rules/template_test.go @@ -50,12 +50,13 @@ func TestValidateAllowedExtension(t *testing.T) { var values = map[string]interface{}{"nameOverride": "", "httpPort": 80} +const defaultName = "test-release" const namespace = "testNamespace" const strict = false func TestTemplateParsing(t *testing.T) { linter := support.Linter{ChartDir: templateTestBasedir} - Templates(&linter, values, namespace, strict) + Templates(&linter, values, defaultName, namespace, strict) res := linter.Messages if len(res) != 1 { @@ -78,7 +79,7 @@ func TestTemplateIntegrationHappyPath(t *testing.T) { defer os.Rename(ignoredTemplatePath, wrongTemplatePath) linter := support.Linter{ChartDir: templateTestBasedir} - Templates(&linter, values, namespace, strict) + Templates(&linter, values, defaultName, namespace, strict) res := linter.Messages if len(res) != 0 { @@ -88,7 +89,7 @@ func TestTemplateIntegrationHappyPath(t *testing.T) { func TestV3Fail(t *testing.T) { linter := support.Linter{ChartDir: "./testdata/v3-fail"} - Templates(&linter, values, namespace, strict) + Templates(&linter, values, defaultName, namespace, strict) res := linter.Messages if len(res) != 3 { @@ -108,7 +109,7 @@ func TestV3Fail(t *testing.T) { func TestMultiTemplateFail(t *testing.T) { linter := support.Linter{ChartDir: "./testdata/multi-template-fail"} - Templates(&linter, values, namespace, strict) + Templates(&linter, values, defaultName, namespace, strict) res := linter.Messages if len(res) != 1 { @@ -229,7 +230,7 @@ func TestDeprecatedAPIFails(t *testing.T) { } linter := support.Linter{ChartDir: filepath.Join(tmpdir, mychart.Name())} - Templates(&linter, values, namespace, strict) + Templates(&linter, values, defaultName, namespace, strict) if l := len(linter.Messages); l != 1 { for i, msg := range linter.Messages { t.Logf("Message %d: %s", i, msg) @@ -286,7 +287,7 @@ func TestStrictTemplateParsingMapError(t *testing.T) { linter := &support.Linter{ ChartDir: filepath.Join(dir, ch.Metadata.Name), } - Templates(linter, ch.Values, namespace, strict) + Templates(linter, ch.Values, defaultName, namespace, strict) if len(linter.Messages) != 0 { t.Errorf("expected zero messages, got %d", len(linter.Messages)) for i, msg := range linter.Messages { @@ -416,7 +417,7 @@ func TestEmptyWithCommentsManifests(t *testing.T) { } linter := support.Linter{ChartDir: filepath.Join(tmpdir, mychart.Name())} - Templates(&linter, values, namespace, strict) + Templates(&linter, values, defaultName, namespace, strict) if l := len(linter.Messages); l > 0 { for i, msg := range linter.Messages { t.Logf("Message %d: %s", i, msg) From a9694a1dcc56434fbfa58118deae22c0ba32edd0 Mon Sep 17 00:00:00 2001 From: bartem Date: Wed, 20 Mar 2024 16:31:45 +0300 Subject: [PATCH 2/4] mr feedback Signed-off-by: bartem --- pkg/action/lint.go | 3 ++- pkg/lint/lint.go | 8 ++++---- pkg/lint/rules/template.go | 13 +++++++++---- pkg/lint/rules/template_options.go | 20 ++++++++++++++++++++ 4 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 pkg/lint/rules/template_options.go diff --git a/pkg/action/lint.go b/pkg/action/lint.go index cf6bd23d9..d1553f855 100644 --- a/pkg/action/lint.go +++ b/pkg/action/lint.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/pkg/errors" + "helm.sh/helm/v3/pkg/lint/rules" "helm.sh/helm/v3/pkg/chartutil" "helm.sh/helm/v3/pkg/lint" @@ -126,5 +127,5 @@ func lintChart(path string, vals map[string]interface{}, releaseName, namespace return linter, errors.Wrap(err, "unable to check Chart.yaml file in chart") } - return lint.AllWithKubeVersion(chartPath, vals, releaseName, namespace, kubeVersion), nil + return lint.AllWithKubeVersion(chartPath, vals, namespace, kubeVersion, rules.WithReleaseName(releaseName)), nil } diff --git a/pkg/lint/lint.go b/pkg/lint/lint.go index 15ebcad4d..31c93c867 100644 --- a/pkg/lint/lint.go +++ b/pkg/lint/lint.go @@ -25,19 +25,19 @@ import ( ) // All runs all of the available linters on the given base directory. -func All(basedir string, values map[string]interface{}, releaseName, namespace string, _ bool) support.Linter { - return AllWithKubeVersion(basedir, values, releaseName, namespace, nil) +func All(basedir string, values map[string]interface{}, namespace string, _ bool, opts ...rules.TemplateOption) support.Linter { + return AllWithKubeVersion(basedir, values, namespace, nil, opts...) } // 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{}, releaseName, namespace string, kubeVersion *chartutil.KubeVersion) support.Linter { +func AllWithKubeVersion(basedir string, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion, opts ...rules.TemplateOption) 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, releaseName, namespace, kubeVersion) + rules.TemplatesWithKubeVersion(&linter, values, namespace, kubeVersion, opts...) rules.Dependencies(&linter) return linter } diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 5cf641684..3aec094f3 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -45,12 +45,12 @@ var ( ) // Templates lints the templates in the Linter. -func Templates(linter *support.Linter, values map[string]interface{}, releaseName, namespace string, _ bool) { - TemplatesWithKubeVersion(linter, values, releaseName, namespace, nil) +func Templates(linter *support.Linter, values map[string]interface{}, namespace string, _ bool, opts ...TemplateOption) { + TemplatesWithKubeVersion(linter, values, namespace, nil, opts...) } // TemplatesWithKubeVersion lints the templates in the Linter, allowing to specify the kubernetes version. -func TemplatesWithKubeVersion(linter *support.Linter, values map[string]interface{}, releaseName, namespace string, kubeVersion *chartutil.KubeVersion) { +func TemplatesWithKubeVersion(linter *support.Linter, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion, opts ...TemplateOption) { fpath := "templates/" templatesPath := filepath.Join(linter.ChartDir, fpath) @@ -70,8 +70,13 @@ func TemplatesWithKubeVersion(linter *support.Linter, values map[string]interfac return } + o := defaultTemplateOptions + for _, optFn := range opts { + optFn(o) + } + options := chartutil.ReleaseOptions{ - Name: releaseName, + Name: o.releaseName, Namespace: namespace, } diff --git a/pkg/lint/rules/template_options.go b/pkg/lint/rules/template_options.go new file mode 100644 index 000000000..203801fa5 --- /dev/null +++ b/pkg/lint/rules/template_options.go @@ -0,0 +1,20 @@ +package rules + +type ( + templateOptions struct { + releaseName string + } + + TemplateOption func(o *templateOptions) +) + +var defaultTemplateOptions = &templateOptions{ + releaseName: "test-release", +} + +// WithReleaseName specify release name for linter +func WithReleaseName(name string) TemplateOption { + return func(o *templateOptions) { + o.releaseName = name + } +} From 799f34f673b733dddb227c3b37a34c8bca464a60 Mon Sep 17 00:00:00 2001 From: bartem Date: Wed, 20 Mar 2024 17:09:46 +0300 Subject: [PATCH 3/4] refactoring Signed-off-by: bartem --- pkg/action/lint.go | 6 ++++-- pkg/lint/lint.go | 21 +++++++++++++++++---- pkg/lint/lint_options.go | 22 ++++++++++++++++++++++ pkg/lint/lint_test.go | 14 +++++++------- pkg/lint/rules/template.go | 27 +++++++++++++++------------ pkg/lint/rules/template_options.go | 20 -------------------- pkg/lint/rules/template_test.go | 30 +++++++++++++++--------------- pkg/lint/support/message.go | 8 +++++++- 8 files changed, 87 insertions(+), 61 deletions(-) create mode 100644 pkg/lint/lint_options.go delete mode 100644 pkg/lint/rules/template_options.go diff --git a/pkg/action/lint.go b/pkg/action/lint.go index d1553f855..365e6a4c3 100644 --- a/pkg/action/lint.go +++ b/pkg/action/lint.go @@ -22,7 +22,6 @@ import ( "strings" "github.com/pkg/errors" - "helm.sh/helm/v3/pkg/lint/rules" "helm.sh/helm/v3/pkg/chartutil" "helm.sh/helm/v3/pkg/lint" @@ -127,5 +126,8 @@ func lintChart(path string, vals map[string]interface{}, releaseName, namespace return linter, errors.Wrap(err, "unable to check Chart.yaml file in chart") } - return lint.AllWithKubeVersion(chartPath, vals, namespace, kubeVersion, rules.WithReleaseName(releaseName)), nil + return lint.AllWithOptions(chartPath, vals, namespace, + lint.WithReleaseName(releaseName), + lint.WithKubeVersion(kubeVersion), + ), nil } diff --git a/pkg/lint/lint.go b/pkg/lint/lint.go index 31c93c867..cf7f4b041 100644 --- a/pkg/lint/lint.go +++ b/pkg/lint/lint.go @@ -25,19 +25,32 @@ import ( ) // All runs all of the available linters on the given base directory. -func All(basedir string, values map[string]interface{}, namespace string, _ bool, opts ...rules.TemplateOption) support.Linter { - return AllWithKubeVersion(basedir, values, namespace, nil, opts...) +// Deprecated, use AllWithOptions instead. +func All(basedir string, values map[string]interface{}, namespace string, _ bool) support.Linter { + return AllWithOptions(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, opts ...rules.TemplateOption) support.Linter { +// Deprecated, use AllWithOptions instead. +func AllWithKubeVersion(basedir string, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion) support.Linter { + return AllWithOptions(basedir, values, namespace, WithKubeVersion(kubeVersion)) +} + +// AllWithOptions runs all the available linters on the given base directory, allowing to specify different options. +func AllWithOptions(basedir string, values map[string]interface{}, namespace string, options ...LinterOption) support.Linter { // Using abs path to get directory context chartDir, _ := filepath.Abs(basedir) linter := support.Linter{ChartDir: chartDir} + + for _, optFn := range options { + optFn(&linter) + } + rules.Chartfile(&linter) rules.ValuesWithOverrides(&linter, values) - rules.TemplatesWithKubeVersion(&linter, values, namespace, kubeVersion, opts...) + rules.TemplatesV2(&linter, values, namespace) rules.Dependencies(&linter) + return linter } diff --git a/pkg/lint/lint_options.go b/pkg/lint/lint_options.go new file mode 100644 index 000000000..9758bcfcb --- /dev/null +++ b/pkg/lint/lint_options.go @@ -0,0 +1,22 @@ +package lint + +import ( + "helm.sh/helm/v3/pkg/chartutil" + "helm.sh/helm/v3/pkg/lint/support" +) + +type LinterOption func(linter *support.Linter) + +// WithReleaseName specifies chart release name +func WithReleaseName(name string) LinterOption { + return func(linter *support.Linter) { + linter.ReleaseName = name + } +} + +// WithKubeVersion specifies kube version +func WithKubeVersion(version *chartutil.KubeVersion) LinterOption { + return func(linter *support.Linter) { + linter.KubeVersion = version + } +} diff --git a/pkg/lint/lint_test.go b/pkg/lint/lint_test.go index ee2a47b4f..369f496f2 100644 --- a/pkg/lint/lint_test.go +++ b/pkg/lint/lint_test.go @@ -39,7 +39,7 @@ const subChartValuesDir = "rules/testdata/withsubchart" const malformedTemplate = "rules/testdata/malformed-template" func TestBadChart(t *testing.T) { - m := All(badChartDir, values, defaultName, namespace, strict).Messages + m := AllWithOptions(badChartDir, values, namespace, WithReleaseName(defaultName)).Messages if len(m) != 8 { t.Errorf("Number of errors %v", len(m)) t.Errorf("All didn't fail with expected errors, got %#v", m) @@ -83,7 +83,7 @@ func TestBadChart(t *testing.T) { } func TestInvalidYaml(t *testing.T) { - m := All(badYamlFileDir, values, defaultName, namespace, strict).Messages + m := AllWithOptions(badYamlFileDir, values, namespace, WithReleaseName(defaultName)).Messages if len(m) != 1 { t.Fatalf("All didn't fail with expected errors, got %#v", m) } @@ -93,7 +93,7 @@ func TestInvalidYaml(t *testing.T) { } func TestBadValues(t *testing.T) { - m := All(badValuesFileDir, values, defaultName, namespace, strict).Messages + m := AllWithOptions(badValuesFileDir, values, namespace, WithReleaseName(defaultName)).Messages if len(m) < 1 { t.Fatalf("All didn't fail with expected errors, got %#v", m) } @@ -103,7 +103,7 @@ func TestBadValues(t *testing.T) { } func TestGoodChart(t *testing.T) { - m := All(goodChartDir, values, defaultName, namespace, strict).Messages + m := AllWithOptions(goodChartDir, values, namespace, WithReleaseName(defaultName)).Messages if len(m) != 0 { t.Error("All returned linter messages when it shouldn't have") for i, msg := range m { @@ -127,7 +127,7 @@ func TestHelmCreateChart(t *testing.T) { // Note: we test with strict=true here, even though others have // strict = false. - m := All(createdChart, values, defaultName, namespace, true).Messages + m := AllWithOptions(createdChart, values, namespace, WithReleaseName(defaultName)).Messages if ll := len(m); ll != 1 { t.Errorf("All should have had exactly 1 error. Got %d", ll) for i, msg := range m { @@ -141,7 +141,7 @@ func TestHelmCreateChart(t *testing.T) { // lint ignores import-values // See https://github.com/helm/helm/issues/9658 func TestSubChartValuesChart(t *testing.T) { - m := All(subChartValuesDir, values, defaultName, namespace, strict).Messages + m := AllWithOptions(subChartValuesDir, values, namespace, WithReleaseName(defaultName)).Messages if len(m) != 0 { t.Error("All returned linter messages when it shouldn't have") for i, msg := range m { @@ -157,7 +157,7 @@ func TestMalformedTemplate(t *testing.T) { ch := make(chan int, 1) var m []support.Message go func() { - m = All(malformedTemplate, values, defaultName, namespace, strict).Messages + m = AllWithOptions(malformedTemplate, values, namespace, WithReleaseName(defaultName)).Messages ch <- 1 }() select { diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 3aec094f3..d65375f26 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -45,12 +45,20 @@ var ( ) // Templates lints the templates in the Linter. -func Templates(linter *support.Linter, values map[string]interface{}, namespace string, _ bool, opts ...TemplateOption) { - TemplatesWithKubeVersion(linter, values, namespace, nil, opts...) +// Deprecated, use TemplatesV2 instead. +func Templates(linter *support.Linter, values map[string]interface{}, namespace string, _ bool) { + TemplatesV2(linter, values, 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, opts ...TemplateOption) { +// Deprecated, use TemplatesV2 instead. +func TemplatesWithKubeVersion(linter *support.Linter, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion) { + linter.KubeVersion = kubeVersion + TemplatesV2(linter, values, namespace) +} + +// TemplatesV2 lints the templates in the Linter. +func TemplatesV2(linter *support.Linter, values map[string]interface{}, namespace string) { fpath := "templates/" templatesPath := filepath.Join(linter.ChartDir, fpath) @@ -70,19 +78,14 @@ func TemplatesWithKubeVersion(linter *support.Linter, values map[string]interfac return } - o := defaultTemplateOptions - for _, optFn := range opts { - optFn(o) - } - options := chartutil.ReleaseOptions{ - Name: o.releaseName, + Name: linter.ReleaseName, Namespace: namespace, } caps := chartutil.DefaultCapabilities.Copy() - if kubeVersion != nil { - caps.KubeVersion = *kubeVersion + if linter.KubeVersion != nil { + caps.KubeVersion = *linter.KubeVersion } // lint ignores import-values @@ -166,7 +169,7 @@ func TemplatesWithKubeVersion(linter *support.Linter, values map[string]interfac // NOTE: set to warnings to allow users to support out-of-date kubernetes // Refs https://github.com/helm/helm/issues/8596 linter.RunLinterRule(support.WarningSev, fpath, validateMetadataName(yamlStruct)) - linter.RunLinterRule(support.WarningSev, fpath, validateNoDeprecations(yamlStruct, kubeVersion)) + linter.RunLinterRule(support.WarningSev, fpath, validateNoDeprecations(yamlStruct, linter.KubeVersion)) linter.RunLinterRule(support.ErrorSev, fpath, validateMatchSelector(yamlStruct, renderedContent)) linter.RunLinterRule(support.ErrorSev, fpath, validateListAnnotations(yamlStruct, renderedContent)) diff --git a/pkg/lint/rules/template_options.go b/pkg/lint/rules/template_options.go deleted file mode 100644 index 203801fa5..000000000 --- a/pkg/lint/rules/template_options.go +++ /dev/null @@ -1,20 +0,0 @@ -package rules - -type ( - templateOptions struct { - releaseName string - } - - TemplateOption func(o *templateOptions) -) - -var defaultTemplateOptions = &templateOptions{ - releaseName: "test-release", -} - -// WithReleaseName specify release name for linter -func WithReleaseName(name string) TemplateOption { - return func(o *templateOptions) { - o.releaseName = name - } -} diff --git a/pkg/lint/rules/template_test.go b/pkg/lint/rules/template_test.go index 7086a6c3b..ebf19df63 100644 --- a/pkg/lint/rules/template_test.go +++ b/pkg/lint/rules/template_test.go @@ -51,11 +51,10 @@ var values = map[string]interface{}{"nameOverride": "", "httpPort": 80} const defaultName = "test-release" const namespace = "testNamespace" -const strict = false func TestTemplateParsing(t *testing.T) { - linter := support.Linter{ChartDir: templateTestBasedir} - Templates(&linter, values, defaultName, namespace, strict) + linter := support.Linter{ChartDir: templateTestBasedir, ReleaseName: defaultName} + TemplatesV2(&linter, values, namespace) res := linter.Messages if len(res) != 1 { @@ -77,8 +76,8 @@ func TestTemplateIntegrationHappyPath(t *testing.T) { os.Rename(wrongTemplatePath, ignoredTemplatePath) defer os.Rename(ignoredTemplatePath, wrongTemplatePath) - linter := support.Linter{ChartDir: templateTestBasedir} - Templates(&linter, values, defaultName, namespace, strict) + linter := support.Linter{ChartDir: templateTestBasedir, ReleaseName: defaultName} + TemplatesV2(&linter, values, namespace) res := linter.Messages if len(res) != 0 { @@ -87,8 +86,8 @@ func TestTemplateIntegrationHappyPath(t *testing.T) { } func TestV3Fail(t *testing.T) { - linter := support.Linter{ChartDir: "./testdata/v3-fail"} - Templates(&linter, values, defaultName, namespace, strict) + linter := support.Linter{ChartDir: "./testdata/v3-fail", ReleaseName: defaultName} + TemplatesV2(&linter, values, namespace) res := linter.Messages if len(res) != 3 { @@ -107,8 +106,8 @@ func TestV3Fail(t *testing.T) { } func TestMultiTemplateFail(t *testing.T) { - linter := support.Linter{ChartDir: "./testdata/multi-template-fail"} - Templates(&linter, values, defaultName, namespace, strict) + linter := support.Linter{ChartDir: "./testdata/multi-template-fail", ReleaseName: defaultName} + TemplatesV2(&linter, values, namespace) res := linter.Messages if len(res) != 1 { @@ -227,8 +226,8 @@ func TestDeprecatedAPIFails(t *testing.T) { t.Fatal(err) } - linter := support.Linter{ChartDir: filepath.Join(tmpdir, mychart.Name())} - Templates(&linter, values, defaultName, namespace, strict) + linter := support.Linter{ChartDir: filepath.Join(tmpdir, mychart.Name()), ReleaseName: defaultName} + TemplatesV2(&linter, values, namespace) if l := len(linter.Messages); l != 1 { for i, msg := range linter.Messages { t.Logf("Message %d: %s", i, msg) @@ -282,9 +281,10 @@ func TestStrictTemplateParsingMapError(t *testing.T) { t.Fatal(err) } linter := &support.Linter{ - ChartDir: filepath.Join(dir, ch.Metadata.Name), + ChartDir: filepath.Join(dir, ch.Metadata.Name), + ReleaseName: defaultName, } - Templates(linter, ch.Values, defaultName, namespace, strict) + TemplatesV2(linter, ch.Values, namespace) if len(linter.Messages) != 0 { t.Errorf("expected zero messages, got %d", len(linter.Messages)) for i, msg := range linter.Messages { @@ -412,8 +412,8 @@ func TestEmptyWithCommentsManifests(t *testing.T) { t.Fatal(err) } - linter := support.Linter{ChartDir: filepath.Join(tmpdir, mychart.Name())} - Templates(&linter, values, defaultName, namespace, strict) + linter := support.Linter{ChartDir: filepath.Join(tmpdir, mychart.Name()), ReleaseName: defaultName} + TemplatesV2(&linter, values, namespace) if l := len(linter.Messages); l > 0 { for i, msg := range linter.Messages { t.Logf("Message %d: %s", i, msg) diff --git a/pkg/lint/support/message.go b/pkg/lint/support/message.go index 5efbc7a61..ef429b8da 100644 --- a/pkg/lint/support/message.go +++ b/pkg/lint/support/message.go @@ -16,7 +16,11 @@ limitations under the License. package support -import "fmt" +import ( + "fmt" + + "helm.sh/helm/v3/pkg/chartutil" +) // Severity indicates the severity of a Message. const ( @@ -39,6 +43,8 @@ type Linter struct { // The highest severity of all the failing lint rules HighestSeverity int ChartDir string + ReleaseName string + KubeVersion *chartutil.KubeVersion } // Message describes an error encountered while linting. From 7c540ce1438b94c58b4cf90c46e2febe18678a7a Mon Sep 17 00:00:00 2001 From: bartem Date: Wed, 20 Mar 2024 20:54:12 +0300 Subject: [PATCH 4/4] remove extra param Signed-off-by: bartem --- pkg/lint/lint.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/lint/lint.go b/pkg/lint/lint.go index cf7f4b041..2f02faa7e 100644 --- a/pkg/lint/lint.go +++ b/pkg/lint/lint.go @@ -27,7 +27,7 @@ import ( // All runs all of the available linters on the given base directory. // Deprecated, use AllWithOptions instead. func All(basedir string, values map[string]interface{}, namespace string, _ bool) support.Linter { - return AllWithOptions(basedir, values, namespace, nil) + return AllWithOptions(basedir, values, namespace) } // AllWithKubeVersion runs all the available linters on the given base directory, allowing to specify the kubernetes version.