|
|
|
@ -17,10 +17,12 @@ limitations under the License.
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/ghodss/yaml"
|
|
|
|
|
"github.com/gosuri/uitable"
|
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
|
|
|
|
|
@ -75,6 +77,22 @@ type listCmd struct {
|
|
|
|
|
pending bool
|
|
|
|
|
client helm.Interface
|
|
|
|
|
colWidth uint
|
|
|
|
|
output string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type listResult struct {
|
|
|
|
|
Next string
|
|
|
|
|
Releases []listRelease
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type listRelease struct {
|
|
|
|
|
Name string
|
|
|
|
|
Revision int32
|
|
|
|
|
Updated string
|
|
|
|
|
Status string
|
|
|
|
|
Chart string
|
|
|
|
|
AppVersion string
|
|
|
|
|
Namespace string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
|
|
|
|
@ -114,6 +132,7 @@ func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
|
|
|
|
|
f.BoolVar(&list.pending, "pending", false, "show pending releases")
|
|
|
|
|
f.StringVar(&list.namespace, "namespace", "", "show releases within a specific namespace")
|
|
|
|
|
f.UintVar(&list.colWidth, "col-width", 60, "specifies the max column width of output")
|
|
|
|
|
f.StringVar(&list.output, "output", "", "output the specified format (json or yaml)")
|
|
|
|
|
|
|
|
|
|
// TODO: Do we want this as a feature of 'helm list'?
|
|
|
|
|
//f.BoolVar(&list.superseded, "history", true, "show historical releases")
|
|
|
|
@ -148,23 +167,17 @@ func (l *listCmd) run() error {
|
|
|
|
|
return prettyError(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(res.GetReleases()) == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
rels := filterList(res.Releases)
|
|
|
|
|
|
|
|
|
|
if res.Next != "" && !l.short {
|
|
|
|
|
fmt.Fprintf(l.out, "\tnext: %s\n", res.Next)
|
|
|
|
|
}
|
|
|
|
|
result := getListResult(rels, res.Next)
|
|
|
|
|
|
|
|
|
|
rels := filterList(res.Releases)
|
|
|
|
|
output, err := formatResult(l.output, l.short, result, l.colWidth)
|
|
|
|
|
|
|
|
|
|
if l.short {
|
|
|
|
|
for _, r := range rels {
|
|
|
|
|
fmt.Fprintln(l.out, r.Name)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
if err != nil {
|
|
|
|
|
return prettyError(err)
|
|
|
|
|
}
|
|
|
|
|
fmt.Fprintln(l.out, formatList(rels, l.colWidth))
|
|
|
|
|
|
|
|
|
|
fmt.Fprintln(l.out, output)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -233,23 +246,98 @@ func (l *listCmd) statusCodes() []release.Status_Code {
|
|
|
|
|
return status
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func formatList(rels []*release.Release, colWidth uint) string {
|
|
|
|
|
table := uitable.New()
|
|
|
|
|
|
|
|
|
|
table.MaxColWidth = colWidth
|
|
|
|
|
table.AddRow("NAME", "REVISION", "UPDATED", "STATUS", "CHART", "APP VERSION", "NAMESPACE")
|
|
|
|
|
func getListResult(rels []*release.Release, next string) listResult {
|
|
|
|
|
listReleases := []listRelease{}
|
|
|
|
|
for _, r := range rels {
|
|
|
|
|
md := r.GetChart().GetMetadata()
|
|
|
|
|
c := fmt.Sprintf("%s-%s", md.GetName(), md.GetVersion())
|
|
|
|
|
t := "-"
|
|
|
|
|
if tspb := r.GetInfo().GetLastDeployed(); tspb != nil {
|
|
|
|
|
t = timeconv.String(tspb)
|
|
|
|
|
}
|
|
|
|
|
s := r.GetInfo().GetStatus().GetCode().String()
|
|
|
|
|
v := r.GetVersion()
|
|
|
|
|
a := md.GetAppVersion()
|
|
|
|
|
n := r.GetNamespace()
|
|
|
|
|
table.AddRow(r.GetName(), v, t, s, c, a, n)
|
|
|
|
|
|
|
|
|
|
lr := listRelease{
|
|
|
|
|
Name: r.GetName(),
|
|
|
|
|
Revision: r.GetVersion(),
|
|
|
|
|
Updated: t,
|
|
|
|
|
Status: r.GetInfo().GetStatus().GetCode().String(),
|
|
|
|
|
Chart: fmt.Sprintf("%s-%s", md.GetName(), md.GetVersion()),
|
|
|
|
|
AppVersion: md.GetAppVersion(),
|
|
|
|
|
Namespace: r.GetNamespace(),
|
|
|
|
|
}
|
|
|
|
|
listReleases = append(listReleases, lr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return listResult{
|
|
|
|
|
Releases: listReleases,
|
|
|
|
|
Next: next,
|
|
|
|
|
}
|
|
|
|
|
return table.String()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func shortenListResult(result listResult) []string {
|
|
|
|
|
names := []string{}
|
|
|
|
|
for _, r := range result.Releases {
|
|
|
|
|
names = append(names, r.Name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return names
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func formatResult(format string, short bool, result listResult, colWidth uint) (string, error) {
|
|
|
|
|
var output string
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
var shortResult []string
|
|
|
|
|
var finalResult interface{}
|
|
|
|
|
if short {
|
|
|
|
|
shortResult = shortenListResult(result)
|
|
|
|
|
finalResult = shortResult
|
|
|
|
|
} else {
|
|
|
|
|
finalResult = result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch format {
|
|
|
|
|
case "":
|
|
|
|
|
if short {
|
|
|
|
|
output = formatTextShort(shortResult)
|
|
|
|
|
} else {
|
|
|
|
|
output = formatText(result, colWidth)
|
|
|
|
|
}
|
|
|
|
|
case "json":
|
|
|
|
|
o, e := json.Marshal(finalResult)
|
|
|
|
|
if e != nil {
|
|
|
|
|
err = fmt.Errorf("Failed to Marshal JSON output: %s", e)
|
|
|
|
|
} else {
|
|
|
|
|
output = string(o)
|
|
|
|
|
}
|
|
|
|
|
case "yaml":
|
|
|
|
|
o, e := yaml.Marshal(finalResult)
|
|
|
|
|
if e != nil {
|
|
|
|
|
err = fmt.Errorf("Failed to Marshal YAML output: %s", e)
|
|
|
|
|
} else {
|
|
|
|
|
output = string(o)
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
err = fmt.Errorf("Unknown output format \"%s\"", format)
|
|
|
|
|
}
|
|
|
|
|
return output, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func formatText(result listResult, colWidth uint) string {
|
|
|
|
|
nextOutput := ""
|
|
|
|
|
if result.Next != "" {
|
|
|
|
|
nextOutput = fmt.Sprintf("\tnext: %s\n", result.Next)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
table := uitable.New()
|
|
|
|
|
table.MaxColWidth = colWidth
|
|
|
|
|
table.AddRow("NAME", "REVISION", "UPDATED", "STATUS", "CHART", "APP VERSION", "NAMESPACE")
|
|
|
|
|
for _, lr := range result.Releases {
|
|
|
|
|
table.AddRow(lr.Name, lr.Revision, lr.Updated, lr.Status, lr.Chart, lr.AppVersion, lr.Namespace)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fmt.Sprintf("%s%s", nextOutput, table.String())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func formatTextShort(shortResult []string) string {
|
|
|
|
|
return strings.Join(shortResult, "\n")
|
|
|
|
|
}
|
|
|
|
|