Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
57aa5f1
fix returning empty server array in case the response does not return…
j1n-o9r Apr 13, 2026
245245d
adapted outputResult signature to comply to linter
j1n-o9r Apr 13, 2026
af0c646
switched to getter for retrieving the items
j1n-o9r Apr 13, 2026
c7010c8
adapted printing behavior to align with expected behavior
j1n-o9r Apr 13, 2026
29fcea0
change printing to defined output instead of stderr
j1n-o9r Apr 13, 2026
dd1af86
adapted network list command to align to expectations
j1n-o9r Apr 13, 2026
0b1465c
remove unnecessary normalization of nil value in response items after…
j1n-o9r Apr 13, 2026
391c0bf
adapted network-area list command to align to expectations
j1n-o9r Apr 13, 2026
e0d8cab
removed redundant check
j1n-o9r Apr 13, 2026
d2fbe3f
adapted affinity list command to align to expectations
j1n-o9r Apr 15, 2026
3ffc00f
adapted image list command to align to expectations
j1n-o9r Apr 15, 2026
2d40450
adapted key pair list command to align to expectations
j1n-o9r Apr 15, 2026
73e26f6
fixed debug print in key pair list command
j1n-o9r Apr 15, 2026
1c3ff3e
move project label retrieval
j1n-o9r Apr 15, 2026
da3c008
adapted public ip list command to align to expectations
j1n-o9r Apr 15, 2026
9176013
adapted security group list command to align to expectations
j1n-o9r Apr 15, 2026
e279346
added missing --limit flag for list security groups command
j1n-o9r Apr 15, 2026
d2cdb26
adapted volumes list command to align to expectations
j1n-o9r Apr 15, 2026
a5a95c6
adapted volume snapshots list command to align to expectations
j1n-o9r Apr 15, 2026
765f6c8
adapted volume performance class list command to align to expectations
j1n-o9r Apr 15, 2026
b59b378
adapted volume backups list command to align to expectations
j1n-o9r Apr 15, 2026
95b6cdf
fixed order of params
j1n-o9r Apr 15, 2026
b109211
adapted network area network ranges list command to align to expectat…
j1n-o9r Apr 15, 2026
59893aa
adapted network area routes list command to align to expectations
j1n-o9r Apr 15, 2026
4c78db9
adapted security group rules list command to align to expectations
j1n-o9r Apr 15, 2026
5769401
adapted server machine-types list command to align to expectations
j1n-o9r Apr 20, 2026
98fa927
adapted server network-interfaces list command to align to expectations
j1n-o9r Apr 20, 2026
a6c67fd
adapted server service accounts list command to align to expectations
j1n-o9r Apr 20, 2026
dc8f123
adapted server volumes list command to align to expectations
j1n-o9r Apr 20, 2026
61f72ec
removed unnecessary check in public ip
j1n-o9r Apr 22, 2026
5d81099
regenerate docs
j1n-o9r Apr 22, 2026
e3601b2
fixed linter issue
j1n-o9r Apr 22, 2026
400877c
Update internal/cmd/key-pair/list/list.go
j1n-o9r Apr 22, 2026
9818dee
(fix): remove mistakenly added project label from key pairs list command
j1n-o9r Apr 22, 2026
959b894
(fix): made orgLabel in model from pointer to string for not having t…
j1n-o9r Apr 22, 2026
bf8ff77
(fix): remove unnecessarily declaring variable with explicit statement
j1n-o9r Apr 22, 2026
ef27439
(fix): made OrganizationId and NetworkAreaId in model from pointer to…
j1n-o9r Apr 22, 2026
2256c42
(fix): changed print statement to not contain abbreviation
j1n-o9r Apr 22, 2026
2ff6e8c
(fix): added test suggestion
j1n-o9r Apr 22, 2026
96c590c
adapted server quotas list command to return valid json/yaml when quo…
j1n-o9r Apr 29, 2026
1125d22
fix(iaas): readded lost elif block
j1n-o9r May 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions docs/stackit_security-group_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,25 @@ stackit security-group list [flags]
### Examples

```
List all groups
Lists all security groups
$ stackit security-group list

List groups with labels
Lists security groups with labels
$ stackit security-group list --label-selector label1=value1,label2=value2

Lists all security groups in JSON format
$ stackit security-group list --output-format json

Lists up to 10 security groups
$ stackit security-group list --limit 10
```

### Options

```
-h, --help Help for "stackit security-group list"
--label-selector string Filter by label
--limit int Maximum number of entries to list
```

### Options inherited from parent commands
Expand Down
29 changes: 16 additions & 13 deletions internal/cmd/affinity-groups/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/stackitcloud/stackit-cli/internal/pkg/flags"
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
"github.com/stackitcloud/stackit-cli/internal/pkg/projectname"
"github.com/stackitcloud/stackit-cli/internal/pkg/services/iaas/client"
)

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

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

params.Printer.Outputln("No affinity groups found")
return nil
// Truncate Output
if model.Limit != nil && len(items) > int(*model.Limit) {
items = items[:*model.Limit]
}
return outputResult(params.Printer, model.OutputFormat, projectLabel, items)
},
}
configureFlags(cmd)
Expand Down Expand Up @@ -110,13 +114,12 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel,
return &model, nil
}

func outputResult(p *print.Printer, model inputModel, items []iaas.AffinityGroup) error {
var outputFormat string
Comment thread
j1n-o9r marked this conversation as resolved.
if model.GlobalFlagModel != nil {
outputFormat = model.OutputFormat
}

func outputResult(p *print.Printer, outputFormat, projectLabel string, items []iaas.AffinityGroup) error {
return p.OutputResult(outputFormat, items, func() error {
if len(items) == 0 {
p.Outputf("No affinity groups found for project %q\n", projectLabel)
return nil
}
table := tables.NewTable()
table.SetHeader("ID", "NAME", "POLICY")
for _, item := range items {
Expand Down
27 changes: 22 additions & 5 deletions internal/cmd/affinity-groups/list/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,23 +141,40 @@ func TestBuildRequest(t *testing.T) {
}

func TestOutputResult(t *testing.T) {
type args struct {
outputFormat string
projectLabel string
instances []iaas.AffinityGroup
}
tests := []struct {
description string
model inputModel
response []iaas.AffinityGroup
args args
isValid bool
}{
{
description: "empty",
model: inputModel{},
response: []iaas.AffinityGroup{},
args: args{},
Comment thread
j1n-o9r marked this conversation as resolved.
isValid: true,
},
{
description: "empty slice",
args: args{
instances: []iaas.AffinityGroup{},
},
isValid: true,
},
{
description: "empty affinity group in slice",
args: args{
instances: []iaas.AffinityGroup{{}},
},
isValid: true,
},
}
params := testparams.NewTestParams()
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
err := outputResult(params.Printer, tt.model, tt.response)
err := outputResult(params.Printer, tt.args.outputFormat, tt.args.projectLabel, tt.args.instances)
if err != nil {
if !tt.isValid {
return
Expand Down
23 changes: 12 additions & 11 deletions internal/cmd/image/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,18 @@ func NewCmd(params *types.CmdParams) *cobra.Command {

// Call API
request := buildRequest(ctx, model, apiClient)

response, err := request.Execute()
if err != nil {
return fmt.Errorf("list images: %w", err)
}
items := response.GetItems()

if items := response.GetItems(); len(items) == 0 {
params.Printer.Info("No images found for project %q", projectLabel)
} else {
if model.Limit != nil && len(items) > int(*model.Limit) {
items = (items)[:*model.Limit]
}
if err := outputResult(params.Printer, model.OutputFormat, items); err != nil {
return fmt.Errorf("output images: %w", err)
}
// Truncate output
if model.Limit != nil && len(items) > int(*model.Limit) {
items = (items)[:*model.Limit]
}
if err := outputResult(params.Printer, model.OutputFormat, projectLabel, items); err != nil {
return fmt.Errorf("output images: %w", err)
}

return nil
Expand Down Expand Up @@ -149,8 +146,12 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APICli
return request
}

func outputResult(p *print.Printer, outputFormat string, items []iaas.Image) error {
func outputResult(p *print.Printer, outputFormat, projectLabel string, items []iaas.Image) error {
return p.OutputResult(outputFormat, items, func() error {
if len(items) == 0 {
p.Outputf("No images found for project %q\n", projectLabel)
return nil
}
table := tables.NewTable()
table.SetHeader("ID", "NAME", "OS", "ARCHITECTURE", "DISTRIBUTION", "VERSION", "SCOPE", "OWNER", "LABELS")
for i := range items {
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/image/list/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ func TestBuildRequest(t *testing.T) {
func Test_outputResult(t *testing.T) {
type args struct {
outputFormat string
projectLabel string
items []iaas.Image
}
tests := []struct {
Expand Down Expand Up @@ -215,7 +216,7 @@ func Test_outputResult(t *testing.T) {
params := testparams.NewTestParams()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := outputResult(params.Printer, tt.args.outputFormat, tt.args.items); (err != nil) != tt.wantErr {
if err := outputResult(params.Printer, tt.args.outputFormat, tt.args.projectLabel, tt.args.items); (err != nil) != tt.wantErr {
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
}
})
Expand Down
12 changes: 7 additions & 5 deletions internal/cmd/key-pair/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,9 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
return fmt.Errorf("list key pairs: %w", err)
}

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

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

func outputResult(p *print.Printer, outputFormat string, keyPairs []iaas.Keypair) error {
return p.OutputResult(outputFormat, keyPairs, func() error {
if len(keyPairs) == 0 {
p.Outputf("No key pairs found\n")
return nil
}

table := tables.NewTable()
table.SetHeader("KEY PAIR NAME", "LABELS", "FINGERPRINT", "CREATED AT", "UPDATED AT")

Expand Down
46 changes: 25 additions & 21 deletions internal/cmd/network-area/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const (
type inputModel struct {
*globalflags.GlobalFlagModel
Limit *int64
OrganizationId *string
OrganizationId string
LabelSelector *string
}

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

if resp.Items == nil || len(*resp.Items) == 0 {
var orgLabel string
rmApiClient, err := rmClient.ConfigureClient(params.Printer, params.CliVersion)
if err == nil {
orgLabel, err = rmUtils.GetOrganizationName(ctx, rmApiClient, *model.OrganizationId)
if err != nil {
params.Printer.Debug(print.ErrorLevel, "get organization name: %v", err)
orgLabel = *model.OrganizationId
} else if orgLabel == "" {
orgLabel = *model.OrganizationId
}
} else {
params.Printer.Debug(print.ErrorLevel, "configure resource manager client: %v", err)
items := resp.GetItems()

var orgLabel string
rmApiClient, err := rmClient.ConfigureClient(params.Printer, params.CliVersion)
if err == nil {
orgLabel, err = rmUtils.GetOrganizationName(ctx, rmApiClient, model.OrganizationId)
if err != nil {
params.Printer.Debug(print.ErrorLevel, "get organization name: %v", err)
orgLabel = model.OrganizationId
}
params.Printer.Info("No STACKIT Network Areas found for organization %q\n", orgLabel)
return nil
} else {
params.Printer.Debug(print.ErrorLevel, "configure resource manager client: %v", err)
}

if orgLabel == "" {
orgLabel = model.OrganizationId
}

// Truncate output
items := *resp.Items
if model.Limit != nil && len(items) > int(*model.Limit) {
items = items[:*model.Limit]
}

return outputResult(params.Printer, model.OutputFormat, items)
return outputResult(params.Printer, model.OutputFormat, orgLabel, items)
},
}
configureFlags(cmd)
Expand Down Expand Up @@ -133,7 +132,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel,
model := inputModel{
GlobalFlagModel: globalFlags,
Limit: limit,
OrganizationId: flags.FlagToStringPointer(p, cmd, organizationIdFlag),
OrganizationId: flags.FlagToStringValue(p, cmd, organizationIdFlag),
LabelSelector: flags.FlagToStringPointer(p, cmd, labelSelectorFlag),
}

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

func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APIClient) iaas.ApiListNetworkAreasRequest {
req := apiClient.ListNetworkAreas(ctx, *model.OrganizationId)
req := apiClient.ListNetworkAreas(ctx, model.OrganizationId)
if model.LabelSelector != nil {
req = req.LabelSelector(*model.LabelSelector)
}
return req
}

func outputResult(p *print.Printer, outputFormat string, networkAreas []iaas.NetworkArea) error {
func outputResult(p *print.Printer, outputFormat, orgLabel string, networkAreas []iaas.NetworkArea) error {
return p.OutputResult(outputFormat, networkAreas, func() error {
if len(networkAreas) == 0 {
p.Outputf("No STACKIT Network Areas found for organization %q\n", orgLabel)
return nil
}

table := tables.NewTable()
table.SetHeader("ID", "Name", "# Attached Projects")

Expand Down
5 changes: 3 additions & 2 deletions internal/cmd/network-area/list/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel {
GlobalFlagModel: &globalflags.GlobalFlagModel{
Verbosity: globalflags.VerbosityDefault,
},
OrganizationId: &testOrganizationId,
OrganizationId: testOrganizationId,
Limit: utils.Ptr(int64(10)),
LabelSelector: utils.Ptr(testLabelSelector),
}
Expand Down Expand Up @@ -167,6 +167,7 @@ func TestBuildRequest(t *testing.T) {
func TestOutputResult(t *testing.T) {
type args struct {
outputFormat string
orgLabel string
networkAreas []iaas.NetworkArea
}
tests := []struct {
Expand Down Expand Up @@ -197,7 +198,7 @@ func TestOutputResult(t *testing.T) {
params := testparams.NewTestParams()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := outputResult(params.Printer, tt.args.outputFormat, tt.args.networkAreas); (err != nil) != tt.wantErr {
if err := outputResult(params.Printer, tt.args.outputFormat, tt.args.orgLabel, tt.args.networkAreas); (err != nil) != tt.wantErr {
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
}
})
Expand Down
Loading
Loading