From 6b25948653914328580bdc56a9c8403a7a812398 Mon Sep 17 00:00:00 2001 From: Daichi Sakaue Date: Fri, 11 Oct 2024 17:29:32 +0900 Subject: [PATCH 1/7] Refactor implementation Signed-off-by: Daichi Sakaue --- cmd/list.go | 37 +++++++++-- cmd/root.go | 2 + e2e/Makefile | 15 ++++- e2e/list_test.go | 101 +++++++++++++++++------------ e2e/testdata/policy/README.md | 15 +++++ e2e/testdata/policy/l3.yaml | 20 ++++++ e2e/testdata/policy/l4.yaml | 115 ++++++++++++++++++++++++++++++++++ e2e/utils_test.go | 2 +- go.mod | 2 +- 9 files changed, 260 insertions(+), 49 deletions(-) create mode 100644 e2e/testdata/policy/README.md create mode 100644 e2e/testdata/policy/l4.yaml diff --git a/cmd/list.go b/cmd/list.go index 03a5861..0610a96 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -5,12 +5,14 @@ import ( "encoding/json" "fmt" "io" + "sort" "strconv" "strings" "text/tabwriter" "github.com/cilium/cilium/api/v1/client/endpoint" "github.com/spf13/cobra" + "golang.org/x/exp/maps" ) func init() { @@ -40,6 +42,22 @@ type derivedFromEntry struct { Name string `json:"name"` } +func compareDerivedFromEntry(x, y *derivedFromEntry) bool { + if x.Direction != y.Direction { + return strings.Compare(x.Direction, y.Direction) < 0 + } + if x.Kind != y.Kind { + return strings.Compare(x.Kind, y.Kind) < 0 + } + if x.Namespace != y.Namespace { + return strings.Compare(x.Namespace, y.Namespace) < 0 + } + if x.Name != y.Name { + return strings.Compare(x.Name, y.Name) < 0 + } + return false +} + func parseDerivedFromEntry(input []string, direction string) derivedFromEntry { val := derivedFromEntry{ Direction: direction, @@ -77,22 +95,27 @@ func runList(ctx context.Context, w io.Writer, name string) error { return err } - policyList := make([]derivedFromEntry, 0) + policySet := make(map[derivedFromEntry]struct{}) ingressRules := response.Payload.Status.Policy.Realized.L4.Ingress for _, rule := range ingressRules { for _, r := range rule.DerivedFromRules { - policyList = append(policyList, parseDerivedFromEntry(r, directionIngress)) + entry := parseDerivedFromEntry(r, directionIngress) + policySet[entry] = struct{}{} } } egressRules := response.Payload.Status.Policy.Realized.L4.Egress for _, rule := range egressRules { for _, r := range rule.DerivedFromRules { - policyList = append(policyList, parseDerivedFromEntry(r, directionEgress)) + entry := parseDerivedFromEntry(r, directionEgress) + policySet[entry] = struct{}{} } } + policyList := maps.Keys(policySet) + sort.Slice(policyList, func(i, j int) bool { return compareDerivedFromEntry(&policyList[i], &policyList[j]) }) + switch rootOptions.output { case OutputJson: text, err := json.MarshalIndent(policyList, "", " ") @@ -103,9 +126,11 @@ func runList(ctx context.Context, w io.Writer, name string) error { return err case OutputSimple: tw := tabwriter.NewWriter(w, 0, 1, 1, ' ', 0) - _, err := tw.Write([]byte("DIRECTION\tKIND\tNAMESPACE\tNAME\n")) - if err != nil { - return err + if !rootOptions.noHeaders { + _, err := tw.Write([]byte("DIRECTION\tKIND\tNAMESPACE\tNAME\n")) + if err != nil { + return err + } } for _, p := range policyList { _, err := tw.Write([]byte(fmt.Sprintf("%v\t%v\t%v\t%v\n", p.Direction, p.Kind, p.Namespace, p.Name))) diff --git a/cmd/root.go b/cmd/root.go index 3451d32..d97d6a8 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -17,6 +17,7 @@ var rootOptions struct { proxySelector string proxyPort uint16 output string + noHeaders bool } func init() { @@ -24,6 +25,7 @@ func init() { rootCmd.PersistentFlags().StringVar(&rootOptions.proxySelector, "proxy-selector", "app.kubernetes.io/name=cilium-agent-proxy", "label selector to find the proxy pods") rootCmd.PersistentFlags().Uint16Var(&rootOptions.proxyPort, "proxy-port", 8080, "port number of the proxy endpoints") rootCmd.PersistentFlags().StringVarP(&rootOptions.output, "output", "o", OutputSimple, "output format") + rootCmd.PersistentFlags().BoolVar(&rootOptions.noHeaders, "no-headers", false, "stop printing header") } var rootCmd = &cobra.Command{} diff --git a/e2e/Makefile b/e2e/Makefile index b2f73e5..d80f725 100644 --- a/e2e/Makefile +++ b/e2e/Makefile @@ -33,22 +33,33 @@ start: $(MAKE) --no-print-directory wait-for-workloads run-test-pod-%: + @# https://github.com/orgs/aquaproj/discussions/2964 + @echo Hello | yq > /dev/null cat testdata/template/ubuntu.yaml | \ yq '.metadata.name = "$*"' | \ yq '.spec.selector.matchLabels = {"test": "$*"}' | \ - yq '.spec.template.metadata.labels = {"test": "$*"}' | \ + yq '.spec.template.metadata.labels = {"test": "$*", "group": "test"}' | \ kubectl apply -f - .PHONY: install-test-pod install-test-pod: $(MAKE) --no-print-directory run-test-pod-self $(MAKE) --no-print-directory run-test-pod-l3-ingress-explicit-allow - $(MAKE) --no-print-directory run-test-pod-l3-ingress-no-rule + $(MAKE) --no-print-directory run-test-pod-l3-ingress-implicit-deny $(MAKE) --no-print-directory run-test-pod-l3-ingress-explicit-deny $(MAKE) --no-print-directory run-test-pod-l3-egress-implicit-deny $(MAKE) --no-print-directory run-test-pod-l3-egress-explicit-deny + + $(MAKE) --no-print-directory run-test-pod-l4-ingress-explicit-allow-any + $(MAKE) --no-print-directory run-test-pod-l4-ingress-explicit-allow-tcp + $(MAKE) --no-print-directory run-test-pod-l4-ingress-explicit-deny-any + $(MAKE) --no-print-directory run-test-pod-l4-ingress-explicit-deny-udp + $(MAKE) --no-print-directory run-test-pod-l4-egress-explicit-deny-any + $(MAKE) --no-print-directory run-test-pod-l4-egress-explicit-deny-tcp $(MAKE) --no-print-directory wait-for-workloads + kubectl apply -f testdata/policy/l3.yaml + kubectl apply -f testdata/policy/l4.yaml .PHONY: install-policy-viewer install-policy-viewer: diff --git a/e2e/list_test.go b/e2e/list_test.go index 2f64dee..a5ca46a 100644 --- a/e2e/list_test.go +++ b/e2e/list_test.go @@ -1,28 +1,12 @@ package e2e import ( - "encoding/json" - "fmt" - "reflect" + "strings" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) -func testJson(g Gomega, target []byte, expected string) { - var t, e interface{} - err := json.Unmarshal(target, &t) - g.Expect(err).NotTo(HaveOccurred(), "actual: %s", target) - - err = json.Unmarshal([]byte(expected), &e) - g.Expect(err).NotTo(HaveOccurred(), "expected: %s", expected) - - if !reflect.DeepEqual(t, e) { - err := fmt.Errorf("compare failed. actual: %s, expected: %s", target, expected) - g.Expect(err).NotTo(HaveOccurred()) - } -} - func testList() { cases := []struct { Selector string @@ -30,42 +14,81 @@ func testList() { }{ { Selector: "test=self", - Expected: `[{ - "direction": "EGRESS", - "kind": "CiliumNetworkPolicy", - "namespace": "default", - "name": "l3-egress" - }]`, + Expected: `EGRESS,CiliumNetworkPolicy,default,l3-baseline +EGRESS,CiliumNetworkPolicy,default,l3-egress +EGRESS,CiliumNetworkPolicy,default,l4-egress +INGRESS,CiliumNetworkPolicy,default,l3-baseline`, }, { Selector: "test=l3-ingress-explicit-allow", - Expected: `[{ - "direction": "INGRESS", - "kind": "CiliumNetworkPolicy", - "namespace": "default", - "name": "l3-ingress-explicit-allow" - }]`, + Expected: `EGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-ingress-explicit-allow`, }, { - Selector: "test=l3-ingress-no-rule", - Expected: `[]`, + Selector: "test=l3-ingress-implicit-deny", + Expected: `EGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-baseline`, }, { Selector: "test=l3-ingress-explicit-deny", - Expected: `[{ - "direction": "INGRESS", - "kind": "CiliumNetworkPolicy", - "namespace": "default", - "name": "l3-ingress-explicit-deny" - }]`, + Expected: `EGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-ingress-explicit-deny`, + }, + { + Selector: "test=l3-egress-implicit-deny", + Expected: `EGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-baseline`, + }, + { + Selector: "test=l3-egress-explicit-deny", + Expected: `EGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-baseline`, + }, + { + Selector: "test=l4-ingress-explicit-allow-any", + Expected: `EGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l4-ingress-explicit-allow-any`, + }, + { + Selector: "test=l4-ingress-explicit-allow-tcp", + Expected: `EGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l4-ingress-explicit-allow-tcp`, + }, + { + Selector: "test=l4-ingress-explicit-deny-any", + Expected: `EGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l4-ingress-explicit-deny-any`, + }, + { + Selector: "test=l4-ingress-explicit-deny-udp", + Expected: `EGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l4-ingress-explicit-deny-udp`, + }, + { + Selector: "test=l4-egress-explicit-deny-any", + Expected: `EGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-baseline`, + }, + { + Selector: "test=l4-egress-explicit-deny-tcp", + Expected: `EGRESS,CiliumNetworkPolicy,default,l3-baseline +INGRESS,CiliumNetworkPolicy,default,l3-baseline`, }, } It("should list applied policies", func() { for _, c := range cases { podName := onePodByLabelSelector(Default, "default", c.Selector) - result := runViewerSafe(Default, nil, "list", "-o=json", podName) - testJson(Default, result, c.Expected) + result := runViewerSafe(Default, nil, "list", "-o=json", "--no-headers", podName) + result = jqSafe(Default, result, "-r", ".[] | [.direction, .kind, .namespace, .name] | @csv") + resultString := strings.Replace(string(result), `"`, "", -1) + Expect(resultString).To(Equal(c.Expected), "compare failed. selector: %s, actual: %s, expected: %s", c.Selector, resultString, c.Expected) } }) } diff --git a/e2e/testdata/policy/README.md b/e2e/testdata/policy/README.md new file mode 100644 index 0000000..d685ede --- /dev/null +++ b/e2e/testdata/policy/README.md @@ -0,0 +1,15 @@ +# NetworkPolicy Configuration for Test Pods + +| Target | From self (Egress) | To pod (Ingress) | +|-|-|-| +| l3-ingress-explicit-allow | allow | allow | +| l3-ingress-implicit-deny | allow | - | +| l3-ingress-explicit-deny | allow | deny | +| l3-egress-implicit-deny | - | - | +| l3-egress-explicit-deny | deny | - | +| l4-ingress-explicit-allow-any | allow (L4) | allow (L4) | +| l4-ingress-explicit-allow-tcp | allow (L4) | allow (L4) | +| l4-ingress-explicit-deny-any | allow (L4) | deny (L4) | +| l4-ingress-explicit-deny-udp | allow (L4) | deny (L4) | +| l4-egress-explicit-deny-any | deny (L4) | - | +| l4-egress-explicit-deny-tcp | deny (L4) | - | diff --git a/e2e/testdata/policy/l3.yaml b/e2e/testdata/policy/l3.yaml index ccc3433..15c42ef 100644 --- a/e2e/testdata/policy/l3.yaml +++ b/e2e/testdata/policy/l3.yaml @@ -1,5 +1,22 @@ apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy +metadata: + name: l3-baseline +spec: + endpointSelector: + matchLabels: + k8s:group: test + ingressDeny: + - fromEndpoints: + - matchLabels: + k8s:test: scapegoat + egressDeny: + - toEndpoints: + - matchLabels: + k8s:test: scapegoat +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy metadata: name: l3-egress spec: @@ -10,6 +27,9 @@ spec: - toEndpoints: - matchLabels: k8s:test: l3-ingress-explicit-allow + - toEndpoints: + - matchLabels: + k8s:test: l3-ingress-no-rule - toEndpoints: - matchLabels: k8s:test: l3-ingress-implicit-deny diff --git a/e2e/testdata/policy/l4.yaml b/e2e/testdata/policy/l4.yaml new file mode 100644 index 0000000..565d6a2 --- /dev/null +++ b/e2e/testdata/policy/l4.yaml @@ -0,0 +1,115 @@ +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: l4-egress +spec: + endpointSelector: + matchLabels: + k8s:test: self + egress: + - toEndpoints: + - matchLabels: + k8s:test: l4-ingress-explicit-allow-any + toPorts: + - ports: + - port: "53" + - toEndpoints: + - matchLabels: + k8s:test: l4-ingress-explicit-allow-tcp + toPorts: + - ports: + - port: "8080" + protocol: TCP + - toEndpoints: + - matchLabels: + k8s:test: l4-ingress-explicit-deny-any + toPorts: + - ports: + - port: "53" + - toEndpoints: + - matchLabels: + k8s:test: l4-ingress-explicit-deny-udp + toPorts: + - ports: + - port: "161" # SNMP (UDP) + protocol: UDP + egressDeny: + - toEndpoints: + - matchLabels: + k8s:test: l4-egress-explicit-deny-any + toPorts: + - ports: + - port: "53" + - toEndpoints: + - matchLabels: + k8s:test: l4-egress-explicit-deny-tcp + toPorts: + - ports: + - port: "8080" + protocol: TCP +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: l4-ingress-explicit-allow-any +spec: + endpointSelector: + matchLabels: + k8s:test: l4-ingress-explicit-allow-any + ingress: + - fromEndpoints: + - matchLabels: + k8s:test: self + toPorts: + - ports: + - port: "53" +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: l4-ingress-explicit-allow-tcp +spec: + endpointSelector: + matchLabels: + k8s:test: l4-ingress-explicit-allow-tcp + ingress: + - fromEndpoints: + - matchLabels: + k8s:test: self + toPorts: + - ports: + - port: "8080" + protocol: TCP +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: l4-ingress-explicit-deny-any +spec: + endpointSelector: + matchLabels: + k8s:test: l4-ingress-explicit-deny-any + ingressDeny: + - fromEndpoints: + - matchLabels: + k8s:test: self + toPorts: + - ports: + - port: "53" +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: l4-ingress-explicit-deny-udp +spec: + endpointSelector: + matchLabels: + k8s:test: l4-ingress-explicit-deny-udp + ingressDeny: + - fromEndpoints: + - matchLabels: + k8s:test: self + toPorts: + - ports: + - port: "161" # SNMP (UDP) + protocol: UDP diff --git a/e2e/utils_test.go b/e2e/utils_test.go index b89dcb9..b1aca35 100644 --- a/e2e/utils_test.go +++ b/e2e/utils_test.go @@ -65,6 +65,6 @@ func onePodByLabelSelector(g Gomega, namespace, selector string) string { data := kubectlSafe(g, nil, "get", "pod", "-n", namespace, "-l", selector, "-o=json") count, err := strconv.Atoi(string(jqSafe(g, data, "-r", ".items | length"))) g.Expect(err).NotTo(HaveOccurred()) - g.Expect(count).To(Equal(1)) + g.Expect(count).To(Equal(1), "namespace: %s, selector: %s", namespace, selector) return string(jqSafe(g, data, "-r", ".items[0].metadata.name")) } diff --git a/go.mod b/go.mod index 704bde4..0904b62 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/onsi/ginkgo/v2 v2.20.2 github.com/onsi/gomega v1.34.2 github.com/spf13/cobra v1.8.1 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 k8s.io/apimachinery v0.29.3 k8s.io/client-go v0.29.3 ) @@ -77,7 +78,6 @@ require ( go.opentelemetry.io/otel/trace v1.21.0 // indirect go.uber.org/multierr v1.11.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect golang.org/x/sync v0.8.0 // indirect From eb5ba6d4381b1a48eeb6d0d05dde6b4b918d28e5 Mon Sep 17 00:00:00 2001 From: Daichi Sakaue Date: Wed, 16 Oct 2024 14:59:53 +0900 Subject: [PATCH 2/7] Apply suggestions from code review Co-authored-by: Tomoki Sugiura --- cmd/list.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/list.go b/cmd/list.go index 0610a96..b9b02ba 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -42,9 +42,9 @@ type derivedFromEntry struct { Name string `json:"name"` } -func compareDerivedFromEntry(x, y *derivedFromEntry) bool { - if x.Direction != y.Direction { - return strings.Compare(x.Direction, y.Direction) < 0 +func lessDerivedFromEntry(x, y *derivedFromEntry) bool { + if strings.Compare(x.Direction, y.Direction) < 0 { + return true } if x.Kind != y.Kind { return strings.Compare(x.Kind, y.Kind) < 0 From 0e43978a79c27f8bc4fd56eb939285c27ff2dce1 Mon Sep 17 00:00:00 2001 From: Daichi Sakaue Date: Wed, 16 Oct 2024 15:29:03 +0900 Subject: [PATCH 3/7] Fix compare result Signed-off-by: Daichi Sakaue --- cmd/list.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/list.go b/cmd/list.go index b9b02ba..6ce423c 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -43,8 +43,8 @@ type derivedFromEntry struct { } func lessDerivedFromEntry(x, y *derivedFromEntry) bool { - if strings.Compare(x.Direction, y.Direction) < 0 { - return true + if x.Direction != y.Direction { + return strings.Compare(x.Direction, y.Direction) < 0 } if x.Kind != y.Kind { return strings.Compare(x.Kind, y.Kind) < 0 @@ -114,7 +114,7 @@ func runList(ctx context.Context, w io.Writer, name string) error { } policyList := maps.Keys(policySet) - sort.Slice(policyList, func(i, j int) bool { return compareDerivedFromEntry(&policyList[i], &policyList[j]) }) + sort.Slice(policyList, func(i, j int) bool { return lessDerivedFromEntry(&policyList[i], &policyList[j]) }) switch rootOptions.output { case OutputJson: From 31822e45a847f7638ad79b62b694cd3e261f338a Mon Sep 17 00:00:00 2001 From: Daichi Sakaue Date: Wed, 16 Oct 2024 16:51:31 +0900 Subject: [PATCH 4/7] Update cmd/list.go Co-authored-by: Tomoki Sugiura --- cmd/list.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/list.go b/cmd/list.go index 6ce423c..fa85452 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -127,8 +127,7 @@ func runList(ctx context.Context, w io.Writer, name string) error { case OutputSimple: tw := tabwriter.NewWriter(w, 0, 1, 1, ' ', 0) if !rootOptions.noHeaders { - _, err := tw.Write([]byte("DIRECTION\tKIND\tNAMESPACE\tNAME\n")) - if err != nil { + if _, err := tw.Write([]byte("DIRECTION\tKIND\tNAMESPACE\tNAME\n")); err != nil { return err } } From 5bb2a0b0fc61167d3788caa76c4019512a93dfc4 Mon Sep 17 00:00:00 2001 From: Daichi Sakaue Date: Wed, 16 Oct 2024 16:57:57 +0900 Subject: [PATCH 5/7] Reflect comments Signed-off-by: Daichi Sakaue --- cmd/list.go | 3 +-- e2e/utils_test.go | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cmd/list.go b/cmd/list.go index fa85452..e10b158 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -132,8 +132,7 @@ func runList(ctx context.Context, w io.Writer, name string) error { } } for _, p := range policyList { - _, err := tw.Write([]byte(fmt.Sprintf("%v\t%v\t%v\t%v\n", p.Direction, p.Kind, p.Namespace, p.Name))) - if err != nil { + if _, err := tw.Write([]byte(fmt.Sprintf("%v\t%v\t%v\t%v\n", p.Direction, p.Kind, p.Namespace, p.Name))); err != nil { return err } } diff --git a/e2e/utils_test.go b/e2e/utils_test.go index b1aca35..c84bdc8 100644 --- a/e2e/utils_test.go +++ b/e2e/utils_test.go @@ -26,12 +26,11 @@ func runCommand(path string, input []byte, args ...string) ([]byte, []byte, erro if input != nil { cmd.Stdin = bytes.NewReader(input) } - err := cmd.Run() - if err == nil { - return stdout.Bytes(), stderr.Bytes(), nil + if err := cmd.Run(); err != nil { + _, file := filepath.Split(path) + return stdout.Bytes(), stderr.Bytes(), fmt.Errorf("%s failed with %s: stderr=%s", file, err, stderr) } - _, file := filepath.Split(path) - return stdout.Bytes(), stderr.Bytes(), fmt.Errorf("%s failed with %s: stderr=%s", file, err, stderr) + return stdout.Bytes(), stderr.Bytes(), nil } func kubectl(input []byte, args ...string) ([]byte, []byte, error) { From a1ac70d950e063bfc5252d4eb1d13038b2d1844c Mon Sep 17 00:00:00 2001 From: Daichi Sakaue Date: Wed, 16 Oct 2024 17:32:13 +0900 Subject: [PATCH 6/7] Modify compare procedure Signed-off-by: Daichi Sakaue --- cmd/list.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/cmd/list.go b/cmd/list.go index e10b158..6f8d576 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -43,19 +43,17 @@ type derivedFromEntry struct { } func lessDerivedFromEntry(x, y *derivedFromEntry) bool { - if x.Direction != y.Direction { - return strings.Compare(x.Direction, y.Direction) < 0 + ret := strings.Compare(x.Direction, y.Direction) + if ret == 0 { + ret = strings.Compare(x.Kind, y.Kind) } - if x.Kind != y.Kind { - return strings.Compare(x.Kind, y.Kind) < 0 + if ret == 0 { + ret = strings.Compare(x.Namespace, y.Namespace) } - if x.Namespace != y.Namespace { - return strings.Compare(x.Namespace, y.Namespace) < 0 + if ret == 0 { + ret = strings.Compare(x.Name, y.Name) } - if x.Name != y.Name { - return strings.Compare(x.Name, y.Name) < 0 - } - return false + return ret < 0 } func parseDerivedFromEntry(input []string, direction string) derivedFromEntry { From eea9c1d58cb195206ec3914029c198c14bc6638e Mon Sep 17 00:00:00 2001 From: Daichi Sakaue Date: Wed, 16 Oct 2024 17:58:51 +0900 Subject: [PATCH 7/7] Add comment Signed-off-by: Daichi Sakaue --- cmd/list.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/list.go b/cmd/list.go index 6f8d576..fd884d9 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -93,6 +93,7 @@ func runList(ctx context.Context, w io.Writer, name string) error { return err } + // The same rule appears multiple times in the response, so we need to dedup it policySet := make(map[derivedFromEntry]struct{}) ingressRules := response.Payload.Status.Policy.Realized.L4.Ingress