Skip to content

Commit afdc246

Browse files
authored
[v8] Enhance "service" command for multiple service bindings (#3660)
* Enhance "service" command for multiple service bindings * in the "bound apps" section, show also multiple service bindings for an app * add binding guid and created_at timestamp to table * sort by 1. name 2. created_at * Update integration tests for "service" command multi bindings support
1 parent e8e7a0c commit afdc246

File tree

5 files changed

+53
-15
lines changed

5 files changed

+53
-15
lines changed

command/v7/service_command.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package v7
22

33
import (
44
"fmt"
5+
"sort"
56
"strconv"
67

78
"code.cloudfoundry.org/cli/v8/actor/v7action"
@@ -240,13 +241,25 @@ func (cmd ServiceCommand) displayBoundApps(serviceInstanceWithDetails v7action.S
240241
return
241242
}
242243

243-
table := [][]string{{"name", "binding name", "status", "message"}}
244-
for _, app := range serviceInstanceWithDetails.BoundApps {
244+
table := [][]string{{"name", "binding name", "status", "message", "guid", "created_at"}}
245+
246+
bindings := serviceInstanceWithDetails.BoundApps
247+
// sort by app name, then by created at descending
248+
sort.Slice(bindings, func(i, j int) bool {
249+
if bindings[i].AppName == bindings[j].AppName {
250+
return bindings[i].CreatedAt > bindings[j].CreatedAt
251+
}
252+
return bindings[i].AppName < bindings[j].AppName
253+
})
254+
255+
for _, app := range bindings {
245256
table = append(table, []string{
246257
app.AppName,
247258
app.Name,
248259
fmt.Sprintf("%s %s", app.LastOperation.Type, app.LastOperation.State),
249260
app.LastOperation.Description,
261+
app.GUID,
262+
app.CreatedAt,
250263
})
251264
}
252265

command/v7/service_command_test.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,19 +271,23 @@ var _ = Describe("service command", func() {
271271
{
272272
Name: "named-binding",
273273
AppName: "app-1",
274+
GUID: "guid-1",
274275
LastOperation: resources.LastOperation{
275276
Type: resources.CreateOperation,
276277
State: resources.OperationSucceeded,
277278
Description: "great",
278279
},
280+
CreatedAt: "created-at-1",
279281
},
280282
{
281283
AppName: "app-2",
284+
GUID: "guid-2",
282285
LastOperation: resources.LastOperation{
283286
Type: resources.UpdateOperation,
284287
State: resources.OperationFailed,
285288
Description: "sorry",
286289
},
290+
CreatedAt: "created-at-2",
287291
},
288292
},
289293
},
@@ -295,9 +299,9 @@ var _ = Describe("service command", func() {
295299
It("prints the bound apps table", func() {
296300
Expect(testUI.Out).To(SatisfyAll(
297301
Say(`Showing bound apps:\n`),
298-
Say(` name\s+binding name\s+status\s+message\n`),
299-
Say(` app-1\s+named-binding\s+create succeeded\s+great\n`),
300-
Say(` app-2\s+update failed\s+sorry\n`),
302+
Say(` name\s+binding name\s+status\s+message\s+guid\s+created_at\n`),
303+
Say(` app-1\s+named-binding\s+create succeeded\s+great\s+guid-1\s+created-at-1\n`),
304+
Say(` app-2\s+update failed\s+sorry\s+guid-2\s+created-at-2\n`),
301305
))
302306
})
303307
})
@@ -704,19 +708,34 @@ var _ = Describe("service command", func() {
704708
{
705709
Name: "named-binding",
706710
AppName: "app-1",
711+
GUID: "guid-1",
707712
LastOperation: resources.LastOperation{
708713
Type: resources.CreateOperation,
709714
State: resources.OperationSucceeded,
710715
Description: "great",
711716
},
717+
CreatedAt: "created-at-1",
712718
},
713719
{
714720
AppName: "app-2",
721+
GUID: "guid-2",
715722
LastOperation: resources.LastOperation{
716723
Type: resources.UpdateOperation,
717724
State: resources.OperationFailed,
718725
Description: "sorry",
719726
},
727+
CreatedAt: "created-at-2",
728+
},
729+
{
730+
Name: "named-binding",
731+
AppName: "app-1",
732+
GUID: "guid-3",
733+
LastOperation: resources.LastOperation{
734+
Type: resources.CreateOperation,
735+
State: resources.OperationSucceeded,
736+
Description: "great",
737+
},
738+
CreatedAt: "created-at-2",
720739
},
721740
},
722741
},
@@ -728,9 +747,10 @@ var _ = Describe("service command", func() {
728747
It("prints the bound apps table", func() {
729748
Expect(testUI.Out).To(SatisfyAll(
730749
Say(`Showing bound apps:\n`),
731-
Say(`name\s+binding name\s+status\s+message\n`),
732-
Say(`app-1\s+named-binding\s+create succeeded\s+great\n`),
733-
Say(`app-2\s+update failed\s+sorry\n`),
750+
Say(`name\s+binding name\s+status\s+message\s+guid\s+created_at\n`),
751+
Say(`app-1\s+named-binding\s+create succeeded\s+great\s+guid-3\s+created-at-2\n`),
752+
Say(`app-1\s+named-binding\s+create succeeded\s+great\s+guid-1\s+created-at-1\n`),
753+
Say(`app-2\s+update failed\s+sorry\s+guid-2\s+created-at-2\n`),
734754
))
735755
})
736756
})

integration/v7/isolated/service_command_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,9 @@ var _ = Describe("service command", func() {
182182

183183
Expect(session).To(SatisfyAll(
184184
Say(`Showing bound apps:\n`),
185-
Say(`name\s+binding name\s+status\s+message\n`),
186-
Say(`%s\s+%s\s+create succeeded\s*\n`, appName1, bindingName1),
187-
Say(`%s\s+%s\s+create succeeded\s*\n`, appName2, bindingName2),
185+
Say(`name\s+binding name\s+status\s+message\s+guid\s+created_at\n`),
186+
Say(`%s\s+%s\s+create succeeded\s+%s\s+%s\n`, appName1, bindingName1, helpers.GUIDRegex, helpers.TimestampRegex),
187+
Say(`%s\s+%s\s+create succeeded\s+%s\s+%s\n`, appName2, bindingName2, helpers.GUIDRegex, helpers.TimestampRegex),
188188
))
189189
})
190190
})
@@ -528,9 +528,9 @@ var _ = Describe("service command", func() {
528528

529529
Expect(session).To(SatisfyAll(
530530
Say(`Showing bound apps:\n`),
531-
Say(`name\s+binding name\s+status\s+message\n`),
532-
Say(`%s\s+%s\s+create succeeded\s+very happy service\n`, appName1, bindingName1),
533-
Say(`%s\s+%s\s+create succeeded\s+very happy service\n`, appName2, bindingName2),
531+
Say(`name\s+binding name\s+status\s+message\s+guid\s+created_at\n`),
532+
Say(`%s\s+%s\s+create succeeded\s+very happy service\s+%s\s+%s\n`, appName1, bindingName1, helpers.GUIDRegex, helpers.TimestampRegex),
533+
Say(`%s\s+%s\s+create succeeded\s+very happy service\s+%s\s+%s\n`, appName2, bindingName2, helpers.GUIDRegex, helpers.TimestampRegex),
534534
))
535535
})
536536
})

resources/service_credential_binding_resource.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ type ServiceCredentialBinding struct {
3131
LastOperation LastOperation `jsonry:"last_operation"`
3232
// Parameters can be specified when creating a binding
3333
Parameters types.OptionalObject `jsonry:"parameters"`
34+
// CreatedAt timestamp when the binding was created (useful for distinguishing multiple bindings)
35+
CreatedAt string `json:"created_at,omitempty"`
3436
}
3537

3638
func (s ServiceCredentialBinding) MarshalJSON() ([]byte, error) {

resources/service_credential_binding_resource_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ var _ = Describe("service credential binding resource", func() {
6060
}
6161
}`,
6262
),
63+
Entry("created_at", ServiceCredentialBinding{CreatedAt: "fake-created-at"}, `{"created_at": "fake-created-at"}`),
6364
Entry(
6465
"everything",
6566
ServiceCredentialBinding{
@@ -71,6 +72,7 @@ var _ = Describe("service credential binding resource", func() {
7172
Parameters: types.NewOptionalObject(map[string]interface{}{
7273
"foo": "bar",
7374
}),
75+
CreatedAt: "fake-created-at",
7476
},
7577
`{
7678
"type": "app",
@@ -90,7 +92,8 @@ var _ = Describe("service credential binding resource", func() {
9092
},
9193
"parameters": {
9294
"foo": "bar"
93-
}
95+
},
96+
"created_at": "fake-created-at"
9497
}`,
9598
),
9699
)

0 commit comments

Comments
 (0)