New output flag for list command (#1215)
* New output flag for list command Support output as json Add new formatters file to handle extrac formatting to its own concern New config interface to support list command specification * Fix usage message * Add error handling for formatters
This commit is contained in:
parent
71bb7354e7
commit
e0a793b7c5
14
main.go
14
main.go
|
|
@ -471,7 +471,13 @@ func main() {
|
|||
{
|
||||
Name: "list",
|
||||
Usage: "list releases defined in state file",
|
||||
Flags: []cli.Flag{},
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "output",
|
||||
Value: "",
|
||||
Usage: "output releases list as a json string",
|
||||
},
|
||||
},
|
||||
Action: action(func(run *app.App, c configImpl) error {
|
||||
return run.ListReleases(c)
|
||||
}),
|
||||
|
|
@ -597,6 +603,12 @@ func (c configImpl) Timeout() int {
|
|||
return c.c.Int("timeout")
|
||||
}
|
||||
|
||||
// ListConfig
|
||||
|
||||
func (c configImpl) Output() string {
|
||||
return c.c.String("output")
|
||||
}
|
||||
|
||||
// GlobalConfig
|
||||
|
||||
func (c configImpl) HelmBinary() string {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import (
|
|||
"syscall"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/gosuri/uitable"
|
||||
"github.com/roboll/helmfile/pkg/argparser"
|
||||
"github.com/roboll/helmfile/pkg/helmexec"
|
||||
"github.com/roboll/helmfile/pkg/remote"
|
||||
|
|
@ -60,6 +59,13 @@ type App struct {
|
|||
helmsMutex sync.Mutex
|
||||
}
|
||||
|
||||
type HelmRelease struct {
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Labels string `json:"labels"`
|
||||
}
|
||||
|
||||
func New(conf ConfigProvider) *App {
|
||||
return Init(&App{
|
||||
OverrideKubeContext: conf.KubeContext(),
|
||||
|
|
@ -259,9 +265,8 @@ func (a *App) PrintState(c StateConfigProvider) error {
|
|||
})
|
||||
}
|
||||
|
||||
func (a *App) ListReleases(c StateConfigProvider) error {
|
||||
table := uitable.New()
|
||||
table.AddRow("NAME", "NAMESPACE", "ENABLED", "LABELS")
|
||||
func (a *App) ListReleases(c ListConfigProvider) error {
|
||||
var releases []*HelmRelease
|
||||
|
||||
err := a.VisitDesiredStatesWithReleasesFiltered(a.FileOrDir, func(st *state.HelmState) []error {
|
||||
//var releases m
|
||||
|
|
@ -270,12 +275,28 @@ func (a *App) ListReleases(c StateConfigProvider) error {
|
|||
for k, v := range r.Labels {
|
||||
labels = fmt.Sprintf("%s,%s:%s", labels, k, v)
|
||||
}
|
||||
labels = strings.Trim(labels, ",")
|
||||
installed := r.Installed == nil || *r.Installed
|
||||
table.AddRow(r.Name, r.Namespace, fmt.Sprintf("%t", installed), strings.Trim(labels, ","))
|
||||
releases = append(releases, &HelmRelease{
|
||||
Name: r.Name,
|
||||
Namespace: r.Namespace,
|
||||
Enabled: installed,
|
||||
Labels: labels,
|
||||
})
|
||||
}
|
||||
return []error{}
|
||||
})
|
||||
fmt.Println(table.String())
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.Output() == "json" {
|
||||
err = FormatAsJson(releases)
|
||||
} else {
|
||||
err = FormatAsTable(releases)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1962,7 +1962,8 @@ services:
|
|||
}
|
||||
|
||||
type configImpl struct {
|
||||
set []string
|
||||
set []string
|
||||
output string
|
||||
}
|
||||
|
||||
func (c configImpl) Set() []string {
|
||||
|
|
@ -1993,6 +1994,10 @@ func (c configImpl) Concurrency() int {
|
|||
return 1
|
||||
}
|
||||
|
||||
func (c configImpl) Output() string {
|
||||
return c.output
|
||||
}
|
||||
|
||||
type applyConfig struct {
|
||||
args string
|
||||
values []string
|
||||
|
|
@ -3849,6 +3854,63 @@ myrelease4 true id:myrelease1
|
|||
assert.Equal(t, expected, out)
|
||||
}
|
||||
|
||||
func TestListWithJsonOutput(t *testing.T) {
|
||||
files := map[string]string{
|
||||
"/path/to/helmfile.d/first.yaml": `
|
||||
releases:
|
||||
- name: myrelease1
|
||||
chart: mychart1
|
||||
installed: no
|
||||
labels:
|
||||
id: myrelease1
|
||||
- name: myrelease2
|
||||
chart: mychart1
|
||||
`,
|
||||
"/path/to/helmfile.d/second.yaml": `
|
||||
releases:
|
||||
- name: myrelease3
|
||||
chart: mychart1
|
||||
installed: yes
|
||||
- name: myrelease4
|
||||
chart: mychart1
|
||||
labels:
|
||||
id: myrelease1
|
||||
`,
|
||||
}
|
||||
stdout := os.Stdout
|
||||
defer func() { os.Stdout = stdout }()
|
||||
|
||||
var buffer bytes.Buffer
|
||||
logger := helmexec.NewLogger(&buffer, "debug")
|
||||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
Namespace: "testNamespace",
|
||||
}, files)
|
||||
|
||||
expectNoCallsToHelm(app)
|
||||
|
||||
out := captureStdout(func() {
|
||||
err := app.ListReleases(configImpl{
|
||||
output: "json",
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
expected := "[" +
|
||||
"{\"name\":\"myrelease1\",\"namespace\":\"\",\"enabled\":false,\"labels\":\"id:myrelease1\"}," +
|
||||
"{\"name\":\"myrelease2\",\"namespace\":\"\",\"enabled\":true,\"labels\":\"\"}," +
|
||||
"{\"name\":\"myrelease3\",\"namespace\":\"\",\"enabled\":true,\"labels\":\"\"}," +
|
||||
"{\"name\":\"myrelease4\",\"namespace\":\"\",\"enabled\":true,\"labels\":\"id:myrelease1\"}" +
|
||||
"]\n"
|
||||
assert.Equal(t, expected, out)
|
||||
}
|
||||
|
||||
func TestSetValuesTemplate(t *testing.T) {
|
||||
files := map[string]string{
|
||||
"/path/to/helmfile.yaml": `
|
||||
|
|
|
|||
|
|
@ -156,3 +156,7 @@ type loggingConfig interface {
|
|||
type interactive interface {
|
||||
Interactive() bool
|
||||
}
|
||||
|
||||
type ListConfigProvider interface {
|
||||
Output() string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/gosuri/uitable"
|
||||
)
|
||||
|
||||
func FormatAsTable(releases []*HelmRelease) error {
|
||||
table := uitable.New()
|
||||
table.AddRow("NAME", "NAMESPACE", "ENABLED", "LABELS")
|
||||
|
||||
for _, r := range releases {
|
||||
table.AddRow(r.Name, r.Namespace, fmt.Sprintf("%t", r.Enabled), r.Labels)
|
||||
}
|
||||
|
||||
fmt.Println(table.String())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func FormatAsJson(releases []*HelmRelease) error {
|
||||
output, err := json.Marshal(releases)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("error generating json: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println(string(output))
|
||||
|
||||
return nil
|
||||
}
|
||||
Loading…
Reference in New Issue