Skip to content
This repository has been archived by the owner on Oct 16, 2024. It is now read-only.

Commit

Permalink
Merge pull request #14 from onmetal/feature/sorting
Browse files Browse the repository at this point in the history
Add option to sort the items returned from `list` commands.
  • Loading branch information
guvenc authored Sep 27, 2023
2 parents b84c1f9 + dc1324d commit ad20907
Show file tree
Hide file tree
Showing 56 changed files with 237 additions and 73 deletions.
2 changes: 1 addition & 1 deletion cmd/create_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (o *CreateInterfaceOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&o.ID, "id", o.ID, "ID of the interface.")
fs.Uint32Var(&o.VNI, "vni", o.VNI, "VNI to add the interface to.")
flag.AddrVar(fs, &o.IPv4, "ipv4", o.IPv4, "IPv4 address to assign to the interface.")
flag.AddrVar(fs, &o.IPv6, "ipv6", o.IPv6, "IPv6 address to assign to the interface.")
flag.AddrVar(fs, &o.IPv6, "ipv6", netip.IPv6Unspecified(), "IPv6 address to assign to the interface.")
fs.StringVar(&o.Device, "device", o.Device, "Device to allocate.")
fs.StringVar(&o.PxeServer, "pxe-server", o.PxeServer, "PXE next server.")
fs.StringVar(&o.PxeFileName, "pxe-file-name", o.PxeFileName, "PXE boot file name.")
Expand Down
2 changes: 1 addition & 1 deletion cmd/get_firewall_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func RunGetFirewallRule(
}
defer DpdkClose(cleanup)

fwrule, err := client.GetFirewallRule(ctx, opts.RuleID, opts.InterfaceID)
fwrule, err := client.GetFirewallRule(ctx, opts.InterfaceID, opts.RuleID)
if err != nil && fwrule.Status.Code == 0 {
return fmt.Errorf("error getting firewall rule: %w", err)
}
Expand Down
30 changes: 28 additions & 2 deletions cmd/list_firewall_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"context"
"fmt"
"os"
"sort"
"strings"

"github.com/onmetal/dpservice-cli/util"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -54,10 +56,12 @@ func ListFirewallRules(dpdkClientFactory DPDKClientFactory, rendererFactory Rend

type ListFirewallRulesOptions struct {
InterfaceID string
SortBy string
}

func (o *ListFirewallRulesOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&o.InterfaceID, "interface-id", o.InterfaceID, "InterfaceID from which to list firewall rules.")
fs.StringVar(&o.SortBy, "sort-by", "", "Column to sort by.")
}

func (o *ListFirewallRulesOptions) MarkRequiredFlags(cmd *cobra.Command) error {
Expand All @@ -81,10 +85,32 @@ func RunListFirewallRules(
}
defer DpdkClose(cleanup)

fwrules, err := client.ListFirewallRules(ctx, opts.InterfaceID)
fwruleList, err := client.ListFirewallRules(ctx, opts.InterfaceID)
if err != nil {
return fmt.Errorf("error listing firewall rules: %w", err)
}
// sort items in list
fwrules := fwruleList.Items
sort.SliceStable(fwrules, func(i, j int) bool {
mi, mj := fwrules[i], fwrules[j]
switch strings.ToLower(opts.SortBy) {
case "direction":
return mi.Spec.TrafficDirection < mj.Spec.TrafficDirection
case "src", "source":
return mi.Spec.SourcePrefix.String() < mj.Spec.SourcePrefix.String()
case "dst", "destination":
return mi.Spec.DestinationPrefix.String() < mj.Spec.DestinationPrefix.String()
case "action":
return mi.Spec.FirewallAction < mj.Spec.FirewallAction
case "protocol":
return mi.Spec.ProtocolFilter.String() < mj.Spec.ProtocolFilter.String()
case "priority":
return mi.Spec.Priority < mj.Spec.Priority
default:
return mi.Spec.RuleID < mj.Spec.RuleID
}
})
fwruleList.Items = fwrules

return rendererFactory.RenderList("", os.Stdout, fwrules)
return rendererFactory.RenderList("", os.Stdout, fwruleList)
}
41 changes: 41 additions & 0 deletions cmd/list_interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,19 @@ import (
"context"
"fmt"
"os"
"sort"
"strings"

"github.com/onmetal/dpservice-cli/util"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

func ListInterfaces(dpdkClientFactory DPDKClientFactory, rendererFactory RendererFactory) *cobra.Command {
var (
opts ListInterfacesOptions
)

cmd := &cobra.Command{
Use: "interfaces",
Short: "List all interfaces",
Expand All @@ -35,17 +42,24 @@ func ListInterfaces(dpdkClientFactory DPDKClientFactory, rendererFactory Rendere
cmd.Context(),
dpdkClientFactory,
rendererFactory,
opts,
)
},
}

opts.AddFlags(cmd.Flags())

util.Must(opts.MarkRequiredFlags(cmd))

return cmd
}

type ListInterfacesOptions struct {
SortBy string
}

func (o *ListInterfacesOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&o.SortBy, "sort-by", "", "Column to sort by.")
}

func (o *ListInterfacesOptions) MarkRequiredFlags(cmd *cobra.Command) error {
Expand All @@ -56,6 +70,7 @@ func RunListInterfaces(
ctx context.Context,
dpdkClientFactory DPDKClientFactory,
rendererFactory RendererFactory,
opts ListInterfacesOptions,
) error {
client, cleanup, err := dpdkClientFactory.NewClient(ctx)
if err != nil {
Expand All @@ -82,6 +97,32 @@ func RunListInterfaces(
}
}
}
// sort items in list
interfaces := interfaceList.Items
sort.SliceStable(interfaces, func(i, j int) bool {
mi, mj := interfaces[i], interfaces[j]
switch strings.ToLower(opts.SortBy) {
case "vni":
if mi.Spec.VNI != mj.Spec.VNI {
return mi.Spec.VNI < mj.Spec.VNI
}
return mi.Spec.IPv4.String() < mj.Spec.IPv4.String()
case "device":
return mi.Spec.Device < mj.Spec.Device
case "ipv4":
if mi.Spec.IPv4.String() != mj.Spec.IPv4.String() {
return mi.Spec.IPv4.String() < mj.Spec.IPv4.String()
}
return mi.Spec.VNI < mj.Spec.VNI
case "ipv6":
return mi.Spec.IPv6.String() < mj.Spec.IPv6.String()
case "underlayroute":
return mi.Spec.UnderlayRoute.String() < mj.Spec.UnderlayRoute.String()
default:
return mi.ID < mj.ID
}
})
interfaceList.Items = interfaces

return rendererFactory.RenderList("", os.Stdout, interfaceList)
}
17 changes: 17 additions & 0 deletions cmd/list_loadbalancer_prefixes.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"context"
"fmt"
"os"
"sort"
"strings"

"github.com/onmetal/dpservice-cli/util"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -55,10 +57,12 @@ func ListLoadBalancerPrefixes(dpdkClientFactory DPDKClientFactory, rendererFacto

type ListLoadBalancerPrefixesOptions struct {
InterfaceID string
SortBy string
}

func (o *ListLoadBalancerPrefixesOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&o.InterfaceID, "interface-id", o.InterfaceID, "Interface ID of the prefix.")
fs.StringVar(&o.SortBy, "sort-by", "", "Column to sort by.")
}

func (o *ListLoadBalancerPrefixesOptions) MarkRequiredFlags(cmd *cobra.Command) error {
Expand Down Expand Up @@ -87,5 +91,18 @@ func RunListLoadBalancerPrefixes(
return fmt.Errorf("error listing loadbalancer prefixes: %w", err)
}

// sort items in list
prefixes := prefixList.Items
sort.SliceStable(prefixes, func(i, j int) bool {
mi, mj := prefixes[i], prefixes[j]
switch strings.ToLower(opts.SortBy) {
case "underlayroute":
return mi.Spec.UnderlayRoute.String() < mj.Spec.UnderlayRoute.String()
default:
return mi.Spec.Prefix.String() < mj.Spec.Prefix.String()
}
})
prefixList.Items = prefixes

return rendererFactory.RenderList("", os.Stdout, prefixList)
}
11 changes: 11 additions & 0 deletions cmd/list_loadbalancer_targets.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"fmt"
"os"
"sort"

"github.com/onmetal/dpservice-cli/util"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -55,10 +56,12 @@ func ListLoadBalancerTargets(dpdkClientFactory DPDKClientFactory, rendererFactor

type ListLoadBalancerTargetOptions struct {
LoadBalancerID string
SortBy string
}

func (o *ListLoadBalancerTargetOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&o.LoadBalancerID, "lb-id", o.LoadBalancerID, "ID of the loadbalancer to get the targets for.")
fs.StringVar(&o.SortBy, "sort-by", "", "Column to sort by.")
}

func (o *ListLoadBalancerTargetOptions) MarkRequiredFlags(cmd *cobra.Command) error {
Expand Down Expand Up @@ -87,5 +90,13 @@ func RunListLoadBalancerTargets(
return fmt.Errorf("error listing loadbalancer targets: %w", err)
}

// sort items in list
targets := lbtargets.Items
sort.SliceStable(targets, func(i, j int) bool {
mi, mj := targets[i], targets[j]
return mi.Spec.TargetIP.String() < mj.Spec.TargetIP.String()
})
lbtargets.Items = targets

return rendererFactory.RenderList("", os.Stdout, lbtargets)
}
33 changes: 31 additions & 2 deletions cmd/list_nats.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"fmt"
"net/netip"
"os"
"sort"
"strings"

"github.com/onmetal/dpservice-cli/flag"
"github.com/onmetal/dpservice-cli/util"
Expand Down Expand Up @@ -57,11 +59,13 @@ func ListNats(dpdkClientFactory DPDKClientFactory, rendererFactory RendererFacto
type ListNatsOptions struct {
NatIP netip.Addr
NatType string
SortBy string
}

func (o *ListNatsOptions) AddFlags(fs *pflag.FlagSet) {
flag.AddrVar(fs, &o.NatIP, "nat-ip", o.NatIP, "NAT IP to get info for")
fs.StringVar(&o.NatType, "nat-type", "0", "NAT type: Any = 0/Local = 1/Neigh(bor) = 2")
fs.StringVar(&o.SortBy, "sort-by", "", "Column to sort by.")
}

func (o *ListNatsOptions) MarkRequiredFlags(cmd *cobra.Command) error {
Expand All @@ -85,10 +89,35 @@ func RunListNats(
}
defer DpdkClose(cleanup)

nats, err := client.ListNats(ctx, &opts.NatIP, opts.NatType)
natList, err := client.ListNats(ctx, &opts.NatIP, opts.NatType)
if err != nil {
return fmt.Errorf("error listing nats: %w", err)
}

return rendererFactory.RenderList("", os.Stdout, nats)
// sort items in list
nats := natList.Items
sort.SliceStable(nats, func(i, j int) bool {
mi, mj := nats[i], nats[j]
switch strings.ToLower(opts.SortBy) {
case "ip":
if mi.Spec.NatIP != nil && mj.Spec.NatIP != nil {
return mi.Spec.NatIP.String() < mj.Spec.NatIP.String()
}
return true
case "minport":
return mi.Spec.MinPort < mj.Spec.MinPort
case "maxport":
return mi.Spec.MaxPort < mj.Spec.MaxPort
case "underlayroute":
if mi.Spec.UnderlayRoute != nil && mj.Spec.UnderlayRoute != nil {
return mi.Spec.UnderlayRoute.String() < mj.Spec.UnderlayRoute.String()
}
return true
default:
return mi.Spec.Vni < mj.Spec.Vni
}
})
natList.Items = nats

return rendererFactory.RenderList("", os.Stdout, natList)
}
17 changes: 17 additions & 0 deletions cmd/list_prefixes.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"context"
"fmt"
"os"
"sort"
"strings"

"github.com/onmetal/dpservice-cli/util"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -54,10 +56,12 @@ func ListPrefixes(dpdkClientFactory DPDKClientFactory, rendererFactory RendererF

type ListPrefixesOptions struct {
InterfaceID string
SortBy string
}

func (o *ListPrefixesOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&o.InterfaceID, "interface-id", o.InterfaceID, "Interface ID of the prefix.")
fs.StringVar(&o.SortBy, "sort-by", "", "Column to sort by.")
}

func (o *ListPrefixesOptions) MarkRequiredFlags(cmd *cobra.Command) error {
Expand Down Expand Up @@ -86,5 +90,18 @@ func RunListPrefixes(
return fmt.Errorf("error listing prefixes: %w", err)
}

// sort items in list
prefixes := prefixList.Items
sort.SliceStable(prefixes, func(i, j int) bool {
mi, mj := prefixes[i], prefixes[j]
switch strings.ToLower(opts.SortBy) {
case "underlayroute":
return mi.Spec.UnderlayRoute.String() < mj.Spec.UnderlayRoute.String()
default:
return mi.Spec.Prefix.String() < mj.Spec.Prefix.String()
}
})
prefixList.Items = prefixes

return rendererFactory.RenderList("", os.Stdout, prefixList)
}
21 changes: 20 additions & 1 deletion cmd/list_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"context"
"fmt"
"os"
"sort"
"strings"

"github.com/onmetal/dpservice-cli/util"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -54,11 +56,13 @@ func ListRoutes(dpdkClientFactory DPDKClientFactory, rendererFactory RendererFac
}

type ListRoutesOptions struct {
VNI uint32
VNI uint32
SortBy string
}

func (o *ListRoutesOptions) AddFlags(fs *pflag.FlagSet) {
fs.Uint32Var(&o.VNI, "vni", o.VNI, "VNI to get the routes from.")
fs.StringVar(&o.SortBy, "sort-by", "", "Column to sort by.")
}

func (o *ListRoutesOptions) MarkRequiredFlags(cmd *cobra.Command) error {
Expand Down Expand Up @@ -87,5 +91,20 @@ func RunGetRoute(
return fmt.Errorf("error listing routes: %w", err)
}

// sort items in list
routes := routeList.Items
sort.SliceStable(routes, func(i, j int) bool {
mi, mj := routes[i], routes[j]
switch strings.ToLower(opts.SortBy) {
case "nexthopvni":
return mi.Spec.NextHop.VNI < mj.Spec.NextHop.VNI
case "nexthopip":
return mi.Spec.NextHop.IP.String() < mj.Spec.NextHop.IP.String()
default:
return mi.Spec.Prefix.String() < mj.Spec.Prefix.String()
}
})
routeList.Items = routes

return rendererFactory.RenderList("", os.Stdout, routeList)
}
Loading

0 comments on commit ad20907

Please sign in to comment.