Skip to content

Commit ca7fa42

Browse files
authored
fix(logme): add nil pointer checks for cmd outputs (#619)
relates to STACKITCLI-102
1 parent a86c936 commit ca7fa42

File tree

13 files changed

+319
-29
lines changed

13 files changed

+319
-29
lines changed

internal/cmd/logme/credentials/create/create.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func NewCmd(p *print.Printer) *cobra.Command {
7878
return fmt.Errorf("create LogMe credentials: %w", err)
7979
}
8080

81-
return outputResult(p, model, instanceLabel, resp)
81+
return outputResult(p, model.OutputFormat, model.ShowPassword, instanceLabel, resp)
8282
},
8383
}
8484
configureFlags(cmd)
@@ -122,11 +122,15 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *logme.APICl
122122
return req
123123
}
124124

125-
func outputResult(p *print.Printer, model *inputModel, instanceLabel string, resp *logme.CredentialsResponse) error {
126-
if !model.ShowPassword {
125+
func outputResult(p *print.Printer, outputFormat string, showPassword bool, instanceLabel string, resp *logme.CredentialsResponse) error {
126+
if resp == nil {
127+
return fmt.Errorf("credentials response is empty")
128+
}
129+
130+
if !showPassword && resp.HasRaw() && resp.Raw.Credentials != nil {
127131
resp.Raw.Credentials.Password = utils.Ptr("hidden")
128132
}
129-
switch model.OutputFormat {
133+
switch outputFormat {
130134
case print.JSONOutputFormat:
131135
details, err := json.MarshalIndent(resp, "", " ")
132136
if err != nil {
@@ -150,7 +154,7 @@ func outputResult(p *print.Printer, model *inputModel, instanceLabel string, res
150154
if username := resp.Raw.Credentials.Username; username != nil && *username != "" {
151155
p.Outputf("Username: %s\n", utils.PtrString(username))
152156
}
153-
if !model.ShowPassword {
157+
if !showPassword {
154158
p.Outputf("Password: <hidden>\n")
155159
} else {
156160
p.Outputf("Password: %s\n", utils.PtrString(resp.Raw.Credentials.Password))

internal/cmd/logme/credentials/create/create_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,39 @@ func TestBuildRequest(t *testing.T) {
200200
})
201201
}
202202
}
203+
204+
func TestOutputResult(t *testing.T) {
205+
type args struct {
206+
outputFormat string
207+
showPassword bool
208+
instanceLabel string
209+
credentials *logme.CredentialsResponse
210+
}
211+
tests := []struct {
212+
name string
213+
args args
214+
wantErr bool
215+
}{
216+
{
217+
name: "empty",
218+
args: args{},
219+
wantErr: true,
220+
},
221+
{
222+
name: "set empty credentials",
223+
args: args{
224+
credentials: &logme.CredentialsResponse{},
225+
},
226+
wantErr: false,
227+
},
228+
}
229+
p := print.NewPrinter()
230+
p.Cmd = NewCmd(p)
231+
for _, tt := range tests {
232+
t.Run(tt.name, func(t *testing.T) {
233+
if err := outputResult(p, tt.args.outputFormat, tt.args.showPassword, tt.args.instanceLabel, tt.args.credentials); (err != nil) != tt.wantErr {
234+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
235+
}
236+
})
237+
}
238+
}

internal/cmd/logme/credentials/describe/describe.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *logme.APICl
112112
}
113113

114114
func outputResult(p *print.Printer, outputFormat string, credentials *logme.CredentialsResponse) error {
115+
if credentials == nil {
116+
return fmt.Errorf("credentials is nil")
117+
}
118+
115119
switch outputFormat {
116120
case print.JSONOutputFormat:
117121
details, err := json.MarshalIndent(credentials, "", " ")

internal/cmd/logme/credentials/describe/describe_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,37 @@ func TestBuildRequest(t *testing.T) {
243243
})
244244
}
245245
}
246+
247+
func TestOutputResult(t *testing.T) {
248+
type args struct {
249+
outputFormat string
250+
credentials *logme.CredentialsResponse
251+
}
252+
tests := []struct {
253+
name string
254+
args args
255+
wantErr bool
256+
}{
257+
{
258+
name: "empty",
259+
args: args{},
260+
wantErr: true,
261+
},
262+
{
263+
name: "set empty credentials",
264+
args: args{
265+
credentials: &logme.CredentialsResponse{},
266+
},
267+
wantErr: false,
268+
},
269+
}
270+
p := print.NewPrinter()
271+
p.Cmd = NewCmd(p)
272+
for _, tt := range tests {
273+
t.Run(tt.name, func(t *testing.T) {
274+
if err := outputResult(p, tt.args.outputFormat, tt.args.credentials); (err != nil) != tt.wantErr {
275+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
276+
}
277+
})
278+
}
279+
}

internal/cmd/logme/credentials/list/list_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+
credentials []logme.CredentialsListItem
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 credentials slice",
228+
args: args{
229+
credentials: []logme.CredentialsListItem{},
230+
},
231+
wantErr: false,
232+
},
233+
{
234+
name: "set empty credential in credentials slice",
235+
args: args{
236+
credentials: []logme.CredentialsListItem{{}},
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.credentials); (err != nil) != tt.wantErr {
246+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
247+
}
248+
})
249+
}
250+
}

internal/cmd/logme/instance/create/create.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func NewCmd(p *print.Printer) *cobra.Command {
125125
s.Stop()
126126
}
127127

128-
return outputResult(p, model, projectLabel, resp)
128+
return outputResult(p, model.OutputFormat, model.Async, projectLabel, resp)
129129
},
130130
}
131131
configureFlags(cmd)
@@ -251,8 +251,12 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient logMeClient)
251251
return req, nil
252252
}
253253

254-
func outputResult(p *print.Printer, model *inputModel, projectLabel string, resp *logme.CreateInstanceResponse) error {
255-
switch model.OutputFormat {
254+
func outputResult(p *print.Printer, outputFormat string, async bool, projectLabel string, resp *logme.CreateInstanceResponse) error {
255+
if resp == nil {
256+
return fmt.Errorf("response is nil")
257+
}
258+
259+
switch outputFormat {
256260
case print.JSONOutputFormat:
257261
details, err := json.MarshalIndent(resp, "", " ")
258262
if err != nil {
@@ -271,7 +275,7 @@ func outputResult(p *print.Printer, model *inputModel, projectLabel string, resp
271275
return nil
272276
default:
273277
operationState := "Created"
274-
if model.Async {
278+
if async {
275279
operationState = "Triggered creation of"
276280
}
277281
p.Outputf("%s instance for project %q. Instance ID: %s\n", operationState, projectLabel, utils.PtrString(resp.InstanceId))

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,3 +463,39 @@ func TestBuildRequest(t *testing.T) {
463463
})
464464
}
465465
}
466+
467+
func TestOutputResult(t *testing.T) {
468+
type args struct {
469+
outputFormat string
470+
async bool
471+
projectLabel string
472+
resp *logme.CreateInstanceResponse
473+
}
474+
tests := []struct {
475+
name string
476+
args args
477+
wantErr bool
478+
}{
479+
{
480+
name: "empty",
481+
args: args{},
482+
wantErr: true,
483+
},
484+
{
485+
name: "empty response",
486+
args: args{
487+
resp: &logme.CreateInstanceResponse{},
488+
},
489+
wantErr: false,
490+
},
491+
}
492+
p := print.NewPrinter()
493+
p.Cmd = NewCmd(p)
494+
for _, tt := range tests {
495+
t.Run(tt.name, func(t *testing.T) {
496+
if err := outputResult(p, tt.args.outputFormat, tt.args.async, tt.args.projectLabel, tt.args.resp); (err != nil) != tt.wantErr {
497+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
498+
}
499+
})
500+
}
501+
}

internal/cmd/logme/instance/describe/describe.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *logme.APICl
100100
}
101101

102102
func outputResult(p *print.Printer, outputFormat string, instance *logme.Instance) error {
103+
if instance == nil {
104+
return fmt.Errorf("instance is nil")
105+
}
106+
103107
switch outputFormat {
104108
case print.JSONOutputFormat:
105109
details, err := json.MarshalIndent(instance, "", " ")
@@ -123,16 +127,18 @@ func outputResult(p *print.Printer, outputFormat string, instance *logme.Instanc
123127
table.AddSeparator()
124128
table.AddRow("NAME", utils.PtrString(instance.Name))
125129
table.AddSeparator()
126-
table.AddRow("LAST OPERATION TYPE", utils.PtrString(instance.LastOperation.Type))
127-
table.AddSeparator()
128-
table.AddRow("LAST OPERATION STATE", utils.PtrString(instance.LastOperation.State))
129-
table.AddSeparator()
130+
if instance.LastOperation != nil {
131+
table.AddRow("LAST OPERATION TYPE", utils.PtrString(instance.LastOperation.Type))
132+
table.AddSeparator()
133+
table.AddRow("LAST OPERATION STATE", utils.PtrString(instance.LastOperation.State))
134+
table.AddSeparator()
135+
}
130136
table.AddRow("PLAN ID", utils.PtrString(instance.PlanId))
131137
// Only show ACL if it's present and not empty
132-
acl := (*instance.Parameters)[aclParameterKey]
133-
aclStr, ok := acl.(string)
134-
if ok {
135-
if aclStr != "" {
138+
if instance.Parameters != nil {
139+
acl := (*instance.Parameters)[aclParameterKey]
140+
aclStr, ok := acl.(string)
141+
if ok && aclStr != "" {
136142
table.AddSeparator()
137143
table.AddRow("ACL", aclStr)
138144
}

internal/cmd/logme/instance/describe/describe_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,37 @@ func TestBuildRequest(t *testing.T) {
216216
})
217217
}
218218
}
219+
220+
func TestOutputResult(t *testing.T) {
221+
type args struct {
222+
outputFormat string
223+
instance *logme.Instance
224+
}
225+
tests := []struct {
226+
name string
227+
args args
228+
wantErr bool
229+
}{
230+
{
231+
name: "empty",
232+
args: args{},
233+
wantErr: true,
234+
},
235+
{
236+
name: "empty instance",
237+
args: args{
238+
instance: &logme.Instance{},
239+
},
240+
wantErr: false,
241+
},
242+
}
243+
p := print.NewPrinter()
244+
p.Cmd = NewCmd(p)
245+
for _, tt := range tests {
246+
t.Run(tt.name, func(t *testing.T) {
247+
if err := outputResult(p, tt.args.outputFormat, tt.args.instance); (err != nil) != tt.wantErr {
248+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
249+
}
250+
})
251+
}
252+
}

internal/cmd/logme/instance/list/list.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,18 @@ func outputResult(p *print.Printer, outputFormat string, instances []logme.Insta
152152
table.SetHeader("ID", "NAME", "LAST OPERATION TYPE", "LAST OPERATION STATE")
153153
for i := range instances {
154154
instance := instances[i]
155+
156+
lastOperationType, lastOperationState := "", ""
157+
if instance.LastOperation != nil {
158+
lastOperationType = utils.PtrString(instance.LastOperation.Type)
159+
lastOperationState = utils.PtrString(instance.LastOperation.State)
160+
}
161+
155162
table.AddRow(
156163
utils.PtrString(instance.InstanceId),
157164
utils.PtrString(instance.Name),
158-
utils.PtrString(instance.LastOperation.Type),
159-
utils.PtrString(instance.LastOperation.State),
165+
lastOperationType,
166+
lastOperationState,
160167
)
161168
}
162169
err := table.Display(p)

0 commit comments

Comments
 (0)