11package list
22
33import (
4+ "cmp"
45 "context"
56 "fmt"
7+ "slices"
68
9+ "github.com/stackitcloud/stackit-cli/internal/pkg/projectname"
710 "github.com/stackitcloud/stackit-cli/internal/pkg/types"
811
912 "github.com/spf13/cobra"
@@ -30,7 +33,7 @@ type inputModel struct {
3033 * globalflags.GlobalFlagModel
3134 Limit * int64
3235 LabelSelector * string
33- NetworkId string
36+ NetworkId * string
3437}
3538
3639func NewCmd (params * types.CmdParams ) * cobra.Command {
@@ -40,6 +43,11 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
4043 Long : "Lists all network interfaces of a network." ,
4144 Args : args .NoArgs ,
4245 Example : examples .Build (
46+ // Note: this subcommand uses two different API enpoints, which makes the implementation somewhat messy
47+ examples .NewExample (
48+ `Lists all network interfaces` ,
49+ `$ stackit network-interface list` ,
50+ ),
4351 examples .NewExample (
4452 `Lists all network interfaces with network ID "xxx"` ,
4553 `$ stackit network-interface list --network-id xxx` ,
@@ -70,32 +78,52 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
7078 return err
7179 }
7280
73- // Call API
74- req := buildRequest (ctx , model , apiClient )
81+ if model .NetworkId == nil {
82+ // Call API to get all NICs in the Project
83+ req := buildProjectRequest (ctx , model , apiClient )
84+
85+ resp , err := req .Execute ()
86+ if err != nil {
87+ return fmt .Errorf ("list network interfaces: %w" , err )
88+ }
89+
90+ projectLabel , err := projectname .GetProjectName (ctx , params .Printer , params .CliVersion , cmd )
91+ if err != nil {
92+ projectLabel = model .ProjectId
93+ }
94+
95+ // Truncate output
96+ items := utils .GetSliceFromPointer (resp .Items )
97+ if model .Limit != nil && len (items ) > int (* model .Limit ) {
98+ items = items [:* model .Limit ]
99+ }
100+
101+ return outputProjectResult (params .Printer , model .OutputFormat , items , projectLabel )
102+ }
103+
104+ // Call API to get NICs for one Network
105+ req := buildNetworkRequest (ctx , model , apiClient )
106+
75107 resp , err := req .Execute ()
76108 if err != nil {
77109 return fmt .Errorf ("list network interfaces: %w" , err )
78110 }
79111
80- if resp .Items == nil || len (* resp .Items ) == 0 {
81- networkLabel , err := iaasUtils .GetNetworkName (ctx , apiClient , model .ProjectId , model .Region , model .NetworkId )
82- if err != nil {
83- params .Printer .Debug (print .ErrorLevel , "get network name: %v" , err )
84- networkLabel = model .NetworkId
85- } else if networkLabel == "" {
86- networkLabel = model .NetworkId
87- }
88- params .Printer .Info ("No network interfaces found for network %q\n " , networkLabel )
89- return nil
112+ networkLabel , err := iaasUtils .GetNetworkName (ctx , apiClient , model .ProjectId , model .Region , * model .NetworkId )
113+ if err != nil {
114+ params .Printer .Debug (print .ErrorLevel , "get network name: %v" , err )
115+ networkLabel = * model .NetworkId
116+ } else if networkLabel == "" {
117+ networkLabel = * model .NetworkId
90118 }
91119
92120 // Truncate output
93- items := * resp .Items
121+ items := utils . GetSliceFromPointer ( resp .Items )
94122 if model .Limit != nil && len (items ) > int (* model .Limit ) {
95123 items = items [:* model .Limit ]
96124 }
97125
98- return outputResult (params .Printer , model .OutputFormat , items )
126+ return outputNetworkResult (params .Printer , model .OutputFormat , items , networkLabel )
99127 },
100128 }
101129 configureFlags (cmd )
@@ -106,9 +134,6 @@ func configureFlags(cmd *cobra.Command) {
106134 cmd .Flags ().Var (flags .UUIDFlag (), networkIdFlag , "Network ID" )
107135 cmd .Flags ().Int64 (limitFlag , 0 , "Maximum number of entries to list" )
108136 cmd .Flags ().String (labelSelectorFlag , "" , "Filter by label" )
109-
110- err := flags .MarkFlagsRequired (cmd , networkIdFlag )
111- cobra .CheckErr (err )
112137}
113138
114139func parseInput (p * print.Printer , cmd * cobra.Command , _ []string ) (* inputModel , error ) {
@@ -129,24 +154,71 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel,
129154 GlobalFlagModel : globalFlags ,
130155 Limit : limit ,
131156 LabelSelector : flags .FlagToStringPointer (p , cmd , labelSelectorFlag ),
132- NetworkId : flags .FlagToStringValue (p , cmd , networkIdFlag ),
157+ NetworkId : flags .FlagToStringPointer (p , cmd , networkIdFlag ),
133158 }
134159
135160 p .DebugInputModel (model )
136161 return & model , nil
137162}
138163
139- func buildRequest (ctx context.Context , model * inputModel , apiClient * iaas.APIClient ) iaas.ApiListNicsRequest {
140- req := apiClient .ListNics (ctx , model .ProjectId , model .Region , model . NetworkId )
164+ func buildProjectRequest (ctx context.Context , model * inputModel , apiClient * iaas.APIClient ) iaas.ApiListProjectNICsRequest {
165+ req := apiClient .ListProjectNICs (ctx , model .ProjectId , model .Region )
141166 if model .LabelSelector != nil {
142167 req = req .LabelSelector (* model .LabelSelector )
143168 }
144169
145170 return req
146171}
147172
148- func outputResult (p * print.Printer , outputFormat string , nics []iaas.NIC ) error {
173+ func buildNetworkRequest (ctx context.Context , model * inputModel , apiClient * iaas.APIClient ) iaas.ApiListNicsRequest {
174+ req := apiClient .ListNics (ctx , model .ProjectId , model .Region , * model .NetworkId )
175+ if model .LabelSelector != nil {
176+ req = req .LabelSelector (* model .LabelSelector )
177+ }
178+
179+ return req
180+ }
181+
182+ func outputProjectResult (p * print.Printer , outputFormat string , nics []iaas.NIC , projectLabel string ) error {
149183 return p .OutputResult (outputFormat , nics , func () error {
184+ if len (nics ) == 0 {
185+ p .Outputf ("No network interfaces found for project %q\n " , projectLabel )
186+ return nil
187+ }
188+
189+ slices .SortFunc (nics , func (a , b iaas.NIC ) int {
190+ return cmp .Compare (utils .PtrValue (a .NetworkId ), utils .PtrValue (b .NetworkId ))
191+ })
192+
193+ table := tables .NewTable ()
194+ table .SetHeader ("ID" , "NAME" , "NETWORK ID" , "NIC SECURITY" , "DEVICE ID" , "IPv4 ADDRESS" , "STATUS" , "TYPE" )
195+
196+ for _ , nic := range nics {
197+ table .AddRow (
198+ utils .PtrString (nic .Id ),
199+ utils .PtrString (nic .Name ),
200+ utils .PtrString (nic .NetworkId ),
201+ utils .PtrString (nic .NicSecurity ),
202+ utils .PtrString (nic .Device ),
203+ utils .PtrString (nic .Ipv4 ),
204+ utils .PtrString (nic .Status ),
205+ utils .PtrString (nic .Type ),
206+ )
207+ table .AddSeparator ()
208+ }
209+
210+ p .Outputln (table .Render ())
211+ return nil
212+ })
213+ }
214+
215+ func outputNetworkResult (p * print.Printer , outputFormat string , nics []iaas.NIC , networkLabel string ) error {
216+ return p .OutputResult (outputFormat , nics , func () error {
217+ if len (nics ) == 0 {
218+ p .Outputf ("No network interfaces found for network %q\n " , networkLabel )
219+ return nil
220+ }
221+
150222 table := tables .NewTable ()
151223 table .SetHeader ("ID" , "NAME" , "NIC SECURITY" , "DEVICE ID" , "IPv4 ADDRESS" , "STATUS" , "TYPE" )
152224
0 commit comments