Skip to content

Commit ae66c51

Browse files
Merge pull request #1502 from rcmadhankumar/handle-invalid-column-names
Handling invalid column names on kctrl list commands
2 parents 140f68f + 9b43747 commit ae66c51

File tree

22 files changed

+182
-84
lines changed

22 files changed

+182
-84
lines changed

cli/pkg/kctrl/cmd/app/app_tailer.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ type AppTailer struct {
3232
opts AppTailerOpts
3333

3434
lastSeenDeployStdout string
35+
36+
columns *[]string
3537
}
3638

3739
type AppTailerOpts struct {
@@ -40,8 +42,8 @@ type AppTailerOpts struct {
4042
PrintCurrentState bool
4143
}
4244

43-
func NewAppTailer(namespace string, name string, ui ui.UI, client kcclient.Interface, opts AppTailerOpts) *AppTailer {
44-
return &AppTailer{Namespace: namespace, Name: name, opts: opts, ui: ui, statusUI: cmdcore.NewStatusLoggingUI(ui), client: client}
45+
func NewAppTailer(namespace string, name string, ui ui.UI, client kcclient.Interface, opts AppTailerOpts, columns *[]string) *AppTailer {
46+
return &AppTailer{Namespace: namespace, Name: name, opts: opts, ui: ui, statusUI: cmdcore.NewStatusLoggingUI(ui), client: client, columns: columns}
4547
}
4648

4749
func (o *AppTailer) printTillCurrent(status kcv1alpha1.AppStatus) error {
@@ -61,7 +63,7 @@ func (o *AppTailer) printTillCurrent(status kcv1alpha1.AppStatus) error {
6163
return nil
6264
}
6365

64-
func (o *AppTailer) printInfo(app kcv1alpha1.App) {
66+
func (o *AppTailer) printInfo(app kcv1alpha1.App) error {
6567
status, isFailing := appStatus(&app)
6668
table := uitable.Table{
6769
Transpose: true,
@@ -82,7 +84,7 @@ func (o *AppTailer) printInfo(app kcv1alpha1.App) {
8284
}},
8385
}
8486

85-
o.ui.PrintTable(table)
87+
return cmdcore.PrintTable(o.ui, table, o.columns)
8688
}
8789

8890
func (o *AppTailer) metricString(status kcv1alpha1.AppStatus) string {
@@ -105,7 +107,10 @@ func (o *AppTailer) TailAppStatus() error {
105107
}
106108

107109
if o.opts.PrintMetadata {
108-
o.printInfo(*app)
110+
err = o.printInfo(*app)
111+
if err != nil {
112+
return err
113+
}
109114
}
110115

111116
if o.opts.PrintCurrentState {

cli/pkg/kctrl/cmd/app/app_tailer_test.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func TestAppSuccessTail(t *testing.T) {
3636
Stdout: "kapp success",
3737
},
3838
}
39-
appTailer := NewAppTailer("default", "test-app", ui.NewNoopUI(), fakeVersionedInterface, AppTailerOpts{})
39+
appTailer := NewAppTailer("default", "test-app", ui.NewNoopUI(), fakeVersionedInterface, AppTailerOpts{}, nil)
4040
appTailer.stopperChan = make(chan struct{})
4141
err := appTailer.printTillCurrent(successStatus)
4242

@@ -54,7 +54,7 @@ func TestAppFetchFail(t *testing.T) {
5454
Stderr: "vendir fail",
5555
},
5656
}
57-
appTailer := NewAppTailer("default", "test-app", ui.NewNoopUI(), fakeVersionedInterface, AppTailerOpts{})
57+
appTailer := NewAppTailer("default", "test-app", ui.NewNoopUI(), fakeVersionedInterface, AppTailerOpts{}, nil)
5858
appTailer.stopperChan = make(chan struct{})
5959
err := appTailer.printTillCurrent(successStatus)
6060

@@ -78,7 +78,7 @@ func TestAppTemplateFail(t *testing.T) {
7878
Stderr: "ytt fail",
7979
},
8080
}
81-
appTailer := NewAppTailer("default", "test-app", ui.NewNoopUI(), fakeVersionedInterface, AppTailerOpts{})
81+
appTailer := NewAppTailer("default", "test-app", ui.NewNoopUI(), fakeVersionedInterface, AppTailerOpts{}, nil)
8282
appTailer.stopperChan = make(chan struct{})
8383
err := appTailer.printTillCurrent(successStatus)
8484

@@ -108,14 +108,28 @@ func TestAppDeployFail(t *testing.T) {
108108
Stderr: "kapp fail",
109109
},
110110
}
111-
appTailer := NewAppTailer("default", "test-app", ui.NewNoopUI(), fakeVersionedInterface, AppTailerOpts{})
111+
appTailer := NewAppTailer("default", "test-app", ui.NewNoopUI(), fakeVersionedInterface, AppTailerOpts{}, nil)
112112
appTailer.stopperChan = make(chan struct{})
113113
err := appTailer.printTillCurrent(successStatus)
114114

115115
require.Error(t, err)
116116
require.Contains(t, err.Error(), "Deploy failed")
117117
}
118118

119+
func TestAppPrintInfoFailOnInvalidColumns(t *testing.T) {
120+
fakeVersionedInterface := &FakeVersionedInterface{t}
121+
app := kcv1alpha1.App{
122+
ObjectMeta: metav1.ObjectMeta{
123+
Name: "kctrl-builder",
124+
Namespace: "in-memory",
125+
},
126+
}
127+
cols := []string{"name", "namepsace", "invalid", "namespace"}
128+
appTailer := NewAppTailer("default", "test-app", ui.NewNoopUI(), fakeVersionedInterface, AppTailerOpts{}, &cols)
129+
err := appTailer.printInfo(app)
130+
require.ErrorContains(t, err, "invalid column names: namepsace,invalid")
131+
}
132+
119133
type FakeVersionedInterface struct {
120134
t *testing.T
121135
}

cli/pkg/kctrl/cmd/app/delete.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ func (o *DeleteOptions) patchNoopDelete(client kcclient.Interface) error {
138138

139139
func (o *DeleteOptions) waitForAppDeletion(client kcclient.Interface) error {
140140
o.statusUI.PrintMessagef("Waiting for app deletion for '%s'", o.Name)
141-
appWatcher := NewAppTailer(o.NamespaceFlags.Name, o.Name, o.ui, client, AppTailerOpts{})
141+
appWatcher := NewAppTailer(o.NamespaceFlags.Name, o.Name, o.ui, client, AppTailerOpts{}, nil)
142142
err := appWatcher.TailAppStatus()
143143
if err != nil {
144144
return err

cli/pkg/kctrl/cmd/app/get.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ type GetOptions struct {
2424

2525
NamespaceFlags cmdcore.NamespaceFlags
2626
Name string
27+
28+
columns *[]string
2729
}
2830

29-
func NewGetOptions(ui ui.UI, depsFactory cmdcore.DepsFactory, logger logger.Logger) *GetOptions {
30-
return &GetOptions{ui: ui, depsFactory: depsFactory, logger: logger}
31+
func NewGetOptions(ui ui.UI, depsFactory cmdcore.DepsFactory, logger logger.Logger, columns *[]string) *GetOptions {
32+
return &GetOptions{ui: ui, depsFactory: depsFactory, logger: logger, columns: columns}
3133
}
3234

3335
func NewGetCmd(o *GetOptions, flagsFactory cmdcore.FlagsFactory) *cobra.Command {
@@ -95,9 +97,7 @@ func (o *GetOptions) Run() error {
9597
}},
9698
}
9799

98-
o.ui.PrintTable(table)
99-
100-
return nil
100+
return cmdcore.PrintTable(o.ui, table, o.columns)
101101
}
102102

103103
func (o *GetOptions) formatOwnerReferences(references []metav1.OwnerReference) []string {

cli/pkg/kctrl/cmd/app/kick.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func (o *KickOptions) triggerReconciliation(client kcclient.Interface) error {
141141

142142
func (o *KickOptions) waitForAppReconciliation(client kcclient.Interface) error {
143143
o.statusUI.PrintMessagef("Waiting for app reconciliation for '%s'", o.Name)
144-
appWatcher := NewAppTailer(o.NamespaceFlags.Name, o.Name, o.ui, client, AppTailerOpts{})
144+
appWatcher := NewAppTailer(o.NamespaceFlags.Name, o.Name, o.ui, client, AppTailerOpts{}, nil)
145145

146146
err := appWatcher.TailAppStatus()
147147
if err != nil {

cli/pkg/kctrl/cmd/app/list.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ type ListOptions struct {
2323

2424
NamespaceFlags cmdcore.NamespaceFlags
2525
AllNamespaces bool
26+
27+
columns *[]string
2628
}
2729

28-
func NewListOptions(ui ui.UI, depsFactory cmdcore.DepsFactory, logger logger.Logger) *ListOptions {
29-
return &ListOptions{ui: ui, depsFactory: depsFactory, logger: logger}
30+
func NewListOptions(ui ui.UI, depsFactory cmdcore.DepsFactory, logger logger.Logger, columns *[]string) *ListOptions {
31+
return &ListOptions{ui: ui, depsFactory: depsFactory, logger: logger, columns: columns}
3032
}
3133

3234
func NewListCmd(o *ListOptions, flagsFactory cmdcore.FlagsFactory) *cobra.Command {
@@ -102,9 +104,8 @@ func (o *ListOptions) Run() error {
102104
})
103105
}
104106

105-
o.ui.PrintTable(table)
107+
return cmdcore.PrintTable(o.ui, table, o.columns)
106108

107-
return nil
108109
}
109110

110111
func (o *ListOptions) owner(references []metav1.OwnerReference) string {

cli/pkg/kctrl/cmd/app/status.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ type StatusOptions struct {
2121
Name string
2222

2323
IgnoreNotExists bool
24+
25+
columns *[]string
2426
}
2527

26-
func NewStatusOptions(ui ui.UI, depsFactory cmdcore.DepsFactory, logger logger.Logger) *StatusOptions {
27-
return &StatusOptions{ui: ui, depsFactory: depsFactory, logger: logger}
28+
func NewStatusOptions(ui ui.UI, depsFactory cmdcore.DepsFactory, logger logger.Logger, columns *[]string) *StatusOptions {
29+
return &StatusOptions{ui: ui, depsFactory: depsFactory, logger: logger, columns: columns}
2830
}
2931

3032
func NewStatusCmd(o *StatusOptions, flagsFactory cmdcore.FlagsFactory) *cobra.Command {
@@ -58,7 +60,7 @@ func (o *StatusOptions) Run() error {
5860
IgnoreNotExists: o.IgnoreNotExists,
5961
PrintMetadata: true,
6062
PrintCurrentState: true,
61-
})
63+
}, o.columns)
6264

6365
err = appWatcher.TailAppStatus()
6466
if err != nil {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2024 VMware, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package core
5+
6+
import (
7+
"fmt"
8+
"strings"
9+
10+
"github.com/cppforlife/go-cli-ui/ui"
11+
uitable "github.com/cppforlife/go-cli-ui/ui/table"
12+
)
13+
14+
func validateColumns(headers *[]uitable.Header, cols *[]string) error {
15+
invalidColumns := []string{}
16+
for _, col := range *cols {
17+
found := false
18+
for _, head := range *headers {
19+
if col == head.Key || col == head.Title {
20+
found = true
21+
break
22+
}
23+
}
24+
if !found {
25+
invalidColumns = append(invalidColumns, col)
26+
}
27+
}
28+
29+
if len(invalidColumns) > 0 {
30+
return fmt.Errorf("invalid column names: %s", strings.Join(invalidColumns, ","))
31+
}
32+
return nil
33+
}
34+
35+
func PrintTable(ui ui.UI, table uitable.Table, columns *[]string) error {
36+
err := validateColumns(&table.Header, columns)
37+
if err == nil {
38+
ui.PrintTable(table)
39+
}
40+
return err
41+
}

cli/pkg/kctrl/cmd/dev/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func (o *DevOptions) beforeAppReconcile(app kcv1alpha1.App, kcClient *fakekc.Cli
9898

9999
go func() {
100100
appWatcher := cmdapp.NewAppTailer(app.Namespace, app.Name,
101-
o.ui, kcClient, cmdapp.AppTailerOpts{IgnoreNotExists: true})
101+
o.ui, kcClient, cmdapp.AppTailerOpts{IgnoreNotExists: true}, nil)
102102

103103
err := appWatcher.TailAppStatus()
104104
if err != nil {

cli/pkg/kctrl/cmd/kctrl.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ func NewKctrlCmd(o *KctrlOptions, flagsFactory cmdcore.FlagsFactory) *cobra.Comm
100100
cmdcore.AppManagementCommandsHelpGroup,
101101
cmdcore.RestOfCommandsHelpGroup,
102102
}))
103-
appCmd.AddCommand(app.NewGetCmd(app.NewGetOptions(o.ui, o.depsFactory, o.logger), flagsFactory))
104-
appCmd.AddCommand(app.NewListCmd(app.NewListOptions(o.ui, o.depsFactory, o.logger), flagsFactory))
105-
appCmd.AddCommand(app.NewStatusCmd(app.NewStatusOptions(o.ui, o.depsFactory, o.logger), flagsFactory))
103+
appCmd.AddCommand(app.NewGetCmd(app.NewGetOptions(o.ui, o.depsFactory, o.logger, &o.UIFlags.Columns), flagsFactory))
104+
appCmd.AddCommand(app.NewListCmd(app.NewListOptions(o.ui, o.depsFactory, o.logger, &o.UIFlags.Columns), flagsFactory))
105+
appCmd.AddCommand(app.NewStatusCmd(app.NewStatusOptions(o.ui, o.depsFactory, o.logger, &o.UIFlags.Columns), flagsFactory))
106106
appCmd.AddCommand(app.NewPauseCmd(app.NewPauseOptions(o.ui, o.depsFactory, o.logger), flagsFactory))
107107
appCmd.AddCommand(app.NewKickCmd(app.NewKickOptions(o.ui, o.depsFactory, o.logger), flagsFactory))
108108
appCmd.AddCommand(app.NewDeleteCmd(app.NewDeleteOptions(o.ui, o.depsFactory, o.logger), flagsFactory))
@@ -181,8 +181,8 @@ func AddPackageCommands(o *KctrlOptions, cmd *cobra.Command, flagsFactory cmdcor
181181
cmdcore.PackageManagementCommandsHelpGroup,
182182
cmdcore.PackageAuthoringCommandsHelpGroup,
183183
}))
184-
pkgrepoCmd.AddCommand(pkgrepo.NewListCmd(pkgrepo.NewListOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
185-
pkgrepoCmd.AddCommand(pkgrepo.NewGetCmd(pkgrepo.NewGetOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
184+
pkgrepoCmd.AddCommand(pkgrepo.NewListCmd(pkgrepo.NewListOptions(o.ui, o.depsFactory, o.logger, opts, &o.UIFlags.Columns), flagsFactory))
185+
pkgrepoCmd.AddCommand(pkgrepo.NewGetCmd(pkgrepo.NewGetOptions(o.ui, o.depsFactory, o.logger, opts, &o.UIFlags.Columns), flagsFactory))
186186
pkgrepoCmd.AddCommand(pkgrepo.NewDeleteCmd(pkgrepo.NewDeleteOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
187187
pkgrepoCmd.AddCommand(pkgrepo.NewAddCmd(pkgrepo.NewAddOrUpdateOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
188188
pkgrepoCmd.AddCommand(pkgrepo.NewUpdateCmd(pkgrepo.NewAddOrUpdateOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
@@ -193,26 +193,26 @@ func AddPackageCommands(o *KctrlOptions, cmd *cobra.Command, flagsFactory cmdcor
193193
pkgiCmd.SetUsageTemplate(cobrautil.HelpSectionsUsageTemplate([]cobrautil.HelpSection{
194194
cmdcore.PackageManagementCommandsHelpGroup,
195195
}))
196-
pkgiCmd.AddCommand(pkginst.NewListCmd(pkginst.NewListOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
197-
pkgiCmd.AddCommand(pkginst.NewGetCmd(pkginst.NewGetOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
198-
pkgiCmd.AddCommand(pkginst.NewCreateCmd(pkginst.NewCreateOrUpdateOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
199-
pkgiCmd.AddCommand(pkginst.NewUpdateCmd(pkginst.NewCreateOrUpdateOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
196+
pkgiCmd.AddCommand(pkginst.NewListCmd(pkginst.NewListOptions(o.ui, o.depsFactory, o.logger, opts, &o.UIFlags.Columns), flagsFactory))
197+
pkgiCmd.AddCommand(pkginst.NewGetCmd(pkginst.NewGetOptions(o.ui, o.depsFactory, o.logger, opts, &o.UIFlags.Columns), flagsFactory))
198+
pkgiCmd.AddCommand(pkginst.NewCreateCmd(pkginst.NewCreateOrUpdateOptions(o.ui, o.depsFactory, o.logger, opts, &o.UIFlags.Columns), flagsFactory))
199+
pkgiCmd.AddCommand(pkginst.NewUpdateCmd(pkginst.NewCreateOrUpdateOptions(o.ui, o.depsFactory, o.logger, opts, &o.UIFlags.Columns), flagsFactory))
200200
pkgiCmd.AddCommand(pkginst.NewDeleteCmd(pkginst.NewDeleteOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
201201
pkgiCmd.AddCommand(pkginst.NewPauseCmd(pkginst.NewPauseOrKickOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
202202
pkgiCmd.AddCommand(pkginst.NewKickCmd(pkginst.NewPauseOrKickOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
203-
pkgiCmd.AddCommand(pkginst.NewStatusCmd(pkginst.NewStatusOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
203+
pkgiCmd.AddCommand(pkginst.NewStatusCmd(pkginst.NewStatusOptions(o.ui, o.depsFactory, o.logger, opts, &o.UIFlags.Columns), flagsFactory))
204204

205205
pkgaCmd := pkgavail.NewCmd()
206206
pkgaCmd.SetUsageTemplate(cobrautil.HelpSectionsUsageTemplate([]cobrautil.HelpSection{
207207
cmdcore.PackageManagementCommandsHelpGroup,
208208
}))
209-
pkgaCmd.AddCommand(pkgavail.NewListCmd(pkgavail.NewListOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
210-
pkgaCmd.AddCommand(pkgavail.NewGetCmd(pkgavail.NewGetOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
209+
pkgaCmd.AddCommand(pkgavail.NewListCmd(pkgavail.NewListOptions(o.ui, o.depsFactory, o.logger, opts, &o.UIFlags.Columns), flagsFactory))
210+
pkgaCmd.AddCommand(pkgavail.NewGetCmd(pkgavail.NewGetOptions(o.ui, o.depsFactory, o.logger, opts, &o.UIFlags.Columns), flagsFactory))
211211

212212
cmd.AddCommand(pkgrepoCmd)
213213
cmd.AddCommand(pkgiCmd)
214214
cmd.AddCommand(pkgaCmd)
215-
cmd.AddCommand(pkginst.NewInstallCmd(pkginst.NewCreateOrUpdateOptions(o.ui, o.depsFactory, o.logger, opts), flagsFactory))
215+
cmd.AddCommand(pkginst.NewInstallCmd(pkginst.NewCreateOrUpdateOptions(o.ui, o.depsFactory, o.logger, opts, &o.UIFlags.Columns), flagsFactory))
216216
cmd.AddCommand(cmdpkg.NewInitCmd(cmdpkg.NewInitOptions(o.ui, o.depsFactory, o.logger)))
217217
cmd.AddCommand(pkgrel.NewReleaseCmd(pkgrel.NewReleaseOptions(o.ui, o.depsFactory, o.logger)))
218218

0 commit comments

Comments
 (0)