Skip to content

Commit 22b1f74

Browse files
authored
fix(mongodbflex): add nil pointer checks for cmd outputs (#614)
relates to STACKITCLI-104
1 parent 0f5e3a2 commit 22b1f74

File tree

22 files changed

+694
-54
lines changed

22 files changed

+694
-54
lines changed

internal/cmd/mongodbflex/backup/describe/describe.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func NewCmd(p *print.Printer) *cobra.Command {
8080
}
8181

8282
restoreJobState := mongoUtils.GetRestoreStatus(model.BackupId, restoreJobs)
83-
return outputResult(p, cmd, model.OutputFormat, restoreJobState, *resp.Item)
83+
return outputResult(p, model.OutputFormat, restoreJobState, *resp.Item)
8484
},
8585
}
8686
configureFlags(cmd)
@@ -125,14 +125,14 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *mongodbflex
125125
return req
126126
}
127127

128-
func outputResult(p *print.Printer, cmd *cobra.Command, outputFormat, restoreStatus string, backup mongodbflex.Backup) error {
128+
func outputResult(p *print.Printer, outputFormat, restoreStatus string, backup mongodbflex.Backup) error {
129129
switch outputFormat {
130130
case print.JSONOutputFormat:
131131
details, err := json.MarshalIndent(backup, "", " ")
132132
if err != nil {
133133
return fmt.Errorf("marshal MongoDB Flex backup: %w", err)
134134
}
135-
cmd.Println(string(details))
135+
p.Outputln(string(details))
136136

137137
return nil
138138
case print.YAMLOutputFormat:

internal/cmd/mongodbflex/backup/describe/describe_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,38 @@ func TestBuildRequest(t *testing.T) {
237237
})
238238
}
239239
}
240+
241+
func TestOutputResult(t *testing.T) {
242+
type args struct {
243+
outputFormat string
244+
backup mongodbflex.Backup
245+
restoreStatus string
246+
}
247+
tests := []struct {
248+
name string
249+
args args
250+
wantErr bool
251+
}{
252+
{
253+
name: "empty",
254+
args: args{},
255+
wantErr: false,
256+
},
257+
{
258+
name: "set backup",
259+
args: args{
260+
backup: mongodbflex.Backup{},
261+
},
262+
wantErr: false,
263+
},
264+
}
265+
p := print.NewPrinter()
266+
p.Cmd = NewCmd(p)
267+
for _, tt := range tests {
268+
t.Run(tt.name, func(t *testing.T) {
269+
if err := outputResult(p, tt.args.outputFormat, tt.args.restoreStatus, tt.args.backup); (err != nil) != tt.wantErr {
270+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
271+
}
272+
})
273+
}
274+
}

internal/cmd/mongodbflex/backup/list/list.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *mongodbflex
145145
}
146146

147147
func outputResult(p *print.Printer, outputFormat string, backups []mongodbflex.Backup, restoreJobs *mongodbflex.ListRestoreJobsResponse) error {
148+
if restoreJobs == nil {
149+
return fmt.Errorf("restore jobs is empty")
150+
}
151+
148152
switch outputFormat {
149153
case print.JSONOutputFormat:
150154
details, err := json.MarshalIndent(backups, "", " ")

internal/cmd/mongodbflex/backup/list/list_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,53 @@ func TestBuildRequest(t *testing.T) {
207207
})
208208
}
209209
}
210+
211+
func TestOutputResult(t *testing.T) {
212+
type args struct {
213+
outputFormat string
214+
backups []mongodbflex.Backup
215+
restoreJobs *mongodbflex.ListRestoreJobsResponse
216+
}
217+
tests := []struct {
218+
name string
219+
args args
220+
wantErr bool
221+
}{
222+
{
223+
name: "empty",
224+
args: args{},
225+
wantErr: true,
226+
},
227+
{
228+
name: "set empty backups",
229+
args: args{
230+
backups: []mongodbflex.Backup{},
231+
},
232+
wantErr: true,
233+
},
234+
{
235+
name: "set restore jobs",
236+
args: args{
237+
restoreJobs: &mongodbflex.ListRestoreJobsResponse{},
238+
},
239+
wantErr: false,
240+
},
241+
{
242+
name: "set restore jobs and empty backups",
243+
args: args{
244+
backups: []mongodbflex.Backup{},
245+
restoreJobs: &mongodbflex.ListRestoreJobsResponse{},
246+
},
247+
wantErr: false,
248+
},
249+
}
250+
p := print.NewPrinter()
251+
p.Cmd = NewCmd(p)
252+
for _, tt := range tests {
253+
t.Run(tt.name, func(t *testing.T) {
254+
if err := outputResult(p, tt.args.outputFormat, tt.args.backups, tt.args.restoreJobs); (err != nil) != tt.wantErr {
255+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
256+
}
257+
})
258+
}
259+
}

internal/cmd/mongodbflex/backup/restore-jobs/restore_jobs_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,44 @@ func TestBuildRequest(t *testing.T) {
207207
})
208208
}
209209
}
210+
211+
func TestOutputResult(t *testing.T) {
212+
type args struct {
213+
outputFormat string
214+
restoreJobs []mongodbflex.RestoreInstanceStatus
215+
}
216+
tests := []struct {
217+
name string
218+
args args
219+
wantErr bool
220+
}{
221+
{
222+
name: "empty",
223+
args: args{},
224+
wantErr: false,
225+
},
226+
{
227+
name: "set empty restore jobs",
228+
args: args{
229+
restoreJobs: []mongodbflex.RestoreInstanceStatus{},
230+
},
231+
wantErr: false,
232+
},
233+
{
234+
name: "set empty restore job",
235+
args: args{
236+
restoreJobs: []mongodbflex.RestoreInstanceStatus{{}},
237+
},
238+
wantErr: false,
239+
},
240+
}
241+
p := print.NewPrinter()
242+
p.Cmd = NewCmd(p)
243+
for _, tt := range tests {
244+
t.Run(tt.name, func(t *testing.T) {
245+
if err := outputResult(p, tt.args.outputFormat, tt.args.restoreJobs); (err != nil) != tt.wantErr {
246+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
247+
}
248+
})
249+
}
250+
}

internal/cmd/mongodbflex/backup/schedule/schedule.go

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *mongodbflex
104104
}
105105

106106
func outputResult(p *print.Printer, outputFormat string, instance *mongodbflex.Instance) error {
107+
if instance == nil {
108+
return fmt.Errorf("instance is nil")
109+
}
110+
107111
output := struct {
108112
BackupSchedule string `json:"backup_schedule"`
109113
DailySnaphotRetentionDays string `json:"daily_snapshot_retention_days"`
@@ -112,12 +116,14 @@ func outputResult(p *print.Printer, outputFormat string, instance *mongodbflex.I
112116
SnapshotRetentionDays string `json:"snapshot_retention_days"`
113117
WeeklySnapshotRetentionWeeks string `json:"weekly_snapshot_retention_weeks"`
114118
}{
115-
BackupSchedule: *instance.BackupSchedule,
116-
DailySnaphotRetentionDays: (*instance.Options)["dailySnapshotRetentionDays"],
117-
MonthlySnapshotRetentionMonths: (*instance.Options)["monthlySnapshotRetentionDays"],
118-
PointInTimeWindowHours: (*instance.Options)["pointInTimeWindowHours"],
119-
SnapshotRetentionDays: (*instance.Options)["snapshotRetentionDays"],
120-
WeeklySnapshotRetentionWeeks: (*instance.Options)["weeklySnapshotRetentionWeeks"],
119+
BackupSchedule: utils.PtrString(instance.BackupSchedule),
120+
}
121+
if instance.Options != nil {
122+
output.DailySnaphotRetentionDays = (*instance.Options)["dailySnapshotRetentionDays"]
123+
output.MonthlySnapshotRetentionMonths = (*instance.Options)["monthlySnapshotRetentionDays"]
124+
output.PointInTimeWindowHours = (*instance.Options)["pointInTimeWindowHours"]
125+
output.SnapshotRetentionDays = (*instance.Options)["snapshotRetentionDays"]
126+
output.WeeklySnapshotRetentionWeeks = (*instance.Options)["weeklySnapshotRetentionWeeks"]
121127
}
122128

123129
switch outputFormat {
@@ -139,20 +145,19 @@ func outputResult(p *print.Printer, outputFormat string, instance *mongodbflex.I
139145
return nil
140146
default:
141147
table := tables.NewTable()
142-
table.AddRow("BACKUP SCHEDULE (UTC)", utils.PtrString(instance.BackupSchedule))
148+
table.AddRow("BACKUP SCHEDULE (UTC)", output.BackupSchedule)
143149
table.AddSeparator()
144-
if instance.Options != nil {
145-
table.AddRow("DAILY SNAPSHOT RETENTION (DAYS)", (*instance.Options)["dailySnapshotRetentionDays"])
146-
table.AddSeparator()
147-
table.AddRow("MONTHLY SNAPSHOT RETENTION (MONTHS)", (*instance.Options)["monthlySnapshotRetentionMonths"])
148-
table.AddSeparator()
149-
table.AddRow("POINT IN TIME WINDOW (HOURS)", (*instance.Options)["pointInTimeWindowHours"])
150-
table.AddSeparator()
151-
table.AddRow("SNAPSHOT RETENTION (DAYS)", (*instance.Options)["snapshotRetentionDays"])
152-
table.AddSeparator()
153-
table.AddRow("WEEKLY SNAPSHOT RETENTION (WEEKS)", (*instance.Options)["weeklySnapshotRetentionWeeks"])
154-
table.AddSeparator()
155-
}
150+
table.AddRow("DAILY SNAPSHOT RETENTION (DAYS)", output.DailySnaphotRetentionDays)
151+
table.AddSeparator()
152+
table.AddRow("MONTHLY SNAPSHOT RETENTION (MONTHS)", output.MonthlySnapshotRetentionMonths)
153+
table.AddSeparator()
154+
table.AddRow("POINT IN TIME WINDOW (HOURS)", output.PointInTimeWindowHours)
155+
table.AddSeparator()
156+
table.AddRow("SNAPSHOT RETENTION (DAYS)", output.SnapshotRetentionDays)
157+
table.AddSeparator()
158+
table.AddRow("WEEKLY SNAPSHOT RETENTION (WEEKS)", output.WeeklySnapshotRetentionWeeks)
159+
table.AddSeparator()
160+
156161
err := table.Display(p)
157162
if err != nil {
158163
return fmt.Errorf("render table: %w", err)

internal/cmd/mongodbflex/backup/schedule/schedule_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,37 @@ func TestBuildRequest(t *testing.T) {
193193
})
194194
}
195195
}
196+
197+
func TestOutputResult(t *testing.T) {
198+
type args struct {
199+
outputFormat string
200+
instance *mongodbflex.Instance
201+
}
202+
tests := []struct {
203+
name string
204+
args args
205+
wantErr bool
206+
}{
207+
{
208+
name: "empty",
209+
args: args{},
210+
wantErr: true,
211+
},
212+
{
213+
name: "set empty instance",
214+
args: args{
215+
instance: &mongodbflex.Instance{},
216+
},
217+
wantErr: false,
218+
},
219+
}
220+
p := print.NewPrinter()
221+
p.Cmd = NewCmd(p)
222+
for _, tt := range tests {
223+
t.Run(tt.name, func(t *testing.T) {
224+
if err := outputResult(p, tt.args.outputFormat, tt.args.instance); (err != nil) != tt.wantErr {
225+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
226+
}
227+
})
228+
}
229+
}

internal/cmd/mongodbflex/instance/create/create.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88

99
"github.com/goccy/go-yaml"
10+
"github.com/spf13/cobra"
1011
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
1112
cliErr "github.com/stackitcloud/stackit-cli/internal/pkg/errors"
1213
"github.com/stackitcloud/stackit-cli/internal/pkg/examples"
@@ -18,8 +19,6 @@ import (
1819
mongodbflexUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/mongodbflex/utils"
1920
"github.com/stackitcloud/stackit-cli/internal/pkg/spinner"
2021
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
21-
22-
"github.com/spf13/cobra"
2322
"github.com/stackitcloud/stackit-sdk-go/services/mongodbflex"
2423
"github.com/stackitcloud/stackit-sdk-go/services/mongodbflex/wait"
2524
)
@@ -133,7 +132,7 @@ func NewCmd(p *print.Printer) *cobra.Command {
133132
s.Stop()
134133
}
135134

136-
return outputResult(p, model, projectLabel, resp)
135+
return outputResult(p, model.OutputFormat, model.Async, projectLabel, resp)
137136
},
138137
}
139138
configureFlags(cmd)
@@ -273,8 +272,12 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient MongoDBFlexC
273272
return req, nil
274273
}
275274

276-
func outputResult(p *print.Printer, model *inputModel, projectLabel string, resp *mongodbflex.CreateInstanceResponse) error {
277-
switch model.OutputFormat {
275+
func outputResult(p *print.Printer, outputFormat string, async bool, projectLabel string, resp *mongodbflex.CreateInstanceResponse) error {
276+
if resp == nil {
277+
return fmt.Errorf("create instance response is nil")
278+
}
279+
280+
switch outputFormat {
278281
case print.JSONOutputFormat:
279282
details, err := json.MarshalIndent(resp, "", " ")
280283
if err != nil {
@@ -293,7 +296,7 @@ func outputResult(p *print.Printer, model *inputModel, projectLabel string, resp
293296
return nil
294297
default:
295298
operationState := "Created"
296-
if model.Async {
299+
if async {
297300
operationState = "Triggered creation of"
298301
}
299302
p.Outputf("%s instance for project %q. Instance ID: %s\n", operationState, projectLabel, utils.PtrString(resp.Id))

internal/cmd/mongodbflex/instance/create/create_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,3 +546,39 @@ func TestBuildRequest(t *testing.T) {
546546
})
547547
}
548548
}
549+
550+
func TestOutputResult(t *testing.T) {
551+
type args struct {
552+
outputFormat string
553+
async bool
554+
projectLabel string
555+
createInstanceResponse *mongodbflex.CreateInstanceResponse
556+
}
557+
tests := []struct {
558+
name string
559+
args args
560+
wantErr bool
561+
}{
562+
{
563+
name: "empty",
564+
args: args{},
565+
wantErr: true,
566+
},
567+
{
568+
name: "set empty create instance response",
569+
args: args{
570+
createInstanceResponse: &mongodbflex.CreateInstanceResponse{},
571+
},
572+
wantErr: false,
573+
},
574+
}
575+
p := print.NewPrinter()
576+
p.Cmd = NewCmd(p)
577+
for _, tt := range tests {
578+
t.Run(tt.name, func(t *testing.T) {
579+
if err := outputResult(p, tt.args.outputFormat, tt.args.async, tt.args.projectLabel, tt.args.createInstanceResponse); (err != nil) != tt.wantErr {
580+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
581+
}
582+
})
583+
}
584+
}

0 commit comments

Comments
 (0)