From 18a57ce30fb39563843b5c51614b31441e8685eb Mon Sep 17 00:00:00 2001 From: Andreas Bieber Date: Tue, 24 Apr 2018 16:16:11 +0200 Subject: [PATCH] feat(helm): add --with-subcharts option for "helm inspect values" Running helm inspect values [CHART] outputs the contents of a chart's values.yaml verbatim. This is often used to determine which configuration options a chart exposes. However, it does not provide the contents of values.yaml files of potential subcharts bundled in the charts subdirectory. The new command-line option --with-subcharts causes Helm to merge the values.yaml files of a chart and all its subcharts and output the result. Closes #3926 --- cmd/helm/inspect.go | 88 ++++++++++++++++--- cmd/helm/inspect_test.go | 17 ++++ .../Chart.yaml | 3 + .../charts/subchart1/Chart.yaml | 3 + .../subchart1/charts/subsubchart/Chart.yaml | 3 + .../subchart1/charts/subsubchart/values.yaml | 5 ++ .../charts/subchart1/values.yaml | 7 ++ .../charts/subchart2/Chart.yaml | 3 + .../charts/subchart2/values.yaml | 6 ++ .../expected.yml | 25 ++++++ .../values.yaml | 6 ++ docs/helm/helm_inspect_values.md | 3 +- 12 files changed, 158 insertions(+), 11 deletions(-) create mode 100644 cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/Chart.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/Chart.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/charts/subsubchart/Chart.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/charts/subsubchart/values.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/values.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart2/Chart.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart2/values.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/expected.yml create mode 100644 cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/values.yaml diff --git a/cmd/helm/inspect.go b/cmd/helm/inspect.go index 999856959..3cb5db4a5 100644 --- a/cmd/helm/inspect.go +++ b/cmd/helm/inspect.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/cobra" "k8s.io/helm/pkg/chartutil" + "k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/kubernetes/pkg/util/slice" ) @@ -52,15 +53,16 @@ of the README file ` type inspectCmd struct { - chartpath string - output string - verify bool - keyring string - out io.Writer - version string - repoURL string - username string - password string + chartpath string + output string + verify bool + withSubcharts bool + keyring string + out io.Writer + version string + repoURL string + username string + password string certFile string keyFile string @@ -164,6 +166,10 @@ func newInspectCmd(out io.Writer) *cobra.Command { subCmd.Flags().BoolVar(&insp.verify, vflag, false, vdesc) } + withSubcharts := "with-subcharts" + withSubchartsDescr := "recursively merges values.yaml files of this chart and all of its subcharts" + valuesSubCmd.Flags().BoolVar(&insp.withSubcharts, withSubcharts, false, withSubchartsDescr) + kflag := "keyring" kdesc := "path to the keyring containing public verification keys" kdefault := defaultKeyring() @@ -238,7 +244,17 @@ func (i *inspectCmd) run() error { if i.output == all { fmt.Fprintln(i.out, "---") } - fmt.Fprintln(i.out, chrt.Values.Raw) + if i.withSubcharts { + mergedOutput, err := coalesceValues(chrt) + + if err != nil { + return err + } + + fmt.Fprintln(i.out, mergedOutput) + } else { + fmt.Fprintln(i.out, chrt.Values.Raw) + } } if i.output == readmeOnly || i.output == all { @@ -254,6 +270,58 @@ func (i *inspectCmd) run() error { return nil } +func coalesceValues(chrt *chart.Chart) (string, error) { + mainVal, err := chartutil.CoalesceValues(chrt, chrt.Values) + if err != nil { + return "", err + } + + mainValMap := mainVal.AsMap() + coalescedGlobals := map[string]interface{}{} + coalesceGlobals(&mainVal, &coalescedGlobals) + + if len(coalescedGlobals) > 0 { + mainValMap[chartutil.GlobalKey] = &coalescedGlobals + } + + s, err := chartutil.Values(mainValMap).YAML() + return s, err +} + +func coalesceGlobals(src *chartutil.Values, destGlob *map[string]interface{}) { + for key, val := range *src { + if key == chartutil.GlobalKey || val == nil { + continue + } + + if subVal, ok := val.(map[string]interface{}); ok { + coalesceGlobalsRecursive(&subVal, destGlob) + } + } +} + +func coalesceGlobalsRecursive(src *map[string]interface{}, destGlob *map[string]interface{}) { + for key, val := range *src { + if key == chartutil.GlobalKey && val != nil { + valMap := val.(map[string]interface{}) + for globKey, globVal := range valMap { + if _, exists := (*destGlob)[globKey]; !exists { + (*destGlob)[globKey] = globVal + } + } + + delete(*src, chartutil.GlobalKey) + continue + } + + if valMap, ok := val.(map[string]interface{}); ok { + if _, globExists := valMap[chartutil.GlobalKey]; globExists { + coalesceGlobalsRecursive(&valMap, destGlob) + } + } + } +} + func findReadme(files []*any.Any) (file *any.Any) { for _, file := range files { if slice.ContainsString(readmeFileNames, strings.ToLower(file.TypeUrl), nil) { diff --git a/cmd/helm/inspect_test.go b/cmd/helm/inspect_test.go index 44d71fbbd..ae82fdfcb 100644 --- a/cmd/helm/inspect_test.go +++ b/cmd/helm/inspect_test.go @@ -78,3 +78,20 @@ func TestInspect(t *testing.T) { t.Errorf("expected empty values buffer, got %q", b.String()) } } + +func TestInspectWithSubCharts(t *testing.T) { + expected, _ := ioutil.ReadFile("testdata/testcharts/chart-globals-inspect-values-with-subcharts/expected.yml") + b := bytes.NewBuffer(nil) + + insp := &inspectCmd{ + chartpath: "testdata/testcharts/chart-globals-inspect-values-with-subcharts", + output: all, + out: b, + withSubcharts: true, + } + insp.run() + + if b.String() != string(expected) { + t.Fatalf("Expected:\n%s \nbut got:\n%s", expected, b.String()) + } +} diff --git a/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/Chart.yaml b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/Chart.yaml new file mode 100644 index 000000000..101f86a62 --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/Chart.yaml @@ -0,0 +1,3 @@ +description: A Helm chart for Kubernetes +name: chart-globals-inspect-values-with-subcharts +version: 0.1.0 diff --git a/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/Chart.yaml b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/Chart.yaml new file mode 100644 index 000000000..68d375232 --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/Chart.yaml @@ -0,0 +1,3 @@ +description: A Helm chart for Kubernetes +name: chart-globals-inspect-values-with-subcharts-subchart1 +version: 0.1.0 diff --git a/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/charts/subsubchart/Chart.yaml b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/charts/subsubchart/Chart.yaml new file mode 100644 index 000000000..bf1432084 --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/charts/subsubchart/Chart.yaml @@ -0,0 +1,3 @@ +description: A Helm chart for Kubernetes +name: chart-globals-inspect-values-with-subcharts-subchart1-subsubchart +version: 0.1.0 diff --git a/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/charts/subsubchart/values.yaml b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/charts/subsubchart/values.yaml new file mode 100644 index 000000000..0272dd784 --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/charts/subsubchart/values.yaml @@ -0,0 +1,5 @@ +global: + key1: from subsubchart + key5: from subsubchart + +subsubchartKey: 'subsubchart' diff --git a/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/values.yaml b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/values.yaml new file mode 100644 index 000000000..6b97c4be0 --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart1/values.yaml @@ -0,0 +1,7 @@ +global: + key3: from subchart 1 + key4: + key41: from subchart 1 + +subchart1Key: 'subchart1' +mainchartKey: from subchart 1 diff --git a/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart2/Chart.yaml b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart2/Chart.yaml new file mode 100644 index 000000000..bc2897fb1 --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart2/Chart.yaml @@ -0,0 +1,3 @@ +description: A Helm chart for Kubernetes +name: chart-globals-inspect-values-with-subcharts-subchart2 +version: 0.1.0 diff --git a/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart2/values.yaml b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart2/values.yaml new file mode 100644 index 000000000..a41a9ffd3 --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/charts/subchart2/values.yaml @@ -0,0 +1,6 @@ +global: + key1: from subchart 2 + key6: + key61: from subchart 2 + +subchart2Key: 'subchart2' diff --git a/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/expected.yml b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/expected.yml new file mode 100644 index 000000000..6c1f05979 --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/expected.yml @@ -0,0 +1,25 @@ +description: A Helm chart for Kubernetes +name: chart-globals-inspect-values-with-subcharts +version: 0.1.0 + +--- +chart-globals-inspect-values-with-subcharts-subchart1: + chart-globals-inspect-values-with-subcharts-subchart1-subsubchart: + subsubchartKey: subsubchart + mainchartKey: from subchart 1 + subchart1Key: subchart1 +chart-globals-inspect-values-with-subcharts-subchart2: + subchart2Key: subchart2 +global: + key1: from mainchart + key2: + key21: from mainchart + key3: from subchart 1 + key4: + key41: from subchart 1 + key5: from subsubchart + key6: + key61: from subchart 2 +mainchartKey: foo + +--- diff --git a/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/values.yaml b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/values.yaml new file mode 100644 index 000000000..b8175aadb --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-globals-inspect-values-with-subcharts/values.yaml @@ -0,0 +1,6 @@ +global: + key1: from mainchart + key2: + key21: from mainchart + +mainchartKey: 'foo' diff --git a/docs/helm/helm_inspect_values.md b/docs/helm/helm_inspect_values.md index 6a907cc7d..b40cbb544 100644 --- a/docs/helm/helm_inspect_values.md +++ b/docs/helm/helm_inspect_values.md @@ -26,6 +26,7 @@ helm inspect values [CHART] --username string chart repository username where to locate the requested chart --verify verify the provenance data for this chart --version string version of the chart. By default, the newest chart is shown + --with-subcharts recursively merges values.yaml files of this chart and all of its subcharts ``` ### Options inherited from parent commands @@ -42,4 +43,4 @@ helm inspect values [CHART] ### SEE ALSO * [helm inspect](helm_inspect.md) - inspect a chart -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 24-Apr-2018