Repository: helm/helm
Pull request #7138 (2019-12-03 19:10:24)

Add a flag to allow template to output CRDs
Addresses #6930 

Add an optional flag that will cause `helm template` to output CRDs along with the templated manifests.


Patch:
diff --git a/cmd/helm/template.go b/cmd/helm/template.go
index 5312d798f..b660cc69f 100644
--- a/cmd/helm/template.go
+++ b/cmd/helm/template.go
@@ -44,6 +44,7 @@ faked locally. Additionally, none of the server-side testing of chart validity
 
 func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 	var validate bool
+	var includeCrds bool
 	client := action.NewInstall(cfg)
 	valueOpts := &values.Options{}
 	var extraAPIs []string
@@ -67,7 +68,14 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 
 			var manifests bytes.Buffer
 
+			if includeCrds {
+				for _, f := range rel.Chart.CRDs() {
+					fmt.Fprintf(&manifests, "---\n# Source: %s\n%s\n", f.Name, f.Data)
+				}
+			}
+
 			fmt.Fprintln(&manifests, strings.TrimSpace(rel.Manifest))
+
 			if !client.DisableHooks {
 				for _, m := range rel.Hooks {
 					fmt.Fprintf(&manifests, "---\n# Source: %s\n%s\n", m.Path, m.Manifest)
@@ -120,6 +128,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 	f.StringArrayVarP(&showFiles, "show-only", "s", []string{}, "only show manifests rendered from the given templates")
 	f.StringVar(&client.OutputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout")
 	f.BoolVar(&validate, "validate", false, "validate your manifests against the Kubernetes cluster you are currently pointing at. This is the same validation performed on an install")
+	f.BoolVar(&includeCrds, "include-crds", false, "include CRDs in the templated output")
 	f.StringArrayVarP(&extraAPIs, "api-versions", "a", []string{}, "Kubernetes api versions used for Capabilities.APIVersions")
 
 	return cmd


Test patch:
diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go
index 8aa2f6c06..735829432 100644
--- a/cmd/helm/template_test.go
+++ b/cmd/helm/template_test.go
@@ -79,6 +79,11 @@ func TestTemplateCmd(t *testing.T) {
 			cmd:    fmt.Sprintf("template --api-versions helm.k8s.io/test '%s'", chartPath),
 			golden: "output/template-with-api-version.txt",
 		},
+		{
+			name:   "template with CRDs",
+			cmd:    fmt.Sprintf("template '%s' --include-crds", chartPath),
+			golden: "output/template-with-crds.txt",
+		},
 	}
 	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/testdata/output/template-with-crds.txt b/cmd/helm/testdata/output/template-with-crds.txt
new file mode 100644
index 000000000..9fa1c7e6d
--- /dev/null
+++ b/cmd/helm/testdata/output/template-with-crds.txt
@@ -0,0 +1,72 @@
+---
+# Source: crds/crdA.yaml
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: testCRDs
+spec:
+  group: testCRDGroups
+  names:
+    kind: TestCRD
+    listKind: TestCRDList
+    plural: TestCRDs
+    shortNames:
+      - tc
+    singular: authconfig
+
+---
+# Source: subchart1/charts/subcharta/templates/service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  name: subcharta
+  labels:
+    helm.sh/chart: "subcharta-0.1.0"
+spec:
+  type: ClusterIP
+  ports:
+  - port: 80
+    targetPort: 80
+    protocol: TCP
+    name: apache
+  selector:
+    app.kubernetes.io/name: subcharta
+---
+# Source: subchart1/charts/subchartb/templates/service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  name: subchartb
+  labels:
+    helm.sh/chart: "subchartb-0.1.0"
+spec:
+  type: ClusterIP
+  ports:
+  - port: 80
+    targetPort: 80
+    protocol: TCP
+    name: nginx
+  selector:
+    app.kubernetes.io/name: subchartb
+---
+# Source: subchart1/templates/service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  name: subchart1
+  labels:
+    helm.sh/chart: "subchart1-0.1.0"
+    app.kubernetes.io/instance: "RELEASE-NAME"
+    kube-version/major: "1"
+    kube-version/minor: "16"
+    kube-version/version: "v1.16.0"
+    kube-api-version/test: v1
+spec:
+  type: ClusterIP
+  ports:
+  - port: 80
+    targetPort: 80
+    protocol: TCP
+    name: nginx
+  selector:
+    app.kubernetes.io/name: subchart1
diff --git a/pkg/chartutil/testdata/subpop/charts/subchart1/crds/crdA.yaml b/pkg/chartutil/testdata/subpop/charts/subchart1/crds/crdA.yaml
new file mode 100644
index 000000000..fca77fd4b
--- /dev/null
+++ b/pkg/chartutil/testdata/subpop/charts/subchart1/crds/crdA.yaml
@@ -0,0 +1,13 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: testCRDs
+spec:
+  group: testCRDGroups
+  names:
+    kind: TestCRD
+    listKind: TestCRDList
+    plural: TestCRDs
+    shortNames:
+      - tc
+    singular: authconfig