Unverified Commit 30f236b7 authored by Nikhil Manchanda's avatar Nikhil Manchanda Committed by GitHub

Merge pull request #3877 from chancez/enhance_helm_template_handling

Update helm template -x to support children chart manifests in more cases
parents 28d87e17 fb1dd48b
......@@ -117,31 +117,10 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
} else {
return err
}
// verify specified templates exist relative to chart
rf := []string{}
var af string
var err error
if len(t.renderFiles) > 0 {
for _, f := range t.renderFiles {
if !filepath.IsAbs(f) {
af, err = filepath.Abs(filepath.Join(t.chartPath, f))
if err != nil {
return fmt.Errorf("could not resolve template path: %s", err)
}
} else {
af = f
}
rf = append(rf, af)
if _, err := os.Stat(af); err != nil {
return fmt.Errorf("could not resolve template path: %s", err)
}
}
}
// verify that output-dir exists if provided
if t.outputDir != "" {
_, err = os.Stat(t.outputDir)
_, err := os.Stat(t.outputDir)
if os.IsNotExist(err) {
return fmt.Errorf("output-dir '%s' does not exist", t.outputDir)
}
......@@ -232,19 +211,7 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
m := tiller.Manifest{Name: k, Content: v, Head: &util.SimpleHead{Kind: h}}
listManifests = append(listManifests, m)
}
in := func(needle string, haystack []string) bool {
// make needle path absolute
d := strings.Split(needle, string(os.PathSeparator))
dd := d[1:]
an := filepath.Join(t.chartPath, strings.Join(dd, string(os.PathSeparator)))
for _, h := range haystack {
if h == an {
return true
}
}
return false
}
if settings.Debug {
rel := &release.Release{
Name: t.releaseName,
......@@ -257,10 +224,45 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
printRelease(os.Stdout, rel)
}
for _, m := range tiller.SortByKind(listManifests) {
if len(t.renderFiles) > 0 && !in(m.Name, rf) {
continue
var manifestsToRender []tiller.Manifest
// if we have a list of files to render, then check that each of the
// provided files exists in the chart.
if len(t.renderFiles) > 0 {
for _, f := range t.renderFiles {
missing := true
if !filepath.IsAbs(f) {
newF, err := filepath.Abs(filepath.Join(t.chartPath, f))
if err != nil {
return fmt.Errorf("could not turn template path %s into absolute path: %s", f, err)
}
f = newF
}
for _, manifest := range listManifests {
manifestPathSplit := strings.Split(manifest.Name, string(filepath.Separator))
// remove the chart name from the path
manifestPathSplit = manifestPathSplit[1:]
toJoin := append([]string{t.chartPath}, manifestPathSplit...)
manifestPath := filepath.Join(toJoin...)
// if the filepath provided matches a manifest path in the
// chart, render that manifest
if f == manifestPath {
manifestsToRender = append(manifestsToRender, manifest)
missing = false
}
}
if missing {
return fmt.Errorf("could not find template %s in chart", f)
}
}
} else {
// no renderFiles provided, render all manifests in the chart
manifestsToRender = listManifests
}
for _, m := range tiller.SortByKind(manifestsToRender) {
data := m.Content
b := filepath.Base(m.Name)
if !t.showNotes && b == "NOTES.txt" {
......
......@@ -27,10 +27,13 @@ import (
"testing"
)
var chartPath = "./../../pkg/chartutil/testdata/subpop/charts/subchart1"
var (
subchart1ChartPath = "./../../pkg/chartutil/testdata/subpop/charts/subchart1"
frobnitzChartPath = "./../../pkg/chartutil/testdata/frobnitz"
)
func TestTemplateCmd(t *testing.T) {
absChartPath, err := filepath.Abs(chartPath)
subchart1AbsChartPath, err := filepath.Abs(subchart1ChartPath)
if err != nil {
t.Fatal(err)
}
......@@ -40,74 +43,95 @@ func TestTemplateCmd(t *testing.T) {
args []string
expectKey string
expectValue string
expectError string
}{
{
name: "check_name",
desc: "check for a known name in chart",
args: []string{chartPath},
args: []string{subchart1ChartPath},
expectKey: "subchart1/templates/service.yaml",
expectValue: "protocol: TCP\n name: nginx",
},
{
name: "check_set_name",
desc: "verify --set values exist",
args: []string{chartPath, "-x", "templates/service.yaml", "--set", "service.name=apache"},
args: []string{subchart1ChartPath, "-x", "templates/service.yaml", "--set", "service.name=apache"},
expectKey: "subchart1/templates/service.yaml",
expectValue: "protocol: TCP\n name: apache",
},
{
name: "check_execute",
desc: "verify --execute single template",
args: []string{chartPath, "-x", "templates/service.yaml", "--set", "service.name=apache"},
args: []string{subchart1ChartPath, "-x", "templates/service.yaml", "--set", "service.name=apache"},
expectKey: "subchart1/templates/service.yaml",
expectValue: "protocol: TCP\n name: apache",
},
{
name: "check_execute_non_existent",
desc: "verify --execute fails on a template that doesnt exist",
args: []string{subchart1ChartPath, "-x", "templates/thisdoesntexist.yaml"},
expectError: "could not find template",
},
{
name: "check_execute_absolute",
desc: "verify --execute single template",
args: []string{chartPath, "-x", absChartPath + "/" + "templates/service.yaml", "--set", "service.name=apache"},
args: []string{subchart1ChartPath, "-x", subchart1AbsChartPath + "/" + "templates/service.yaml", "--set", "service.name=apache"},
expectKey: "subchart1/templates/service.yaml",
expectValue: "protocol: TCP\n name: apache",
},
{
name: "check_execute_subchart_template",
desc: "verify --execute single template on a subchart template",
args: []string{subchart1ChartPath, "-x", "charts/subcharta/templates/service.yaml", "--set", "subcharta.service.name=foobar"},
expectKey: "subchart1/charts/subcharta/templates/service.yaml",
expectValue: "protocol: TCP\n name: foobar",
},
{
name: "check_execute_subchart_template_for_tgz_subchart",
desc: "verify --execute single template on a subchart template where the subchart is a .tgz in the chart directory",
args: []string{frobnitzChartPath, "-x", "charts/mariner/templates/placeholder.tpl", "--set", "mariner.name=moon"},
expectKey: "frobnitz/charts/mariner/templates/placeholder.tpl",
expectValue: "Goodbye moon",
},
{
name: "check_namespace",
desc: "verify --namespace",
args: []string{chartPath, "--namespace", "test"},
args: []string{subchart1ChartPath, "--namespace", "test"},
expectKey: "subchart1/templates/service.yaml",
expectValue: "namespace: \"test\"",
},
{
name: "check_release_name",
desc: "verify --release exists",
args: []string{chartPath, "--name", "test"},
args: []string{subchart1ChartPath, "--name", "test"},
expectKey: "subchart1/templates/service.yaml",
expectValue: "release-name: \"test\"",
},
{
name: "check_notes",
desc: "verify --notes shows notes",
args: []string{chartPath, "--notes", "true"},
args: []string{subchart1ChartPath, "--notes", "true"},
expectKey: "subchart1/templates/NOTES.txt",
expectValue: "Sample notes for subchart1",
},
{
name: "check_values_files",
desc: "verify --values files values exist",
args: []string{chartPath, "--values", chartPath + "/charts/subchartA/values.yaml"},
args: []string{subchart1ChartPath, "--values", subchart1ChartPath + "/charts/subchartA/values.yaml"},
expectKey: "subchart1/templates/service.yaml",
expectValue: "name: apache",
},
{
name: "check_name_template",
desc: "verify --name-template result exists",
args: []string{chartPath, "--name-template", "foobar-{{ b64enc \"abc\" }}-baz"},
args: []string{subchart1ChartPath, "--name-template", "foobar-{{ b64enc \"abc\" }}-baz"},
expectKey: "subchart1/templates/service.yaml",
expectValue: "release-name: \"foobar-YWJj-baz\"",
},
{
name: "check_kube_version",
desc: "verify --kube-version overrides the kubernetes version",
args: []string{chartPath, "--kube-version", "1.6"},
args: []string{subchart1ChartPath, "--kube-version", "1.6"},
expectKey: "subchart1/templates/service.yaml",
expectValue: "kube-version/major: \"1\"\n kube-version/minor: \"6\"\n kube-version/gitversion: \"v1.6.0\"",
},
......@@ -115,7 +139,8 @@ func TestTemplateCmd(t *testing.T) {
var buf bytes.Buffer
for _, tt := range tests {
t.Run(tt.name, func(T *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
// capture stdout
old := os.Stdout
r, w, _ := os.Pipe()
......@@ -125,8 +150,21 @@ func TestTemplateCmd(t *testing.T) {
cmd := newTemplateCmd(out)
cmd.SetArgs(tt.args)
err := cmd.Execute()
if err != nil {
t.Errorf("expected: %v, got %v", tt.expectValue, err)
if tt.expectError != "" {
if err == nil {
t.Errorf("expected err: %s, but no error occurred", tt.expectError)
}
// non nil error, check if it contains the expected error
if strings.Contains(err.Error(), tt.expectError) {
// had the error we were looking for, this test case is
// done
return
} else {
t.Fatalf("expected err: %q, got: %q", tt.expectError, err)
}
} else if err != nil {
t.Errorf("expected no error, got %v", err)
}
// restore stdout
w.Close()
......
# This is a placeholder.
Goodbye {{.Values.name | default "world"}}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment