From d41ca72e425c529896632e3cf4b98e2972e3dbd2 Mon Sep 17 00:00:00 2001
From: liaoj <jliao@alauda.io>
Date: Wed, 7 Nov 2018 12:50:05 +0800
Subject: [PATCH] fix:#4873, check release name (#4883)

for command helm template and helm install
when cusotmer input invalid release name, return a error

Signed-off-by: jliao <jliao@alauda.io>
---
 cmd/helm/install.go        |  5 +++++
 cmd/helm/install_test.go   | 32 +++++++++++++++++++++++++++++---
 cmd/helm/template.go       |  7 ++++++-
 cmd/helm/template_test.go  | 31 +++++++++++++++++++++++++++++--
 docs/helm/helm_template.md |  2 +-
 5 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/cmd/helm/install.go b/cmd/helm/install.go
index c5c6b9a49..05321f1f7 100644
--- a/cmd/helm/install.go
+++ b/cmd/helm/install.go
@@ -32,6 +32,7 @@ import (
 	"github.com/ghodss/yaml"
 	"github.com/spf13/cobra"
 
+	"k8s.io/apimachinery/pkg/util/validation"
 	"k8s.io/helm/pkg/chartutil"
 	"k8s.io/helm/pkg/downloader"
 	"k8s.io/helm/pkg/getter"
@@ -248,6 +249,10 @@ func (i *installCmd) run() error {
 		fmt.Printf("FINAL NAME: %s\n", i.name)
 	}
 
+	if msgs := validation.IsDNS1123Label(i.name); i.name != "" && len(msgs) > 0 {
+		return fmt.Errorf("release name %s is not a valid DNS label: %s", i.name, strings.Join(msgs, ";"))
+	}
+
 	// Check chart requirements to make sure all dependencies are present in /charts
 	chartRequested, err := chartutil.Load(i.chartPath)
 	if err != nil {
diff --git a/cmd/helm/install_test.go b/cmd/helm/install_test.go
index 48d9fc8c1..168c53fed 100644
--- a/cmd/helm/install_test.go
+++ b/cmd/helm/install_test.go
@@ -111,9 +111,9 @@ func TestInstall(t *testing.T) {
 		{
 			name:     "install with name-template",
 			args:     []string{"testdata/testcharts/alpine"},
-			flags:    []string{"--name-template", "{{upper \"foobar\"}}"},
-			expected: "FOOBAR",
-			resp:     helm.ReleaseMock(&helm.MockReleaseOptions{Name: "FOOBAR"}),
+			flags:    []string{"--name-template", "{{lower \"FOOBAR\"}}"},
+			expected: "foobar",
+			resp:     helm.ReleaseMock(&helm.MockReleaseOptions{Name: "foobar"}),
 		},
 		{
 			name:     "install with custom description",
@@ -152,6 +152,32 @@ func TestInstall(t *testing.T) {
 			args: []string{"testdata/testcharts/chart-bad-requirements"},
 			err:  true,
 		},
+		// Install, using a bad release name
+		{
+			name:  "install chart with release name using capitals",
+			args:  []string{"testdata/testcharts/alpine"},
+			flags: []string{"--name", "FOO"},
+			err:   true,
+		},
+		{
+			name:  "install chart with release name using periods",
+			args:  []string{"testdata/testcharts/alpine"},
+			flags: []string{"--name", "foo.bar"},
+			err:   true,
+		},
+		{
+			name:  "install chart with release name using underscores",
+			args:  []string{"testdata/testcharts/alpine"},
+			flags: []string{"--name", "foo_bar"},
+			err:   true,
+		},
+		// Install, using a bad name-template
+		{
+			name:  "install with name-template",
+			args:  []string{"testdata/testcharts/alpine"},
+			flags: []string{"--name-template", "{{UPPER \"foobar\"}}"},
+			err:   true,
+		},
 	}
 
 	runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command {
diff --git a/cmd/helm/template.go b/cmd/helm/template.go
index 63609c18c..d776f2989 100644
--- a/cmd/helm/template.go
+++ b/cmd/helm/template.go
@@ -29,6 +29,7 @@ import (
 
 	"github.com/spf13/cobra"
 
+	"k8s.io/apimachinery/pkg/util/validation"
 	"k8s.io/helm/pkg/chartutil"
 	"k8s.io/helm/pkg/manifest"
 	"k8s.io/helm/pkg/proto/hapi/chart"
@@ -92,7 +93,7 @@ func newTemplateCmd(out io.Writer) *cobra.Command {
 
 	f := cmd.Flags()
 	f.BoolVar(&t.showNotes, "notes", false, "show the computed NOTES.txt file as well")
-	f.StringVarP(&t.releaseName, "name", "n", "RELEASE-NAME", "release name")
+	f.StringVarP(&t.releaseName, "name", "n", "release-name", "release name")
 	f.BoolVar(&t.releaseIsUpgrade, "is-upgrade", false, "set .Release.IsUpgrade instead of .Release.IsInstall")
 	f.StringArrayVarP(&t.renderFiles, "execute", "x", []string{}, "only execute the given templates")
 	f.VarP(&t.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
@@ -146,6 +147,10 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
 		}
 	}
 
+	if msgs := validation.IsDNS1123Label(t.releaseName); t.releaseName != "" && len(msgs) > 0 {
+		return fmt.Errorf("release name %s is not a valid DNS label: %s", t.releaseName, strings.Join(msgs, ";"))
+	}
+
 	// Check chart requirements to make sure all dependencies are present in /charts
 	c, err := chartutil.Load(t.chartPath)
 	if err != nil {
diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go
index 64924c2f2..ec989ea67 100644
--- a/cmd/helm/template_test.go
+++ b/cmd/helm/template_test.go
@@ -107,6 +107,27 @@ func TestTemplateCmd(t *testing.T) {
 			expectKey:   "subchart1/templates/service.yaml",
 			expectValue: "release-name: \"test\"",
 		},
+		{
+			name:        "check_invalid_name_uppercase",
+			desc:        "verify the release name using capitals is invalid",
+			args:        []string{subchart1ChartPath, "--name", "FOO"},
+			expectKey:   "subchart1/templates/service.yaml",
+			expectError: "is not a valid DNS label",
+		},
+		{
+			name:        "check_invalid_name_uppercase",
+			desc:        "verify the release name using periods is invalid",
+			args:        []string{subchart1ChartPath, "--name", "foo.bar"},
+			expectKey:   "subchart1/templates/service.yaml",
+			expectError: "is not a valid DNS label",
+		},
+		{
+			name:        "check_invalid_name_uppercase",
+			desc:        "verify the release name using underscores is invalid",
+			args:        []string{subchart1ChartPath, "--name", "foo_bar"},
+			expectKey:   "subchart1/templates/service.yaml",
+			expectError: "is not a valid DNS label",
+		},
 		{
 			name:        "check_release_is_install",
 			desc:        "verify --is-upgrade toggles .Release.IsInstall",
@@ -135,12 +156,18 @@ func TestTemplateCmd(t *testing.T) {
 			expectKey:   "subchart1/templates/service.yaml",
 			expectValue: "name: apache",
 		},
+		{
+			name:        "check_invalid_name_template",
+			desc:        "verify the relase name generate by template is invalid",
+			args:        []string{subchart1ChartPath, "--name-template", "foobar-{{ b64enc \"abc\" }}-baz"},
+			expectError: "is not a valid DNS label",
+		},
 		{
 			name:        "check_name_template",
 			desc:        "verify --name-template result exists",
-			args:        []string{subchart1ChartPath, "--name-template", "foobar-{{ b64enc \"abc\" }}-baz"},
+			args:        []string{subchart1ChartPath, "--name-template", "foobar-{{ lower \"ABC\" }}-baz"},
 			expectKey:   "subchart1/templates/service.yaml",
-			expectValue: "release-name: \"foobar-YWJj-baz\"",
+			expectValue: "release-name: \"foobar-abc-baz\"",
 		},
 		{
 			name:        "check_kube_version",
diff --git a/docs/helm/helm_template.md b/docs/helm/helm_template.md
index d7770fb7f..805556096 100644
--- a/docs/helm/helm_template.md
+++ b/docs/helm/helm_template.md
@@ -28,7 +28,7 @@ helm template [flags] CHART
   -h, --help                     help for template
       --is-upgrade               set .Release.IsUpgrade instead of .Release.IsInstall
       --kube-version string      kubernetes version used as Capabilities.KubeVersion.Major/Minor (default "1.9")
-  -n, --name string              release name (default "RELEASE-NAME")
+  -n, --name string              release name (default "release-name")
       --name-template string     specify template used to name the release
       --namespace string         namespace to install the release into
       --notes                    show the computed NOTES.txt file as well
-- 
GitLab