refactoring

Signed-off-by: bartem <bartem@ozon.ru>
pull/12280/head
bartem 2 years ago
parent a9694a1dcc
commit 799f34f673

@ -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
}

@ -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
}

@ -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
}
}

@ -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 {

@ -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))

@ -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
}
}

@ -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)
@ -283,8 +282,9 @@ func TestStrictTemplateParsingMapError(t *testing.T) {
}
linter := &support.Linter{
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)

@ -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.

Loading…
Cancel
Save