From 46ed8027508a8ff0df9604d0ca8f0449c1d973e1 Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Fri, 9 Mar 2018 16:56:45 -0800 Subject: [PATCH] add support for output format in json or yaml --- cmd/helm/history.go | 75 ++++++++++++++++++++++++++++++++------- cmd/helm/history_test.go | 20 +++++++++++ docs/helm/helm_history.md | 3 +- 3 files changed, 84 insertions(+), 14 deletions(-) diff --git a/cmd/helm/history.go b/cmd/helm/history.go index 659c39e81ab..944d61509c6 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -23,12 +23,24 @@ import ( "github.com/gosuri/uitable" "github.com/spf13/cobra" + "encoding/json" + "github.com/ghodss/yaml" "k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/timeconv" ) +type releaseInfo struct { + Revision int32 `json:"revision" yaml:"revision"` + Updated string `json:"updated" yaml:"updated"` + Status string `json:"status" yaml:"status"` + Chart string `json:"chart" yaml:"chart"` + Description string `json:"description" yaml:"description"` +} + +type releaseHistory []releaseInfo + var historyHelp = ` History prints historical revisions for a given release. @@ -46,11 +58,12 @@ The historical release set is printed as a formatted table, e.g: ` type historyCmd struct { - max int32 - rls string - out io.Writer - helmc helm.Interface - colWidth uint + max int32 + rls string + out io.Writer + helmc helm.Interface + colWidth uint + outputFormat string } func newHistoryCmd(c helm.Interface, w io.Writer) *cobra.Command { @@ -77,6 +90,7 @@ func newHistoryCmd(c helm.Interface, w io.Writer) *cobra.Command { f := cmd.Flags() f.Int32Var(&his.max, "max", 256, "maximum number of revision to include in history") f.UintVar(&his.colWidth, "col-width", 60, "specifies the max column width of output") + f.StringVarP(&his.outputFormat, "output", "o", "", "prints the output in the specified format ('json' or 'yaml' or defaults to 'table')") return cmd } @@ -90,15 +104,29 @@ func (cmd *historyCmd) run() error { return nil } - fmt.Fprintln(cmd.out, formatHistory(r.Releases, cmd.colWidth)) + releaseHistory := getReleaseHistory(r.Releases) + + var history []byte + var formattingError error + + switch cmd.outputFormat { + case "yaml": + history, formattingError = yaml.Marshal(releaseHistory) + case "json": + history, formattingError = json.Marshal(releaseHistory) + default: + history = formatAsTable(releaseHistory, cmd.colWidth) + } + + if formattingError != nil { + return prettyError(formattingError) + } + + fmt.Fprintln(cmd.out, string(history)) return nil } -func formatHistory(rls []*release.Release, colWidth uint) string { - tbl := uitable.New() - - tbl.MaxColWidth = colWidth - tbl.AddRow("REVISION", "UPDATED", "STATUS", "CHART", "DESCRIPTION") +func getReleaseHistory(rls []*release.Release) (history releaseHistory) { for i := len(rls) - 1; i >= 0; i-- { r := rls[i] c := formatChartname(r.Chart) @@ -106,9 +134,30 @@ func formatHistory(rls []*release.Release, colWidth uint) string { s := r.Info.Status.Code.String() v := r.Version d := r.Info.Description - tbl.AddRow(v, t, s, c, d) + + rInfo := releaseInfo{ + Revision: v, + Updated: t, + Status: s, + Chart: c, + Description: d, + } + history = append(history, rInfo) + } + + return history +} + +func formatAsTable(releases releaseHistory, colWidth uint) []byte { + tbl := uitable.New() + + tbl.MaxColWidth = colWidth + tbl.AddRow("REVISION", "UPDATED", "STATUS", "CHART", "DESCRIPTION") + for i := 0; i <= len(releases)-1; i++ { + r := releases[i] + tbl.AddRow(r.Revision, r.Updated, r.Status, r.Chart, r.Description) } - return tbl.String() + return tbl.Bytes() } func formatChartname(c *chart.Chart) string { diff --git a/cmd/helm/history_test.go b/cmd/helm/history_test.go index f193f6314ca..7594da964e2 100644 --- a/cmd/helm/history_test.go +++ b/cmd/helm/history_test.go @@ -63,6 +63,26 @@ func TestHistoryCmd(t *testing.T) { }, xout: "REVISION\tUPDATED \tSTATUS \tCHART \tDESCRIPTION \n3 \t(.*)\tSUPERSEDED\tfoo-0.1.0-beta.1\tRelease mock\n4 \t(.*)\tDEPLOYED \tfoo-0.1.0-beta.1\tRelease mock\n", }, + { + cmds: "helm history --max=MAX RELEASE_NAME -o yaml", + desc: "get history with yaml output format", + args: []string{"--max=2", "-o=yaml", "angry-bird"}, + resp: []*rpb.Release{ + mk("angry-bird", 4, rpb.Status_DEPLOYED), + mk("angry-bird", 3, rpb.Status_SUPERSEDED), + }, + xout: "- chart: foo-0.1.0-beta.1\n description: Release mock\n revision: 3\n status: SUPERSEDED\n updated: (.*)\n- chart: foo-0.1.0-beta.1\n description: Release mock\n revision: 4\n status: DEPLOYED\n updated: (.*)\n\n", + }, + { + cmds: "helm history --max=MAX RELEASE_NAME -o json", + desc: "get history with json output format", + args: []string{"--max=2", "-o=json", "angry-bird"}, + resp: []*rpb.Release{ + mk("angry-bird", 4, rpb.Status_DEPLOYED), + mk("angry-bird", 3, rpb.Status_SUPERSEDED), + }, + xout: `[{"revision":3,"updated":".*","status":"SUPERSEDED","chart":"foo\-0.1.0-beta.1","description":"Release mock"},{"revision":4,"updated":".*","status":"DEPLOYED","chart":"foo\-0.1.0-beta.1","description":"Release mock"}]\n`, + }, } var buf bytes.Buffer diff --git a/docs/helm/helm_history.md b/docs/helm/helm_history.md index 81c72002171..422c5f4e15b 100755 --- a/docs/helm/helm_history.md +++ b/docs/helm/helm_history.md @@ -30,6 +30,7 @@ helm history [flags] RELEASE_NAME ``` --col-width uint specifies the max column width of output (default 60) --max int32 maximum number of revision to include in history (default 256) + -o, --output string prints the output in the specified format ('json' or 'yaml' or defaults to 'table') --tls enable TLS for request --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") @@ -51,4 +52,4 @@ helm history [flags] RELEASE_NAME ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 9-Mar-2018