Skip to content

Commit 0578af7

Browse files
authored
Add --used and --unused flags to load-balancer list (#308)
* initial implementation * add testing, finish functionality * generate docs, minor improvements * more testing * refactor implementation, simplify RunE * remove unused func * address PR comments * generate-docs * change filtercredentials to use enum for operation type * address PR comments
1 parent b2e05e3 commit 0578af7

File tree

8 files changed

+632
-17
lines changed

8 files changed

+632
-17
lines changed

docs/stackit_load-balancer_observability-credentials.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ stackit load-balancer observability-credentials [flags]
3232
* [stackit load-balancer observability-credentials add](./stackit_load-balancer_observability-credentials_add.md) - Adds observability credentials to Load Balancer
3333
* [stackit load-balancer observability-credentials delete](./stackit_load-balancer_observability-credentials_delete.md) - Deletes observability credentials for Load Balancer
3434
* [stackit load-balancer observability-credentials describe](./stackit_load-balancer_observability-credentials_describe.md) - Shows details of observability credentials for Load Balancer
35-
* [stackit load-balancer observability-credentials list](./stackit_load-balancer_observability-credentials_list.md) - Lists all observability credentials for Load Balancer
35+
* [stackit load-balancer observability-credentials list](./stackit_load-balancer_observability-credentials_list.md) - Lists observability credentials for Load Balancer
3636
* [stackit load-balancer observability-credentials update](./stackit_load-balancer_observability-credentials_update.md) - Updates observability credentials for Load Balancer
3737

docs/stackit_load-balancer_observability-credentials_list.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
## stackit load-balancer observability-credentials list
22

3-
Lists all observability credentials for Load Balancer
3+
Lists observability credentials for Load Balancer
44

55
### Synopsis
66

7-
Lists all observability credentials for Load Balancer.
7+
Lists observability credentials for Load Balancer.
88

99
```
1010
stackit load-balancer observability-credentials list [flags]
@@ -13,13 +13,19 @@ stackit load-balancer observability-credentials list [flags]
1313
### Examples
1414

1515
```
16-
List all observability credentials for Load Balancer
16+
List all Load Balancer observability credentials
1717
$ stackit load-balancer observability-credentials list
1818
19-
List all observability credentials for Load Balancer in JSON format
19+
List all observability credentials being used by Load Balancer
20+
$ stackit load-balancer observability-credentials list --used
21+
22+
List all observability credentials not being used by Load Balancer
23+
$ stackit load-balancer observability-credentials list --unused
24+
25+
List all Load Balancer observability credentials in JSON format
2026
$ stackit load-balancer observability-credentials list --output-format json
2127
22-
List up to 10 observability credentials for Load Balancer
28+
List up to 10 Load Balancer observability credentials
2329
$ stackit load-balancer observability-credentials list --limit 10
2430
```
2531

@@ -28,6 +34,8 @@ stackit load-balancer observability-credentials list [flags]
2834
```
2935
-h, --help Help for "stackit load-balancer observability-credentials list"
3036
--limit int Maximum number of entries to list
37+
--unused List only credentials not being used by a Load Balancer
38+
--used List only credentials being used by a Load Balancer
3139
```
3240

3341
### Options inherited from parent commands

internal/cmd/load-balancer/observability-credentials/list/list.go

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
1414
"github.com/stackitcloud/stackit-cli/internal/pkg/projectname"
1515
"github.com/stackitcloud/stackit-cli/internal/pkg/services/load-balancer/client"
16+
"github.com/stackitcloud/stackit-cli/internal/pkg/services/load-balancer/utils"
1617
"github.com/stackitcloud/stackit-cli/internal/pkg/tables"
1718

1819
"github.com/spf13/cobra"
@@ -22,28 +23,38 @@ import (
2223
const (
2324
instanceIdFlag = "instance-id"
2425
limitFlag = "limit"
26+
usedFlag = "used"
27+
unusedFlag = "unused"
2528
)
2629

2730
type inputModel struct {
2831
*globalflags.GlobalFlagModel
29-
Limit *int64
32+
Limit *int64
33+
Used bool
34+
Unused bool
3035
}
3136

3237
func NewCmd(p *print.Printer) *cobra.Command {
3338
cmd := &cobra.Command{
3439
Use: "list",
35-
Short: "Lists all observability credentials for Load Balancer",
36-
Long: "Lists all observability credentials for Load Balancer.",
40+
Short: "Lists observability credentials for Load Balancer",
41+
Long: "Lists observability credentials for Load Balancer.",
3742
Args: args.NoArgs,
3843
Example: examples.Build(
3944
examples.NewExample(
40-
`List all observability credentials for Load Balancer`,
45+
`List all Load Balancer observability credentials`,
4146
"$ stackit load-balancer observability-credentials list"),
4247
examples.NewExample(
43-
`List all observability credentials for Load Balancer in JSON format`,
48+
`List all observability credentials being used by Load Balancer`,
49+
"$ stackit load-balancer observability-credentials list --used"),
50+
examples.NewExample(
51+
`List all observability credentials not being used by Load Balancer`,
52+
"$ stackit load-balancer observability-credentials list --unused"),
53+
examples.NewExample(
54+
`List all Load Balancer observability credentials in JSON format`,
4455
"$ stackit load-balancer observability-credentials list --output-format json"),
4556
examples.NewExample(
46-
`List up to 10 observability credentials for Load Balancer`,
57+
`List up to 10 Load Balancer observability credentials`,
4758
"$ stackit load-balancer observability-credentials list --limit 10"),
4859
),
4960
RunE: func(cmd *cobra.Command, args []string) error {
@@ -72,13 +83,23 @@ func NewCmd(p *print.Printer) *cobra.Command {
7283
return fmt.Errorf("list Load Balancer observability credentials: %w", err)
7384
}
7485
credentialsPtr := resp.Credentials
75-
if credentialsPtr == nil || (credentialsPtr != nil && len(*credentialsPtr) == 0) {
86+
if credentialsPtr == nil || len(*credentialsPtr) == 0 {
7687
p.Info("No observability credentials found for Load Balancer on project %q\n", projectLabel)
7788
return nil
7889
}
7990

8091
credentials := *credentialsPtr
8192

93+
filterOp, err := getFilterOp(model.Used, model.Unused)
94+
if err != nil {
95+
return err
96+
}
97+
98+
credentials, err = utils.FilterCredentials(ctx, apiClient, credentials, model.ProjectId, filterOp)
99+
if err != nil {
100+
return fmt.Errorf("filter credentials: %w", err)
101+
}
102+
82103
// Truncate output
83104
if model.Limit != nil && len(credentials) > int(*model.Limit) {
84105
credentials = credentials[:*model.Limit]
@@ -92,6 +113,10 @@ func NewCmd(p *print.Printer) *cobra.Command {
92113

93114
func configureFlags(cmd *cobra.Command) {
94115
cmd.Flags().Int64(limitFlag, 0, "Maximum number of entries to list")
116+
cmd.Flags().Bool(usedFlag, false, "List only credentials being used by a Load Balancer")
117+
cmd.Flags().Bool(unusedFlag, false, "List only credentials not being used by a Load Balancer")
118+
119+
cmd.MarkFlagsMutuallyExclusive(usedFlag, unusedFlag)
95120
}
96121

97122
func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) {
@@ -111,6 +136,8 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) {
111136
model := inputModel{
112137
GlobalFlagModel: globalFlags,
113138
Limit: limit,
139+
Used: flags.FlagToBoolValue(p, cmd, usedFlag),
140+
Unused: flags.FlagToBoolValue(p, cmd, unusedFlag),
114141
}
115142

116143
if p.IsVerbosityDebug() {
@@ -155,3 +182,20 @@ func outputResult(p *print.Printer, outputFormat string, credentials []loadbalan
155182
return nil
156183
}
157184
}
185+
186+
func getFilterOp(used, unused bool) (int, error) {
187+
// should not happen, cobra handles this
188+
if used && unused {
189+
return 0, fmt.Errorf("used and unused flags are mutually exclusive")
190+
}
191+
192+
if !used && !unused {
193+
return utils.OP_FILTER_NOP, nil
194+
}
195+
196+
if used {
197+
return utils.OP_FILTER_USED, nil
198+
}
199+
200+
return utils.OP_FILTER_UNUSED, nil
201+
}

internal/cmd/load-balancer/observability-credentials/list/list_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
88
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
9+
lbUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/load-balancer/utils"
910
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
1011

1112
"github.com/google/go-cmp/cmp"
@@ -108,6 +109,34 @@ func TestParseInput(t *testing.T) {
108109
}),
109110
isValid: false,
110111
},
112+
{
113+
description: "used",
114+
flagValues: fixtureFlagValues(func(flagValues map[string]string) {
115+
flagValues[usedFlag] = "true"
116+
}),
117+
isValid: true,
118+
expectedModel: fixtureInputModel(func(model *inputModel) {
119+
model.Used = true
120+
}),
121+
},
122+
{
123+
description: "unused",
124+
flagValues: fixtureFlagValues(func(flagValues map[string]string) {
125+
flagValues[unusedFlag] = "true"
126+
}),
127+
isValid: true,
128+
expectedModel: fixtureInputModel(func(model *inputModel) {
129+
model.Unused = true
130+
}),
131+
},
132+
{
133+
description: "used and unused",
134+
flagValues: fixtureFlagValues(func(flagValues map[string]string) {
135+
flagValues[usedFlag] = "true"
136+
flagValues[unusedFlag] = "true"
137+
}),
138+
isValid: false,
139+
},
111140
}
112141

113142
for _, tt := range tests {
@@ -137,6 +166,14 @@ func TestParseInput(t *testing.T) {
137166
t.Fatalf("error validating flags: %v", err)
138167
}
139168

169+
err = cmd.ValidateFlagGroups()
170+
if err != nil {
171+
if !tt.isValid {
172+
return
173+
}
174+
t.Fatalf("error validating flags: %v", err)
175+
}
176+
140177
model, err := parseInput(p, cmd)
141178
if err != nil {
142179
if !tt.isValid {
@@ -183,3 +220,52 @@ func TestBuildRequest(t *testing.T) {
183220
})
184221
}
185222
}
223+
224+
func TestGetFilterOp(t *testing.T) {
225+
tests := []struct {
226+
description string
227+
used bool
228+
unused bool
229+
expectedFilterOp int
230+
isValid bool
231+
}{
232+
{
233+
description: "used",
234+
used: true,
235+
expectedFilterOp: lbUtils.OP_FILTER_USED,
236+
isValid: true,
237+
},
238+
{
239+
description: "unused",
240+
unused: true,
241+
expectedFilterOp: lbUtils.OP_FILTER_UNUSED,
242+
isValid: true,
243+
},
244+
{
245+
description: "used and unused",
246+
used: true,
247+
unused: true,
248+
isValid: false,
249+
},
250+
{
251+
description: "neither used nor unused",
252+
expectedFilterOp: lbUtils.OP_FILTER_NOP,
253+
isValid: true,
254+
},
255+
}
256+
257+
for _, tt := range tests {
258+
t.Run(tt.description, func(t *testing.T) {
259+
filterOp, err := getFilterOp(tt.used, tt.unused)
260+
if err != nil {
261+
if !tt.isValid {
262+
return
263+
}
264+
t.Fatalf("error getting filter op: %v", err)
265+
}
266+
if filterOp != tt.expectedFilterOp {
267+
t.Fatalf("Data does not match: %d", filterOp)
268+
}
269+
})
270+
}
271+
}

internal/cmd/load-balancer/target-pool/add-target/add_target_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ func (m *loadBalancerClientMocked) UpdateTargetPool(ctx context.Context, project
5757
return testClient.UpdateTargetPool(ctx, projectId, loadBalancerName, targetPoolName)
5858
}
5959

60+
func (m *loadBalancerClientMocked) ListLoadBalancersExecute(_ context.Context, _ string) (*loadbalancer.ListLoadBalancersResponse, error) {
61+
return nil, nil
62+
}
63+
6064
func fixtureArgValues(mods ...func(argValues []string)) []string {
6165
argValues := []string{
6266
testIP,

internal/cmd/load-balancer/target-pool/remove-target/remove_target_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ func (m *loadBalancerClientMocked) UpdateTargetPool(ctx context.Context, project
5757
return testClient.UpdateTargetPool(ctx, projectId, loadBalancerName, targetPoolName)
5858
}
5959

60+
func (m *loadBalancerClientMocked) ListLoadBalancersExecute(_ context.Context, _ string) (*loadbalancer.ListLoadBalancersResponse, error) {
61+
return nil, nil
62+
}
63+
6064
func fixtureArgValues(mods ...func(argValues []string)) []string {
6165
argValues := []string{
6266
testIP,

0 commit comments

Comments
 (0)