Skip to content

Commit 341478f

Browse files
j1n-o9rrubenhoenle
andauthored
fix(iaas): print valid JSON/YAML output for list cmds (#1365)
* fix returning empty server array in case the response does not return any items via outputResult function instead of returning nil bluntly. adapted tests therefore. * adapted outputResult signature to comply to linter * switched to getter for retrieving the items * adapted printing behavior to align with expected behavior * change printing to defined output instead of stderr * adapted network list command to align to expectations * remove unnecessary normalization of nil value in response items after feedback * adapted network-area list command to align to expectations * removed redundant check * adapted affinity list command to align to expectations * adapted image list command to align to expectations * adapted key pair list command to align to expectations * fixed debug print in key pair list command * move project label retrieval * adapted public ip list command to align to expectations * adapted security group list command to align to expectations * added missing --limit flag for list security groups command * adapted volumes list command to align to expectations * adapted volume snapshots list command to align to expectations * adapted volume performance class list command to align to expectations * adapted volume backups list command to align to expectations * fixed order of params * adapted network area network ranges list command to align to expectations * adapted network area routes list command to align to expectations * adapted security group rules list command to align to expectations * adapted server machine-types list command to align to expectations * adapted server network-interfaces list command to align to expectations * adapted server service accounts list command to align to expectations * adapted server volumes list command to align to expectations * removed unnecessary check in public ip * regenerate docs * fixed linter issue * Update internal/cmd/key-pair/list/list.go Co-authored-by: Ruben Hönle <git@hoenle.xyz> * (fix): remove mistakenly added project label from key pairs list command * (fix): made orgLabel in model from pointer to string for not having to deal with nil values since it is required anyways * (fix): remove unnecessarily declaring variable with explicit statement * (fix): made OrganizationId and NetworkAreaId in model from pointer to string for not having to deal with nil values since it is required anyways * (fix): changed print statement to not contain abbreviation * (fix): added test suggestion * adapted server quotas list command to return valid json/yaml when quotas is empty * fix(iaas): readded lost elif block --------- Co-authored-by: Ruben Hönle <git@hoenle.xyz>
1 parent fdc4409 commit 341478f

38 files changed

Lines changed: 373 additions & 289 deletions

File tree

docs/stackit_security-group_list.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,25 @@ stackit security-group list [flags]
1313
### Examples
1414

1515
```
16-
List all groups
16+
Lists all security groups
1717
$ stackit security-group list
1818
19-
List groups with labels
19+
Lists security groups with labels
2020
$ stackit security-group list --label-selector label1=value1,label2=value2
21+
22+
Lists all security groups in JSON format
23+
$ stackit security-group list --output-format json
24+
25+
Lists up to 10 security groups
26+
$ stackit security-group list --limit 10
2127
```
2228

2329
### Options
2430

2531
```
2632
-h, --help Help for "stackit security-group list"
2733
--label-selector string Filter by label
34+
--limit int Maximum number of entries to list
2835
```
2936

3037
### Options inherited from parent commands

internal/cmd/affinity-groups/list/list.go

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/stackitcloud/stackit-cli/internal/pkg/flags"
1919
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
2020
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
21+
"github.com/stackitcloud/stackit-cli/internal/pkg/projectname"
2122
"github.com/stackitcloud/stackit-cli/internal/pkg/services/iaas/client"
2223
)
2324

@@ -63,16 +64,19 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
6364
if err != nil {
6465
return fmt.Errorf("list affinity groups: %w", err)
6566
}
67+
items := result.GetItems()
6668

67-
if items := result.Items; items != nil {
68-
if model.Limit != nil && len(*items) > int(*model.Limit) {
69-
*items = (*items)[:*model.Limit]
70-
}
71-
return outputResult(params.Printer, *model, *items)
69+
projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd)
70+
if err != nil {
71+
params.Printer.Debug(print.ErrorLevel, "get project name: %v", err)
72+
projectLabel = model.ProjectId
7273
}
7374

74-
params.Printer.Outputln("No affinity groups found")
75-
return nil
75+
// Truncate Output
76+
if model.Limit != nil && len(items) > int(*model.Limit) {
77+
items = items[:*model.Limit]
78+
}
79+
return outputResult(params.Printer, model.OutputFormat, projectLabel, items)
7680
},
7781
}
7882
configureFlags(cmd)
@@ -110,13 +114,12 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel,
110114
return &model, nil
111115
}
112116

113-
func outputResult(p *print.Printer, model inputModel, items []iaas.AffinityGroup) error {
114-
var outputFormat string
115-
if model.GlobalFlagModel != nil {
116-
outputFormat = model.OutputFormat
117-
}
118-
117+
func outputResult(p *print.Printer, outputFormat, projectLabel string, items []iaas.AffinityGroup) error {
119118
return p.OutputResult(outputFormat, items, func() error {
119+
if len(items) == 0 {
120+
p.Outputf("No affinity groups found for project %q\n", projectLabel)
121+
return nil
122+
}
120123
table := tables.NewTable()
121124
table.SetHeader("ID", "NAME", "POLICY")
122125
for _, item := range items {

internal/cmd/affinity-groups/list/list_test.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,23 +141,40 @@ func TestBuildRequest(t *testing.T) {
141141
}
142142

143143
func TestOutputResult(t *testing.T) {
144+
type args struct {
145+
outputFormat string
146+
projectLabel string
147+
instances []iaas.AffinityGroup
148+
}
144149
tests := []struct {
145150
description string
146-
model inputModel
147-
response []iaas.AffinityGroup
151+
args args
148152
isValid bool
149153
}{
150154
{
151155
description: "empty",
152-
model: inputModel{},
153-
response: []iaas.AffinityGroup{},
156+
args: args{},
154157
isValid: true,
155158
},
159+
{
160+
description: "empty slice",
161+
args: args{
162+
instances: []iaas.AffinityGroup{},
163+
},
164+
isValid: true,
165+
},
166+
{
167+
description: "empty affinity group in slice",
168+
args: args{
169+
instances: []iaas.AffinityGroup{{}},
170+
},
171+
isValid: true,
172+
},
156173
}
157174
params := testparams.NewTestParams()
158175
for _, tt := range tests {
159176
t.Run(tt.description, func(t *testing.T) {
160-
err := outputResult(params.Printer, tt.model, tt.response)
177+
err := outputResult(params.Printer, tt.args.outputFormat, tt.args.projectLabel, tt.args.instances)
161178
if err != nil {
162179
if !tt.isValid {
163180
return

internal/cmd/image/list/list.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,18 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
8181

8282
// Call API
8383
request := buildRequest(ctx, model, apiClient)
84-
8584
response, err := request.Execute()
8685
if err != nil {
8786
return fmt.Errorf("list images: %w", err)
8887
}
88+
items := response.GetItems()
8989

90-
if items := response.GetItems(); len(items) == 0 {
91-
params.Printer.Info("No images found for project %q", projectLabel)
92-
} else {
93-
if model.Limit != nil && len(items) > int(*model.Limit) {
94-
items = (items)[:*model.Limit]
95-
}
96-
if err := outputResult(params.Printer, model.OutputFormat, items); err != nil {
97-
return fmt.Errorf("output images: %w", err)
98-
}
90+
// Truncate output
91+
if model.Limit != nil && len(items) > int(*model.Limit) {
92+
items = (items)[:*model.Limit]
93+
}
94+
if err := outputResult(params.Printer, model.OutputFormat, projectLabel, items); err != nil {
95+
return fmt.Errorf("output images: %w", err)
9996
}
10097

10198
return nil
@@ -149,8 +146,12 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APICli
149146
return request
150147
}
151148

152-
func outputResult(p *print.Printer, outputFormat string, items []iaas.Image) error {
149+
func outputResult(p *print.Printer, outputFormat, projectLabel string, items []iaas.Image) error {
153150
return p.OutputResult(outputFormat, items, func() error {
151+
if len(items) == 0 {
152+
p.Outputf("No images found for project %q\n", projectLabel)
153+
return nil
154+
}
154155
table := tables.NewTable()
155156
table.SetHeader("ID", "NAME", "OS", "ARCHITECTURE", "DISTRIBUTION", "VERSION", "SCOPE", "OWNER", "LABELS")
156157
for i := range items {

internal/cmd/image/list/list_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ func TestBuildRequest(t *testing.T) {
188188
func Test_outputResult(t *testing.T) {
189189
type args struct {
190190
outputFormat string
191+
projectLabel string
191192
items []iaas.Image
192193
}
193194
tests := []struct {
@@ -215,7 +216,7 @@ func Test_outputResult(t *testing.T) {
215216
params := testparams.NewTestParams()
216217
for _, tt := range tests {
217218
t.Run(tt.name, func(t *testing.T) {
218-
if err := outputResult(params.Printer, tt.args.outputFormat, tt.args.items); (err != nil) != tt.wantErr {
219+
if err := outputResult(params.Printer, tt.args.outputFormat, tt.args.projectLabel, tt.args.items); (err != nil) != tt.wantErr {
219220
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
220221
}
221222
})

internal/cmd/key-pair/list/list.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,9 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
7777
return fmt.Errorf("list key pairs: %w", err)
7878
}
7979

80-
if resp.Items == nil || len(*resp.Items) == 0 {
81-
params.Printer.Info("No key pairs found\n")
82-
return nil
83-
}
80+
items := resp.GetItems()
8481

85-
items := *resp.Items
82+
// Truncate output
8683
if model.Limit != nil && len(items) > int(*model.Limit) {
8784
items = items[:*model.Limit]
8885
}
@@ -130,6 +127,11 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APICli
130127

131128
func outputResult(p *print.Printer, outputFormat string, keyPairs []iaas.Keypair) error {
132129
return p.OutputResult(outputFormat, keyPairs, func() error {
130+
if len(keyPairs) == 0 {
131+
p.Outputf("No key pairs found\n")
132+
return nil
133+
}
134+
133135
table := tables.NewTable()
134136
table.SetHeader("KEY PAIR NAME", "LABELS", "FINGERPRINT", "CREATED AT", "UPDATED AT")
135137

internal/cmd/network-area/list/list.go

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const (
3232
type inputModel struct {
3333
*globalflags.GlobalFlagModel
3434
Limit *int64
35-
OrganizationId *string
35+
OrganizationId string
3636
LabelSelector *string
3737
}
3838

@@ -80,31 +80,30 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
8080
return fmt.Errorf("list network areas: %w", err)
8181
}
8282

83-
if resp.Items == nil || len(*resp.Items) == 0 {
84-
var orgLabel string
85-
rmApiClient, err := rmClient.ConfigureClient(params.Printer, params.CliVersion)
86-
if err == nil {
87-
orgLabel, err = rmUtils.GetOrganizationName(ctx, rmApiClient, *model.OrganizationId)
88-
if err != nil {
89-
params.Printer.Debug(print.ErrorLevel, "get organization name: %v", err)
90-
orgLabel = *model.OrganizationId
91-
} else if orgLabel == "" {
92-
orgLabel = *model.OrganizationId
93-
}
94-
} else {
95-
params.Printer.Debug(print.ErrorLevel, "configure resource manager client: %v", err)
83+
items := resp.GetItems()
84+
85+
var orgLabel string
86+
rmApiClient, err := rmClient.ConfigureClient(params.Printer, params.CliVersion)
87+
if err == nil {
88+
orgLabel, err = rmUtils.GetOrganizationName(ctx, rmApiClient, model.OrganizationId)
89+
if err != nil {
90+
params.Printer.Debug(print.ErrorLevel, "get organization name: %v", err)
91+
orgLabel = model.OrganizationId
9692
}
97-
params.Printer.Info("No STACKIT Network Areas found for organization %q\n", orgLabel)
98-
return nil
93+
} else {
94+
params.Printer.Debug(print.ErrorLevel, "configure resource manager client: %v", err)
95+
}
96+
97+
if orgLabel == "" {
98+
orgLabel = model.OrganizationId
9999
}
100100

101101
// Truncate output
102-
items := *resp.Items
103102
if model.Limit != nil && len(items) > int(*model.Limit) {
104103
items = items[:*model.Limit]
105104
}
106105

107-
return outputResult(params.Printer, model.OutputFormat, items)
106+
return outputResult(params.Printer, model.OutputFormat, orgLabel, items)
108107
},
109108
}
110109
configureFlags(cmd)
@@ -133,7 +132,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel,
133132
model := inputModel{
134133
GlobalFlagModel: globalFlags,
135134
Limit: limit,
136-
OrganizationId: flags.FlagToStringPointer(p, cmd, organizationIdFlag),
135+
OrganizationId: flags.FlagToStringValue(p, cmd, organizationIdFlag),
137136
LabelSelector: flags.FlagToStringPointer(p, cmd, labelSelectorFlag),
138137
}
139138

@@ -142,15 +141,20 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel,
142141
}
143142

144143
func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APIClient) iaas.ApiListNetworkAreasRequest {
145-
req := apiClient.ListNetworkAreas(ctx, *model.OrganizationId)
144+
req := apiClient.ListNetworkAreas(ctx, model.OrganizationId)
146145
if model.LabelSelector != nil {
147146
req = req.LabelSelector(*model.LabelSelector)
148147
}
149148
return req
150149
}
151150

152-
func outputResult(p *print.Printer, outputFormat string, networkAreas []iaas.NetworkArea) error {
151+
func outputResult(p *print.Printer, outputFormat, orgLabel string, networkAreas []iaas.NetworkArea) error {
153152
return p.OutputResult(outputFormat, networkAreas, func() error {
153+
if len(networkAreas) == 0 {
154+
p.Outputf("No STACKIT Network Areas found for organization %q\n", orgLabel)
155+
return nil
156+
}
157+
154158
table := tables.NewTable()
155159
table.SetHeader("ID", "Name", "# Attached Projects")
156160

internal/cmd/network-area/list/list_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel {
3939
GlobalFlagModel: &globalflags.GlobalFlagModel{
4040
Verbosity: globalflags.VerbosityDefault,
4141
},
42-
OrganizationId: &testOrganizationId,
42+
OrganizationId: testOrganizationId,
4343
Limit: utils.Ptr(int64(10)),
4444
LabelSelector: utils.Ptr(testLabelSelector),
4545
}
@@ -167,6 +167,7 @@ func TestBuildRequest(t *testing.T) {
167167
func TestOutputResult(t *testing.T) {
168168
type args struct {
169169
outputFormat string
170+
orgLabel string
170171
networkAreas []iaas.NetworkArea
171172
}
172173
tests := []struct {
@@ -197,7 +198,7 @@ func TestOutputResult(t *testing.T) {
197198
params := testparams.NewTestParams()
198199
for _, tt := range tests {
199200
t.Run(tt.name, func(t *testing.T) {
200-
if err := outputResult(params.Printer, tt.args.outputFormat, tt.args.networkAreas); (err != nil) != tt.wantErr {
201+
if err := outputResult(params.Printer, tt.args.outputFormat, tt.args.orgLabel, tt.args.networkAreas); (err != nil) != tt.wantErr {
201202
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
202203
}
203204
})

0 commit comments

Comments
 (0)