diff --git a/core/core/list.go b/core/core/list.go index 5cdb5db9..0cd87c11 100644 --- a/core/core/list.go +++ b/core/core/list.go @@ -13,6 +13,7 @@ import ( "github.com/kubescape/kubescape/v3/core/pkg/resultshandling/printer" v2 "github.com/kubescape/kubescape/v3/core/pkg/resultshandling/printer/v2" "github.com/kubescape/kubescape/v3/core/pkg/resultshandling/printer/v2/prettyprinter/tableprinter/utils" + "github.com/maruel/natural" "github.com/olekukonko/tablewriter" ) @@ -43,7 +44,7 @@ func (ks *Kubescape) List(ctx context.Context, listPolicies *metav1.ListPolicies if err != nil { return err } - sort.Strings(policies) + policies = naturalSortPolicies(policies) if listFormatFunction, ok := listFormatFunc[listPolicies.Format]; ok { listFormatFunction(ctx, listPolicies.Target, policies) @@ -56,6 +57,13 @@ func (ks *Kubescape) List(ctx context.Context, listPolicies *metav1.ListPolicies return fmt.Errorf("unknown command to download") } +func naturalSortPolicies(policies []string) []string { + sort.Slice(policies, func(i, j int) bool { + return natural.Less(policies[i], policies[j]) + }) + return policies +} + func listFrameworks(ctx context.Context, listPolicies *metav1.ListPolicies) ([]string, error) { tenant := cautils.GetTenantConfig(listPolicies.AccountID, listPolicies.AccessKey, "", "", getKubernetesApi()) // change k8sinterface policyGetter := getPolicyGetter(ctx, nil, tenant.GetAccountID(), true, nil) diff --git a/core/core/list_test.go b/core/core/list_test.go index eefb9fd2..cd24d475 100644 --- a/core/core/list_test.go +++ b/core/core/list_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "io" "os" + "reflect" "sort" "testing" @@ -376,3 +377,52 @@ func TestListExceptions(t *testing.T) { assert.Nil(t, controls) assert.NotNil(t, err) } + +func TestNaturalSortPolicies(t *testing.T) { + type args struct { + policies []string + } + tests := []struct { + name string + args args + want []string + }{ + { + name: "empty", + args: args{ + policies: []string{}, + }, + want: []string{}, + }, + { + name: "one element", + args: args{ + policies: []string{"policy-1"}, + }, + want: []string{"policy-1"}, + }, + { + name: "Natural sort", + args: args{ + policies: []string{"policy-1", "policy-11", "policy-12", "policy-2"}, + }, + want: []string{"policy-1", "policy-2", "policy-11", "policy-12"}, + }, + { + name: "Natural sort 2", + args: args{ + policies: []string{"exclude-aks-kube-system-daemonsets-10", "exclude-aks-kube-system-daemonsets-4", "exclude-aks-kube-system-daemonsets-1", + "exclude-gke-kube-public-resources", "exclude-kubescape-otel", + }, + }, + want: []string{"exclude-aks-kube-system-daemonsets-1", "exclude-aks-kube-system-daemonsets-4", "exclude-aks-kube-system-daemonsets-10", "exclude-gke-kube-public-resources", "exclude-kubescape-otel"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := naturalSortPolicies(tt.args.policies); !reflect.DeepEqual(got, tt.want) { + t.Errorf("sortPolicies() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/go.mod b/go.mod index 9518bc12..4646269d 100644 --- a/go.mod +++ b/go.mod @@ -281,6 +281,7 @@ require ( github.com/letsencrypt/boulder v0.0.0-20221109233200-85aa52084eaf // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/maruel/natural v1.1.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect diff --git a/go.sum b/go.sum index db06b32b..bac36a91 100644 --- a/go.sum +++ b/go.sum @@ -1395,6 +1395,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= +github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/matthyx/go-gitlog v0.0.0-20231005131906-9ffabe3c5bcd h1:Fs7gIqboEWWiJ2OdaWxK0MHGL+8XskZRZdVjJhUnSqE= diff --git a/httphandler/go.mod b/httphandler/go.mod index d881ed0c..62b5b911 100644 --- a/httphandler/go.mod +++ b/httphandler/go.mod @@ -279,6 +279,7 @@ require ( github.com/libgit2/git2go/v33 v33.0.9 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/maruel/natural v1.1.1 // indirect github.com/matthyx/go-gitlog v0.0.0-20231005131906-9ffabe3c5bcd // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect diff --git a/httphandler/go.sum b/httphandler/go.sum index fe0a7baf..4251d879 100644 --- a/httphandler/go.sum +++ b/httphandler/go.sum @@ -1400,6 +1400,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= +github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/matthyx/go-gitlog v0.0.0-20231005131906-9ffabe3c5bcd h1:Fs7gIqboEWWiJ2OdaWxK0MHGL+8XskZRZdVjJhUnSqE=