diff --git a/cmd/helm/template.go b/cmd/helm/template.go index bd14cde1d..a4438b50c 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -22,6 +22,7 @@ import ( "io" "path/filepath" "regexp" + "sort" "strings" "github.com/spf13/cobra" @@ -86,12 +87,21 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { // if we have a list of files to render, then check that each of the // provided files exists in the chart. if len(showFiles) > 0 { + // This is necessary to ensure consistent manifest ordering when using --show-only + // with globs or directory names. splitManifests := releaseutil.SplitManifests(manifests.String()) + manifestsKeys := make([]string, 0, len(splitManifests)) + for k := range splitManifests { + manifestsKeys = append(manifestsKeys, k) + } + sort.Sort(releaseutil.BySplitManifestsOrder(manifestsKeys)) + manifestNameRegex := regexp.MustCompile("# Source: [^/]+/(.+)") var manifestsToRender []string for _, f := range showFiles { missing := true - for _, manifest := range splitManifests { + for _, manifestKey := range manifestsKeys { + manifest := splitManifests[manifestKey] submatch := manifestNameRegex.FindStringSubmatch(manifest) if len(submatch) == 0 { continue @@ -104,10 +114,11 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { // if the filepath provided matches a manifest path in the // chart, render that manifest - if f == manifestPath { - manifestsToRender = append(manifestsToRender, manifest) - missing = false + if matched, _ := filepath.Match(f, manifestPath); !matched { + continue } + manifestsToRender = append(manifestsToRender, manifest) + missing = false } if missing { return fmt.Errorf("could not find template %s in chart", f) diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index 3fd139fad..87ee79e5a 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -94,6 +94,13 @@ func TestTemplateCmd(t *testing.T) { cmd: fmt.Sprintf("template '%s' --show-only templates/service.yaml --show-only charts/subcharta/templates/service.yaml", chartPath), golden: "output/template-show-only-multiple.txt", }, + { + name: "template with show-only glob", + cmd: fmt.Sprintf("template '%s' --show-only templates/subdir/role*", chartPath), + golden: "output/template-show-only-glob.txt", + // Repeat to ensure manifest ordering regressions are caught + repeat: 10, + }, { name: "sorted output of manifests (order of filenames, then order of objects within each YAML file)", cmd: fmt.Sprintf("template '%s'", "testdata/testcharts/object-order"), diff --git a/cmd/helm/testdata/output/template-name-template.txt b/cmd/helm/testdata/output/template-name-template.txt index acba50360..0130a2a92 100644 --- a/cmd/helm/testdata/output/template-name-template.txt +++ b/cmd/helm/testdata/output/template-name-template.txt @@ -1,4 +1,33 @@ --- +# Source: subchart1/templates/subdir/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: subchart1-sa +--- +# Source: subchart1/templates/subdir/role.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: subchart1-role +rules: +- resources: ["*"] + verbs: ["get","list","watch"] +--- +# Source: subchart1/templates/subdir/rolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: subchart1-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: subchart1-role +subjects: +- kind: ServiceAccount + name: subchart1-sa + namespace: default +--- # Source: subchart1/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service diff --git a/cmd/helm/testdata/output/template-set.txt b/cmd/helm/testdata/output/template-set.txt index b0924b5b6..ddaa8886b 100644 --- a/cmd/helm/testdata/output/template-set.txt +++ b/cmd/helm/testdata/output/template-set.txt @@ -1,4 +1,33 @@ --- +# Source: subchart1/templates/subdir/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: subchart1-sa +--- +# Source: subchart1/templates/subdir/role.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: subchart1-role +rules: +- resources: ["*"] + verbs: ["get","list","watch"] +--- +# Source: subchart1/templates/subdir/rolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: subchart1-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: subchart1-role +subjects: +- kind: ServiceAccount + name: subchart1-sa + namespace: default +--- # Source: subchart1/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service diff --git a/cmd/helm/testdata/output/template-show-only-glob.txt b/cmd/helm/testdata/output/template-show-only-glob.txt new file mode 100644 index 000000000..0970e6cd3 --- /dev/null +++ b/cmd/helm/testdata/output/template-show-only-glob.txt @@ -0,0 +1,23 @@ +--- +# Source: subchart1/templates/subdir/role.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: subchart1-role +rules: +- resources: ["*"] + verbs: ["get","list","watch"] +--- +# Source: subchart1/templates/subdir/rolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: subchart1-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: subchart1-role +subjects: +- kind: ServiceAccount + name: subchart1-sa + namespace: default diff --git a/cmd/helm/testdata/output/template-values-files.txt b/cmd/helm/testdata/output/template-values-files.txt index b0924b5b6..ddaa8886b 100644 --- a/cmd/helm/testdata/output/template-values-files.txt +++ b/cmd/helm/testdata/output/template-values-files.txt @@ -1,4 +1,33 @@ --- +# Source: subchart1/templates/subdir/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: subchart1-sa +--- +# Source: subchart1/templates/subdir/role.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: subchart1-role +rules: +- resources: ["*"] + verbs: ["get","list","watch"] +--- +# Source: subchart1/templates/subdir/rolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: subchart1-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: subchart1-role +subjects: +- kind: ServiceAccount + name: subchart1-sa + namespace: default +--- # Source: subchart1/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service diff --git a/cmd/helm/testdata/output/template-with-api-version.txt b/cmd/helm/testdata/output/template-with-api-version.txt index da3559082..7a2a4d5bf 100644 --- a/cmd/helm/testdata/output/template-with-api-version.txt +++ b/cmd/helm/testdata/output/template-with-api-version.txt @@ -1,4 +1,33 @@ --- +# Source: subchart1/templates/subdir/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: subchart1-sa +--- +# Source: subchart1/templates/subdir/role.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: subchart1-role +rules: +- resources: ["*"] + verbs: ["get","list","watch"] +--- +# Source: subchart1/templates/subdir/rolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: subchart1-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: subchart1-role +subjects: +- kind: ServiceAccount + name: subchart1-sa + namespace: default +--- # Source: subchart1/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service diff --git a/cmd/helm/testdata/output/template-with-crds.txt b/cmd/helm/testdata/output/template-with-crds.txt index 9fa1c7e6d..b04a4d5d2 100644 --- a/cmd/helm/testdata/output/template-with-crds.txt +++ b/cmd/helm/testdata/output/template-with-crds.txt @@ -15,6 +15,35 @@ spec: singular: authconfig --- +# Source: subchart1/templates/subdir/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: subchart1-sa +--- +# Source: subchart1/templates/subdir/role.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: subchart1-role +rules: +- resources: ["*"] + verbs: ["get","list","watch"] +--- +# Source: subchart1/templates/subdir/rolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: subchart1-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: subchart1-role +subjects: +- kind: ServiceAccount + name: subchart1-sa + namespace: default +--- # Source: subchart1/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service diff --git a/cmd/helm/testdata/output/template.txt b/cmd/helm/testdata/output/template.txt index 080be618c..8301c2231 100644 --- a/cmd/helm/testdata/output/template.txt +++ b/cmd/helm/testdata/output/template.txt @@ -1,4 +1,33 @@ --- +# Source: subchart1/templates/subdir/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: subchart1-sa +--- +# Source: subchart1/templates/subdir/role.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: subchart1-role +rules: +- resources: ["*"] + verbs: ["get","list","watch"] +--- +# Source: subchart1/templates/subdir/rolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: subchart1-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: subchart1-role +subjects: +- kind: ServiceAccount + name: subchart1-sa + namespace: default +--- # Source: subchart1/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service diff --git a/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/role.yaml b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/role.yaml new file mode 100644 index 000000000..91b954e5f --- /dev/null +++ b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/role.yaml @@ -0,0 +1,7 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ .Chart.Name }}-role +rules: +- resources: ["*"] + verbs: ["get","list","watch"] diff --git a/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/rolebinding.yaml b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/rolebinding.yaml new file mode 100644 index 000000000..5d193f1a6 --- /dev/null +++ b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/rolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .Chart.Name }}-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ .Chart.Name }}-role +subjects: +- kind: ServiceAccount + name: {{ .Chart.Name }}-sa + namespace: default diff --git a/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/serviceaccount.yaml b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/serviceaccount.yaml new file mode 100644 index 000000000..7126c7d89 --- /dev/null +++ b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/serviceaccount.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Chart.Name }}-sa