diff --git a/cmd/helm/lint_test.go b/cmd/helm/lint_test.go index 42487a34f..7f68ad99f 100644 --- a/cmd/helm/lint_test.go +++ b/cmd/helm/lint_test.go @@ -107,3 +107,45 @@ func TestLinRunForNonExistentChart(t *testing.T) { } }) } + +func TestLintRunForStrictErrors(t *testing.T) { + out := bytes.NewBufferString("") + tests := []struct { + name string + chartPath string + strict bool + errStr string + wantErr bool + }{ + { + name: "non-strict should not error", + chartPath: "testdata/testcharts/bad.name", + strict: false, + wantErr: false, + }, + { + name: "strict should error", + chartPath: "testdata/testcharts/bad.name", + strict: true, + errStr: "1 chart(s) linted, 1 chart(s) failed", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + testLint := &lintCmd{ + paths: []string{tt.chartPath}, + strict: tt.strict, + out: out, + } + expectedErr := fmt.Errorf(tt.errStr) + err := testLint.run() + if tt.wantErr && err == nil { + t.Errorf("expected error but got no error") + } + if err != nil && (err.Error() != expectedErr.Error()) { + t.Errorf("expected: \"%v\" , but got: \"%v\"", expectedErr, err) + } + }) + } +} diff --git a/cmd/helm/testdata/testcharts/bad.name/Chart.yaml b/cmd/helm/testdata/testcharts/bad.name/Chart.yaml new file mode 100644 index 000000000..2554907db --- /dev/null +++ b/cmd/helm/testdata/testcharts/bad.name/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +appVersion: "1.0" +description: A Helm chart for Kubernetes +name: bad.name +version: 0.1.0 diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 26c548bac..f494540df 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -77,9 +77,6 @@ func Templates(linter *support.Linter, values []byte, namespace string, strict b } e := engine.New() e.LintMode = true - if strict { - e.Strict = true - } renderedContentMap, err := e.Render(chart, valuesToRender) renderOk := linter.RunLinterRule(support.ErrorSev, path, err) diff --git a/pkg/lint/rules/template_test.go b/pkg/lint/rules/template_test.go index a294d3c57..548a52edb 100644 --- a/pkg/lint/rules/template_test.go +++ b/pkg/lint/rules/template_test.go @@ -17,12 +17,15 @@ limitations under the License. package rules import ( + "io/ioutil" "os" "path/filepath" "strings" "testing" + "k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/lint/support" + "k8s.io/helm/pkg/proto/hapi/chart" ) const ( @@ -82,3 +85,58 @@ func TestTemplateIntegrationHappyPath(t *testing.T) { t.Fatalf("Expected no error, got %d, %v", len(res), res) } } + +// TestSTrictTemplatePrasingMapError is a regression test. +// +// The template engine should not produce an error when a map in values.yaml does +// not contain all possible keys. +// +// See https://github.com/helm/helm/issues/7483 (helm v3) +// and https://github.com/helm/helm/issues/6705 (helm v2) +func TestStrictTemplateParsingMapError(t *testing.T) { + dir, err := ioutil.TempDir("", "helm-test-") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + var vals = []byte(` +mymap: + key1: nestedValue +`) + var manifest = `apiVersion: v1 +kind: ConfigMap +metadata: + name: foo +data: + myval1: {{default "val" .Values.mymap.key1 }} + myval2: {{default "val" .Values.mymap.key2 }} +` + ch := chart.Chart{ + Metadata: &chart.Metadata{ + Name: "regression.6705", + ApiVersion: "v1", + Version: "0.1.0", + }, + Templates: []*chart.Template{ + { + Name: "templates/configmap.yaml", + Data: []byte(manifest), + }, + }, + } + + if err := chartutil.SaveDir(&ch, dir); err != nil { + t.Fatal(err) + } + linter := &support.Linter{ + ChartDir: filepath.Join(dir, ch.Metadata.Name), + } + Templates(linter, vals, namespace, true) + if len(linter.Messages) != 0 { + t.Errorf("expected zero messages, got %d", len(linter.Messages)) + for i, msg := range linter.Messages { + t.Logf("Message %d: %q", i, msg) + } + } +}