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