From 84ddee3af135fff027627ca30d55b5f1b92a28c3 Mon Sep 17 00:00:00 2001 From: shireenf-ibm Date: Wed, 15 May 2024 12:52:02 +0300 Subject: [PATCH 01/12] always keep representative peers which match all-namespaces --- pkg/netpol/connlist/connlist_test.go | 7 ++ pkg/netpol/eval/exposure.go | 7 ++ ...space_with_podSelector_connlist_output.dot | 17 +++++ ...e_with_podSelector_connlist_output.dot.png | Bin 0 -> 19973 bytes ...e_with_podSelector_connlist_output.dot.svg | 54 ++++++++++++++ ...space_with_podSelector_connlist_output.txt | 6 ++ .../backend.yaml | 53 ++++++++++++++ .../frontend.yaml | 67 ++++++++++++++++++ .../netpols.yaml | 59 +++++++++++++++ 9 files changed, 270 insertions(+) create mode 100644 test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot create mode 100644 test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot.png create mode 100644 test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot.svg create mode 100644 test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.txt create mode 100644 tests/test_exposure_to_any_namespace_with_podSelector/backend.yaml create mode 100644 tests/test_exposure_to_any_namespace_with_podSelector/frontend.yaml create mode 100644 tests/test_exposure_to_any_namespace_with_podSelector/netpols.yaml diff --git a/pkg/netpol/connlist/connlist_test.go b/pkg/netpol/connlist/connlist_test.go index 79bef84f..0ed37984 100644 --- a/pkg/netpol/connlist/connlist_test.go +++ b/pkg/netpol/connlist/connlist_test.go @@ -913,4 +913,11 @@ var goodPathTests = []struct { focusWorkload: "ratings-v1-b6994bb9", outputFormats: ExposureValidFormats, }, + { + // test that when the rule enable any-namespace with podSelector, a representative peer is created even + // if there is a matching pod in a specific namespace + testDirName: "test_exposure_to_any_namespace_with_podSelector", + exposureAnalysis: true, + outputFormats: ExposureValidFormats, + }, } diff --git a/pkg/netpol/eval/exposure.go b/pkg/netpol/eval/exposure.go index 162ca514..78cce765 100644 --- a/pkg/netpol/eval/exposure.go +++ b/pkg/netpol/eval/exposure.go @@ -68,12 +68,19 @@ func (pe *PolicyEngine) extractLabelsAndRefineRepresentativePeers(podObj *k8s.Po // refineRepresentativePeersMatchingLabels removes from the policy engine all representative peers // with labels matching the given labels of a real pod +// representative peers matching any-namespace will not be removed. func (pe *PolicyEngine) refineRepresentativePeersMatchingLabels(realPodLabels, realNsLabels map[string]string) { keysToDelete := make([]string, 0) // look for representative peers with labels matching the given real pod's (and its namespace) labels for key, peer := range pe.representativePeersMap { potentialPodSelector := labels.SelectorFromSet(labels.Set(peer.Pod.Labels)) potentialNsSelector := labels.SelectorFromSet(labels.Set(peer.PotentialNamespaceLabels)) + if potentialNsSelector.Empty() { // representative peer that matches any-namespace, will not be removed + continue + } + // remove representative peer matching both realPodLabels and realNsLabels. + // a representative peer that matches any-pod in a specific namespace, and real Labels are for a specific pod in same namespace, + // the representative peer will be removed (we have at least one real pod in that namespace) if potentialPodSelector.Matches(labels.Set(realPodLabels)) && potentialNsSelector.Matches(labels.Set(realNsLabels)) { keysToDelete = append(keysToDelete, key) } diff --git a/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot b/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot new file mode 100644 index 00000000..d3321756 --- /dev/null +++ b/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot @@ -0,0 +1,17 @@ +digraph { + subgraph "cluster_default" { + color="black" + fontcolor="black" + "default/backend[Deployment]" [label="backend[Deployment]" color="blue" fontcolor="blue"] + "default/frontend[Deployment]" [label="frontend[Deployment]" color="blue" fontcolor="blue"] + label="default" + } + subgraph "cluster_all namespaces" { + color="red2" + fontcolor="red2" + "pod with {app=frontend}_in_all namespaces" [label="pod with {app=frontend}" color="red2" fontcolor="red2"] + label="all namespaces" + } + "default/frontend[Deployment]" -> "default/backend[Deployment]" [label="TCP 9090" color="gold2" fontcolor="darkgreen"] + "pod with {app=frontend}_in_all namespaces" -> "default/backend[Deployment]" [label="TCP 9090" color="gold2" fontcolor="darkgreen"] +} \ No newline at end of file diff --git a/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot.png b/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot.png new file mode 100644 index 0000000000000000000000000000000000000000..8cf87301e9a887bfc484566f2618fd64ec86be1b GIT binary patch literal 19973 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Ïl{KoT(H)N2^!t7usW*#B{PsD8aLc#Z>l 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

w~aFv?#f(jf!DH!p0RaV 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 literal 0 HcmV?d00001 diff --git a/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot.svg b/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot.svg new file mode 100644 index 00000000..b8fed0a2 --- /dev/null +++ b/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot.svg @@ -0,0 +1,54 @@ + + + + + + + + +cluster_default + +default + + +cluster_all namespaces + +all namespaces + + + +default/backend[Deployment] + +backend[Deployment] + + + +default/frontend[Deployment] + +frontend[Deployment] + + + +default/frontend[Deployment]->default/backend[Deployment] + + +TCP 9090 + + + +pod with {app=frontend}_in_all namespaces + +pod with {app=frontend} + + + +pod with {app=frontend}_in_all namespaces->default/backend[Deployment] + + +TCP 9090 + + + diff --git a/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.txt b/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.txt new file mode 100644 index 00000000..be7efc75 --- /dev/null +++ b/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.txt @@ -0,0 +1,6 @@ +default/frontend[Deployment] => default/backend[Deployment] : TCP 9090 + +Exposure Analysis Result: + +Ingress Exposure: +default/backend[Deployment] <= [all namespaces]/[pod with {app=frontend}] : TCP 9090 diff --git a/tests/test_exposure_to_any_namespace_with_podSelector/backend.yaml b/tests/test_exposure_to_any_namespace_with_podSelector/backend.yaml new file mode 100644 index 00000000..3537d90d --- /dev/null +++ b/tests/test_exposure_to_any_namespace_with_podSelector/backend.yaml @@ -0,0 +1,53 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: backend +spec: + selector: + matchLabels: + app: backendservice + template: + metadata: + labels: + app: backendservice + spec: + containers: + - name: server + image: backendservice + ports: + - containerPort: 9090 + readinessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 9090 + livenessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 9090 + env: + - name: PORT + value: "9090" + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: backendservice +spec: + type: ClusterIP + selector: + app: backendservice + ports: + - name: http + port: 9090 + targetPort: 9090 + diff --git a/tests/test_exposure_to_any_namespace_with_podSelector/frontend.yaml b/tests/test_exposure_to_any_namespace_with_podSelector/frontend.yaml new file mode 100644 index 00000000..e877eceb --- /dev/null +++ b/tests/test_exposure_to_any_namespace_with_podSelector/frontend.yaml @@ -0,0 +1,67 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: frontend +spec: + selector: + matchLabels: + app: frontend + template: + metadata: + labels: + app: frontend + spec: + containers: + - name: server + image: frontend + ports: + - containerPort: 8080 + readinessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 8080 + livenessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 8080 + env: + - name: PORT + value: "8080" + - name: BACKEND_SERVICE_ADDR + value: "backendservice:9090" + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: frontend +spec: + type: ClusterIP + selector: + app: frontend + ports: + - name: http + port: 80 + targetPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: frontend-external +spec: + type: LoadBalancer + selector: + app: frontend + ports: + - name: http + port: 80 + targetPort: 8080 diff --git a/tests/test_exposure_to_any_namespace_with_podSelector/netpols.yaml b/tests/test_exposure_to_any_namespace_with_podSelector/netpols.yaml new file mode 100644 index 00000000..86103828 --- /dev/null +++ b/tests/test_exposure_to_any_namespace_with_podSelector/netpols.yaml @@ -0,0 +1,59 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + creationTimestamp: null + name: backend-netpol +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: + matchLabels: + app: frontend + ports: + - port: 9090 + protocol: TCP + podSelector: + matchLabels: + app: backendservice + policyTypes: + - Ingress + - Egress +status: {} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + creationTimestamp: null + name: frontend-netpol +spec: + egress: + - ports: + - port: 9090 + protocol: TCP + to: + - podSelector: + matchLabels: + app: backendservice + podSelector: + matchLabels: + app: frontend + policyTypes: + - Ingress + - Egress +status: {} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + creationTimestamp: null + name: default-deny-in-namespace +spec: + podSelector: {} + policyTypes: + - Ingress + - Egress +status: {} + From 8ef848ac60ed6e64b2c3598218763076df770b76 Mon Sep 17 00:00:00 2001 From: shireenf-ibm Date: Wed, 15 May 2024 21:27:57 +0300 Subject: [PATCH 02/12] update test output after merge --- ...with_pod_selector_in_any_ns_connlist_output.dot.svg | 10 +++++----- ..._any_namespace_with_podSelector_connlist_output.dot | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test_outputs/connlist/exposure_test_conn_with_pod_selector_in_any_ns_connlist_output.dot.svg b/test_outputs/connlist/exposure_test_conn_with_pod_selector_in_any_ns_connlist_output.dot.svg index d147b6b2..64da2cb9 100644 --- a/test_outputs/connlist/exposure_test_conn_with_pod_selector_in_any_ns_connlist_output.dot.svg +++ b/test_outputs/connlist/exposure_test_conn_with_pod_selector_in_any_ns_connlist_output.dot.svg @@ -8,16 +8,16 @@ viewBox="0.00 0.00 414.89 278.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - -cluster_all namespaces - -all namespaces - cluster_hello_world hello-world + +cluster_all namespaces + +all namespaces + hello-world/workload-a[Deployment] diff --git a/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot b/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot index d3321756..30d7b1ab 100644 --- a/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot +++ b/test_outputs/connlist/exposure_test_exposure_to_any_namespace_with_podSelector_connlist_output.dot @@ -13,5 +13,5 @@ digraph { label="all namespaces" } "default/frontend[Deployment]" -> "default/backend[Deployment]" [label="TCP 9090" color="gold2" fontcolor="darkgreen"] - "pod with {app=frontend}_in_all namespaces" -> "default/backend[Deployment]" [label="TCP 9090" color="gold2" fontcolor="darkgreen"] + "pod with {app=frontend}_in_all namespaces" -> "default/backend[Deployment]" [label="TCP 9090" color="gold2" fontcolor="darkgreen" weight=1] } \ No newline at end of file From 3c9e43066968b56b7da3aae890bc9908fe00ce12 Mon Sep 17 00:00:00 2001 From: shireenf-ibm Date: Thu, 16 May 2024 10:21:00 +0300 Subject: [PATCH 03/12] examples with rules exposing pod to an existing ns --- pkg/netpol/connlist/connlist_test.go | 10 ++ ...pods_in_an_existing_ns_connlist_output.dot | 23 ++++ ..._in_an_existing_ns_connlist_output.dot.png | Bin 0 -> 39303 bytes ..._in_an_existing_ns_connlist_output.dot.svg | 95 ++++++++++++++++ ...pods_in_an_existing_ns_connlist_output.txt | 18 ++++ ..._pod_in_an_existing_ns_connlist_output.dot | 24 +++++ ..._in_an_existing_ns_connlist_output.dot.png | Bin 0 -> 46299 bytes ..._in_an_existing_ns_connlist_output.dot.svg | 101 ++++++++++++++++++ ..._pod_in_an_existing_ns_connlist_output.txt | 18 ++++ .../backend.yaml | 40 +++++++ .../netpol.yaml | 25 +++++ .../ns_and_deployments.yaml | 31 ++++++ .../backend.yaml | 40 +++++++ .../netpol.yaml | 27 +++++ .../ns_and_deployments.yaml | 31 ++++++ 15 files changed, 483 insertions(+) create mode 100644 test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot create mode 100644 test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot.png create mode 100644 test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot.svg create mode 100644 test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.txt create mode 100644 test_outputs/connlist/exposure_test_conn_to_new_pod_in_an_existing_ns_connlist_output.dot create mode 100644 test_outputs/connlist/exposure_test_conn_to_new_pod_in_an_existing_ns_connlist_output.dot.png create mode 100644 test_outputs/connlist/exposure_test_conn_to_new_pod_in_an_existing_ns_connlist_output.dot.svg create mode 100644 test_outputs/connlist/exposure_test_conn_to_new_pod_in_an_existing_ns_connlist_output.txt create mode 100644 tests/test_conn_to_all_pods_in_an_existing_ns/backend.yaml create mode 100644 tests/test_conn_to_all_pods_in_an_existing_ns/netpol.yaml create mode 100644 tests/test_conn_to_all_pods_in_an_existing_ns/ns_and_deployments.yaml create mode 100644 tests/test_conn_to_new_pod_in_an_existing_ns/backend.yaml create mode 100644 tests/test_conn_to_new_pod_in_an_existing_ns/netpol.yaml create mode 100644 tests/test_conn_to_new_pod_in_an_existing_ns/ns_and_deployments.yaml diff --git a/pkg/netpol/connlist/connlist_test.go b/pkg/netpol/connlist/connlist_test.go index 3115ba74..3a0934dc 100644 --- a/pkg/netpol/connlist/connlist_test.go +++ b/pkg/netpol/connlist/connlist_test.go @@ -925,4 +925,14 @@ var goodPathTests = []struct { exposureAnalysis: true, outputFormats: ExposureValidFormats, }, + { + testDirName: "test_conn_to_all_pods_in_an_existing_ns", + exposureAnalysis: true, + outputFormats: ExposureValidFormats, + }, + { + testDirName: "test_conn_to_new_pod_in_an_existing_ns", + exposureAnalysis: true, + outputFormats: ExposureValidFormats, + }, } diff --git a/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot new file mode 100644 index 00000000..070b7ca5 --- /dev/null +++ b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot @@ -0,0 +1,23 @@ +digraph { + subgraph "cluster_backend" { + color="black" + fontcolor="black" + "backend/backend-app[Deployment]" [label="backend-app[Deployment]" color="blue" fontcolor="blue"] + label="backend" + } + subgraph "cluster_hello_world" { + color="black" + fontcolor="black" + "hello-world/workload-a[Deployment]" [label="workload-a[Deployment]" color="blue" fontcolor="blue"] + label="hello-world" + } + "0.0.0.0-255.255.255.255" [label="0.0.0.0-255.255.255.255" color="red2" fontcolor="red2"] + "entire-cluster" [label="entire-cluster" color="red2" fontcolor="red2" shape=diamond] + "0.0.0.0-255.255.255.255" -> "backend/backend-app[Deployment]" [label="All Connections" color="gold2" fontcolor="darkgreen"] + "backend/backend-app[Deployment]" -> "0.0.0.0-255.255.255.255" [label="All Connections" color="gold2" fontcolor="darkgreen"] + "backend/backend-app[Deployment]" -> "entire-cluster" [label="All Connections" color="gold2" fontcolor="darkgreen" weight=0.5] + "backend/backend-app[Deployment]" -> "hello-world/workload-a[Deployment]" [label="TCP 8050" color="gold2" fontcolor="darkgreen"] + "entire-cluster" -> "backend/backend-app[Deployment]" [label="All Connections" color="gold2" fontcolor="darkgreen" weight=1] + "hello-world/workload-a[Deployment]" -> "backend/backend-app[Deployment]" [label="All Connections" color="gold2" fontcolor="darkgreen"] + "hello-world/workload-a[Deployment]" -> "entire-cluster" [label="All Connections" color="gold2" fontcolor="darkgreen" weight=0.5] +} \ No newline at end of file diff --git a/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot.png b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot.png new file mode 100644 index 0000000000000000000000000000000000000000..a6827e79c44f61abce6e4cda49f2197a23ca8ee0 GIT binary patch literal 39303 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�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�{%KTq;*X4dA${+%-3f>}h7C6(xz?xq@LeXtTj@s%MRpYf z12q5LWm$OS_&6@4p+;~m%e0ewLBf9;`#WGs2-Vd04wcyZbMLnfxL*1RGk zKWjv64jy0be^TRB^ifU0s?~#^*AISI{d`N)yh#21G=OLJ1!KeYdj)l?i9+T4&KAp~ z@h-n)iy_KPmCc*u9*FV^B9e*$waCDST55;^s=?LkS&D2*ieWijaL+to4>C8b65osVdj7Cn5ey$N-Wd6_e-jCJ#&!1Bx zuhivFQ$y-D=@ym6Au0>agevSl#^;`(=fIz{zEXa9(cvj6>ZKEMdI)_$inJNY!cB1T zK1ONf_f#Hf39}dr#<1$frcuEQ>)CZ*Uc73~46xM8lUIvtYuu^*y`>dcx(&Z)S@S#^-C{GrSSTPC;dL~?9X)wy^KHBRL=;KwEO6#aeb#gKQ|Hg-M&)a{@B*v2I6g>DslVOM+^*d&M4o@XNjrd zp5Yg!O9Jl4_appVx~5H=l!o~($2Dv|e%#7Y#{+)l z)9aVRxAZC9q@TD&>nt|QXQbR9oKDTdgO237{W*)oWUqdGFG-}97MUEbe%tmjw|>Mx zQt@B!vA_4(8|<9Q$~;V`x~_e;&d!b83H34|J*p0c`C+UIZr5iesh5VsVqAw>nR)sP zRbF9schU~rifa)I?%5q#L3}>=vs*-jyn4`hg+NcM-2k7F<*rL<ATNl>}`8q z60+gL^IrwO(r{SpU0?q}iSY!ZaVh;6&xF+d9IZa|I8hR`)}Y&PLC{v} zOd8VCI>1NKmN}RSka*--aKg)&Ji2@9!c8eD8!}9d&`flh!S&MMPe^1IH(btuWHFQ3 zb+~AxrH4r9cvjnO>l++xn1W@b5mg&&wxEgT{XH?oT?-n0jXU2>2W^7^;21A&tUhvv zYN^cCj)_X z|G4En`G}sMQNGe|Twaf%t==`XxqkMW7%&eKpzR@4-h(jdC!W0{hq)+m(xx}bs%}_f zM(wk02jf@lgCj_n`X~o-E-63YEQNUK$U%qoTQn~B=YPt(z_fNct_xuxpr9S0lBQYa z3l*Z0o7f8G1boSDp=nIwBkHv4@(n`b#ceKK|!JzIMZ zVw(&zPDPXfYVc(3b5O?%>gf`|d#f9JH+r zgxXjQGKlJ0&-R18-I5|o$YQpqxQ&(l)>NZCy7)HQ$UAsSTu3Csy!^y+BQgJSWNw|b zj={1mr91D=uG(Zj&y=7*oxA^{Sf-KDgQ@Pw1+Iz+L4NA;iElT|*J#Fyi|u1ltlB&F zOG7j4qW3#pNn}0C()yWB4z&^gu(ubj24O#?#a#`}>7?W~I%X5+UCSb}tT1Ahz66nk zgX0{0+uyV%S{>zA9=hUw&a` z2AwNc#?SsRTZuoMFT;^Lk&*Y-2-w+{o`!Go3P5jq>S_R!+0FR@C*3HE!(GeseVX&CZDe|3a8a zwKfLBYInQ(d~T#CP`vN#E7sn8{7`;V?28~ZcK1O}Q1JfacA?#$AvU%qcT%f=@00x< zi?NLu2$#$*7(Q4!N0uZ1Q7BLH#l`fSzIh9wVFBjMdmHihM@ES32Q{(g zH(h*5^GR&%I$jc;b82uffLylKsm2s-OXZBE3k&g)nOi{h%~*YlTdAx1h-&5SlC*|u z-BkZ93R{F`D~1f--rfyCSrA`{UB|U$aQek=rY)a4o}9q+^4VRvTGjjTQKVQvhEYZe zL%yQ}+UNLcGGvr1xEznz4PeD$xACIC{TI2L5xVvwZ9lv+E{81i9c%vnna&ERj~0|e z2HMbcm`(={4feE+qaw)Hdmd?xxuf8NMt#?EnXZ9YwmVCnM2NC@8a}TtP(2t`!mFId z`vAAge@|R0x2z`cB{?v_Sk)gZqE4hl9l0ev*bY|_t-%E7tr#c;kZkXej!)BU^VbjS ze+c5j8JckCuV{50;xxRxjD$N+4`!)gENpbpmwL=XftjSj&F$L6R}z+l`Jqe7$l(EB z@0p8E25fZ6%@4N`?rxZeTX#_VBTll)VHa7TDyNj!EPF=edky5(?q0z~NOpI>664#5 z#G<2H2@zn3zi{J-ICVRdd$^#)6Gs7wC^I$hPlowmKGeBHd;AG#DHVEACz;vRYi4HU z-7$mer8l#9^{zr+A^avT0m_m>1M0T}LiC`Xj_%XrZR*NbAUbovujfwKuga-dx3bWX z(~xg$IuquGrsM#EUTm0h`gISK{v@Kr^!sy6v>kHJ&{XeG1_&J4@H6jGIyFOtrc1U= zKWaX(iYE*Vy6FU*K6jqDkmk3aeg7!+*67;dPZK7VR6jpdA}zfB9}N%THqv!qv@R>F zai`B!>}@K6KapY2FfvQu*2L-PQ$hx?u^A36cDfn5;d$)g_wGmklMklz1rg1I@aIaa zVw4CppR1&9d`a70g4;bV-U~l7MICavSnmf;vG*s{cM@3=9qFVZd5Wf#7Q%6|f$zXc z8UOP7Xz%t!p+84%IK9-N)7MB1sIK5 za^!ugIFho8J^n%WbFLaM_Gg#Qot+5YASsMb_S9qXl18Pz9=Kk#f@f-W^$8^HOba8mAd)V6b~{BP8?$dowawC8p>qP`_Qkgns194LIlPbiA+0MQ$ZSVT0847Z%=q*WfBrv%)(M+7AxrMp7$ zN<12O#$95#4BFz;!rl3{so>yY)jhwhg`{D35gAj-kVXJ$0Q_*(A6{Nf?*2tPzF@eG z+y2&?Aui%FI7m}#CFz6q-E~>Qe<=LyG?Tv@@<-J)t(EsTDWt}V_X-7AS^(gV11}xD z4V=BRWN0CV{a`!x^tiB;25_PjnyL;CaIT_Z&f}$F3#{CoU^K4Mu}XeEcJpoi8c$e3 zV#3-L?I$Il#@RiJedD#PuKk6-=XoJJJ<1kzQ5mHkf?Oz)^?q)YPi>))a>W|DJ`0L}ZfkAoQ5o$TxY+u8Y1#eG0s`$)$J$Zt{K=`qm~*sQYX z1Pr6xhQMtIj;5#Q=v5pbNJ2rH;j;lKolPoIqkV32bsXu{obS5PnizY_Ew1v zIyhL+%%-Qe*o0eLGx1eW6^Y*c?)>E{sEO<9c$K+WZ)Z9cQNl~4ZRfeB`H2iFq zgim||=Sz99zCJ!(Yi7Z6n4xd@(NIX!*}7>+_+PG>K-*Y%(OMLuD!^}&CYb2|pj6nD zGEI=NH+H|0`FqUkxmy=vhp3pDeSgFqH#t*Si9#S!Qh*$aLJL?GM$30ZZcbD>Cu>lzu`Rc( z!gX+nizj>-tw=%h)Jng&IHj!2Opi7T@cklVVPRL7%QQzRN$hZ|SNHEZc_P6`x3MG! zfOEqf~|{D|`>U_DIKN!}=muB8|&`TRhu^6~cj#QHhh#0t5UJz~fVb zgEB!n7d0j!e!hv3WAOcZ)%#n~jt2DLKAx$EK=g`d;n+Ob-F|f~ z=;9zmU*#ebG{RVj($bF1(r(Eb{Af4UrIwXC0U(~uF@;w43cD%I27yGW116@Y%ZG7P zCue8X77$1s8=GdJk`o~?2B6YIy-xoA2)QoqeXf;&mu}I1CtrWSU`Zm>Sc_&0T#DWC-3XqF)n+$ z&M8Z8BL)zvzl_Vh+K!Sw=>CvH#bslauP*Ka~q0GL0g5X{u*Lyb)`gu}V$ z{rupZu=sd5BgO76oQJ{01b%_+!iB;cD+rZbW!To%=gE}=c>@DNd<^t6QlbT!`vJ3F z0(*!+uxJw{p9=gX5b)ku7(k5Is@v`f8`Oj3QG;T3dH^9;OC*9ODh3P?^Uv&RG$A12 z1<9+F)ZY;Hf*LR_{|#X&K?Fg^sTCE=xU@9QNu>KXKM%M*KGxmXc)9Y`eIM=0$_k6b zZ?hPFyJe=X$Np(ARQo=FF9*!0Ed}Imj28!vf}{~FnwK3Is2In=(ntDq!f#T; z4DjcdfKt(42CQE&ng=qe^RY_ox4PplfMWzkG%orJ7bIOMHMKSVE-j@Rq!1OWVa4Xn zg=ZCKT_YBJRnv~0oqOM?Zksc^e6Qj20_kjPe%tVy9i)F3Crop|M9I?N>Mm|wXFHuZ zA05xSS{cO98siq?EKo<6awpCSyN@4NsX-pxc#J;k`W>boS5`Es`OSx+-=eqh)zBU> z>Eqp)FjB?$yX~PvLR_Rrh_aA(6PshLk4%=k)*e{XLA@n~#3kl^t?cYELqjeKqT=ES z5{`4eRyRV2^uEnVwLARaytg%m%yPh5dE%!7t|J?sHIz(9=Z(goE1Sm#mN9#C^K;Fg z`j#;{hV#URlCM4eBO7nnlDLz_QeO|mzR~?!ic7wUn*RGNPffkDBe`+-CM^H-66qGP z<@xhpbLN7lDbqZer`6erfVqp6Z|w+4@;J@nr#xx6-{_)|Ow~fJ89g+Vdx* zX(q)W<&^VsEwT)fv@qzm?lL2*o3PO48w23eZN!Jrt(dX-JOb{JBiWoOdnA3;ZRVuo zYzH;1JkoKvJ*Dw^YN`7vzB!n`%Y9~p@S9>~r{%F- z;-#(VoXb+3e(Ju`)lNj`rpmCZh7d#vlkt63An3D1+w%gbhDC;vp3%p)d6 zbO-xtCneGwm{rK9Sz23{S0%#11n-VwQTcK0&C$TeU9?PQPqGHcfaBeM|U3t_}}AJQ4e7 zW9@lx=oq2_IcchR*?`9zcO5Lfp@l%;v_SX^iHabQK_G<%Az)Ib&>Hvuxx3k$uO@mF zJg`{DkZVsW<=E&PLKt@##+17n!94U&`zH-e + + + + + + + +cluster_backend + +backend + + +cluster_hello_world + +hello-world + + + +backend/backend-app[Deployment] + +backend-app[Deployment] + + + +hello-world/workload-a[Deployment] + +workload-a[Deployment] + + + +backend/backend-app[Deployment]->hello-world/workload-a[Deployment] + + +TCP 8050 + + + +0.0.0.0-255.255.255.255 + +0.0.0.0-255.255.255.255 + + + +backend/backend-app[Deployment]->0.0.0.0-255.255.255.255 + + +All Connections + + + +entire-cluster + +entire-cluster + + + +backend/backend-app[Deployment]->entire-cluster + + +All Connections + + + +hello-world/workload-a[Deployment]->backend/backend-app[Deployment] + + +All Connections + + + +hello-world/workload-a[Deployment]->entire-cluster + + +All Connections + + + +0.0.0.0-255.255.255.255->backend/backend-app[Deployment] + + +All Connections + + + +entire-cluster->backend/backend-app[Deployment] + + +All Connections + + + diff --git a/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.txt b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.txt new file mode 100644 index 00000000..153efa65 --- /dev/null +++ b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.txt @@ -0,0 +1,18 @@ +0.0.0.0-255.255.255.255 => backend/backend-app[Deployment] : All Connections +backend/backend-app[Deployment] => 0.0.0.0-255.255.255.255 : All Connections +backend/backend-app[Deployment] => hello-world/workload-a[Deployment] : TCP 8050 +hello-world/workload-a[Deployment] => backend/backend-app[Deployment] : All Connections + +Exposure Analysis Result: +Egress Exposure: +backend/backend-app[Deployment] => 0.0.0.0-255.255.255.255 : All Connections +backend/backend-app[Deployment] => entire-cluster : All Connections +hello-world/workload-a[Deployment] => entire-cluster : All Connections + +Ingress Exposure: +backend/backend-app[Deployment] <= 0.0.0.0-255.255.255.255 : All Connections +backend/backend-app[Deployment] <= entire-cluster : All Connections + +Workloads not protected by network policies: +backend/backend-app[Deployment] is not protected on Egress +backend/backend-app[Deployment] is not protected on Ingress diff --git a/test_outputs/connlist/exposure_test_conn_to_new_pod_in_an_existing_ns_connlist_output.dot b/test_outputs/connlist/exposure_test_conn_to_new_pod_in_an_existing_ns_connlist_output.dot new file mode 100644 index 00000000..42c84381 --- /dev/null +++ b/test_outputs/connlist/exposure_test_conn_to_new_pod_in_an_existing_ns_connlist_output.dot @@ -0,0 +1,24 @@ +digraph { + subgraph "cluster_backend" { + color="black" + fontcolor="black" + "backend/backend-app[Deployment]" [label="backend-app[Deployment]" color="blue" fontcolor="blue"] + "pod with {app=backend-new}_in_backend" [label="pod with {app=backend-new}" color="red2" fontcolor="red2"] + label="backend" + } + subgraph "cluster_hello_world" { + color="black" + fontcolor="black" + "hello-world/workload-a[Deployment]" [label="workload-a[Deployment]" color="blue" fontcolor="blue"] + label="hello-world" + } + "0.0.0.0-255.255.255.255" [label="0.0.0.0-255.255.255.255" color="red2" fontcolor="red2"] + "entire-cluster" [label="entire-cluster" color="red2" fontcolor="red2" shape=diamond] + "0.0.0.0-255.255.255.255" -> "backend/backend-app[Deployment]" [label="All Connections" color="gold2" fontcolor="darkgreen"] + "backend/backend-app[Deployment]" -> "0.0.0.0-255.255.255.255" [label="All Connections" color="gold2" fontcolor="darkgreen"] + "backend/backend-app[Deployment]" -> "entire-cluster" [label="All Connections" color="gold2" fontcolor="darkgreen" weight=0.5] + "entire-cluster" -> "backend/backend-app[Deployment]" [label="All Connections" color="gold2" fontcolor="darkgreen" weight=1] + "hello-world/workload-a[Deployment]" -> "backend/backend-app[Deployment]" [label="All Connections" color="gold2" fontcolor="darkgreen"] + "hello-world/workload-a[Deployment]" -> "entire-cluster" [label="All Connections" color="gold2" fontcolor="darkgreen" weight=0.5] + "pod with {app=backend-new}_in_backend" -> "hello-world/workload-a[Deployment]" [label="TCP 8050" color="gold2" fontcolor="darkgreen" weight=1] +} \ No newline at end of file diff --git a/test_outputs/connlist/exposure_test_conn_to_new_pod_in_an_existing_ns_connlist_output.dot.png b/test_outputs/connlist/exposure_test_conn_to_new_pod_in_an_existing_ns_connlist_output.dot.png new file mode 100644 index 0000000000000000000000000000000000000000..b6e50062e92d8d805cb62fbefaad20b3c3421c5c GIT binary patch literal 46299 zcmaI-by!u;_dX6ELb{|=QE8Bn?(XjH?(S~s25FG)?rsI?kPZcrF6sIWulMKs*K=Ku zo{O{D>^-w;X6|*bnFs|raa1HiBnSk8Dk&kN1cAU5Lm*HN2+-gT8U9%b_<}Q%78ij$ zzx>bZDoKJsNFkCUf+`+ahijfbDm!f)r@Opkhw14d@ffMF{c`c7pD_jNv=l3`4uhoZ z>spXlR;^WOTC9kys#ceu{I=A!k6uYOsdiGNEQHR*AXU|q)l(c=OF)yEeEXENv`cq# z62~ktypw0-OMCuuUhq4UJ~4_Uf-j^`w2h!PUQyATW^1XSJVWhl~@t9Nrfj60(L z-4!M-?)>k<;`2Z)^cWgp60uzK($6R}ci`EQ3?l z3t4_IIkPuAt!X2L)Z*~2#Q=)io!))yWABBnom95mS#O|%U#B^`D@XE!#!_m>rP?Q> zLC6Uzkb~ui;b@eC1W}PrK|(gKHucWA`>LQ=?4etMZSjN#L<}eghg;lfp^-E;HpJ^K zbo+O2mUQf+R2%yS3Zd*62GWytTR%GN}@QOlDe=;5_!`x2d=x8$W z%b(d;8mV^ZwL}sV;i#}B6XkNzOjp9u459FW@%H(@oPW({P#NWQky!0e=W;6Sk#6Hf zsc%+W?$PIQDLsNd4SGfPPVfjHST4U0Nm-8twux#77jO2?%ZRa-eZ5qOy2V^Xk;}Qb z4dQc71~K?wvrICc(-_l|)b8s%Q&#h_b>Z6;>P0Z{La#Qvyvru>+Tl(wQSfV^qJa@z zQ9z>_iY?kSA7kitpeGv|%tEE|qi~rlEv-ft(Y5dbG*h#=SY1LlUm-6NFb7~X6^H;m zjgWz97%dx;i6*Y#T!9eV8H9VAf^?7%Ac9ChtPC~c7Of^?YN@l+Nwx6?zcK*#OG$vb zUp}a-hdb%e?OX{(L7(RE&YjpRLb{LGjGD?xKD_uv00iH@vQ*pX$I%e~$0)syg|Erp z_eVc&&a6f_zD0ahQNty~syC1GIeU*A0PKQF`{n$-Ylw8)Ouq21r$^!- zC2rBesXDrAKIq%R;iVh$bhviwJpV~ZSPuGt3Gw2YN%#OfN<3m_=Ja!x&a5A{$(T45 zR*=gJ`#*1nvB`KU@>?m6@;X3*`o7TY+%43=Lms0Tu9WZR?C{)%r9^|s2Vg-;1+vPc?I<3TP8|<9mP<(hDJOhmyX#@4x5>fZ{{IaGGGZSXxb~B zdDKD_F-t&4r=o?nz1yNEs5$51i!U&z3{l`h+TK;}&`p1f;{e~WYIgb2vT=S~PTL6ld1^(cDm0s$ z2r@XMls3KqnSzjF<0(rOjgG=Wv&}7In-;e zWTGzX=;3s#UC_VJIGEF&D42z(co{bXP-r#+<6H!l1jgnE@W{x#V`nKw zhkMK2&M~KrriV$mfxhr8`Y#!SG3?M($Ye0QaVxJboBbUd~Krcbc;qISS7W`)T7mXp85qUVUUh zN41$o7a^lvz_#~`euQrSOadP5^Ziu>Ik}M}VwW4LlBe4(e)~6uxK^ZI=x>nxE(28N zapt%(B1SOZy@OF+-;!SK;yw-M|J>m|Ha|Z~?6yF6^gHgteQl_)q=HCWy)kX~Qgw92 z@jmjZ*|s48%`0sp=dwz>q_E+xlV@#K-o2ec*OS^PRl}dugNFaFM;yg`FhVbMWBUSu zc@|Ncqe9GIFbSdxW`VVD-l1h}c+HKdk$7^``xoL#Ui*E3%M~5B>8L>S23NzjEn9x6 z1P!e*Gqd*sGPh}@<-J>3C0(s&gZ&y81i`#Z7tvB7zM=*e-3FEILH3PnR_rMZlmv8u z+cTmfjbx6nfJc7@M58|=5TpNBc08E5E@9O?6{WNFd}z#$`7pjsURUc?jg8M&X^Ye0 zTD8D8+s*Sny6CHVu2}bUNi=eD-swMQXwW&SraTv=p=7eTR$QM-=#*7fT3#KpvA-Dj z^WXbKjzb4Z={IxJC_73h*&@;$v^XTT3`QRX@cRd$wh)XVV$z>u8NCcxLYSZp5v}16 zc1A)PpfUP~p{6kxWbkAmE1DY&xLE)+;|(m--u?ZWbM??Tlw4y};&!UA-_Cz5p5<|V$QjAb*joD|xD0-GjI z&gCZSC2HmVk5pZ>FmB`K6Sd04pUKIqE9p#42a07!BP^CxE56LBw3XAe+GZwdi^ElV z-|fY^bK)wkS7%jHz*mHZ*#=r?l5bcFc}Rt_W&Zl%PC#js?*uVnD1uH|6CkHyg@WJ^ zK?O+3LDHq@^WLX)3Baga1s@i$AS8wd)qhewH>2SUge%>)V{q#K8!(NvAoLk-k)t0U zv4A}P$D)7+GX|>RcnA|@8goMGb80O`zZNjjf(SmA;qSX$QGki&;K6*Zi|g(FHol@9 z`u6q-l?XVdeK*HgNx1-SS&UZ|skD7nXD!YTJB6FZBU83*M#%f91rM=l<*}yo*G8=% z7_*vnLIfTd^Bp>>JH8K&V1jM*<+g8VYiMBIc%=8=%_gIkY%>xzI8fVYcTF(%`~ag? zy*t%MFaC<3(aTvM^Sd*Z!nIlLu`Epof+>|mg7oc;eFjC(PX?wjJ{mUYOXVf_`rJ`I z8rHBG)4GJ_tQr}SnqrwoA$$_U-+|M#SRqmBk)xw5SbBp)Sk0cV2jXD+uSas;hhQLq zb=x)W`j>IyHPv)sd|tZR{oXB?SG^dQ$LmArX)?#8-8yGGr7lSHo$AKIQ`sRNv1p&Q zJ%TJZL<0fGH^OXCcsSzKV5FLHSTyF2=hf5c#--jq1_P*HW@A?5(TWu6Avp)G)k3~pW^9f&oQM%VPdA`vs zUSK;rLYjeuZ<~KRzE9~kN=c83)3@>2m@VwKTl2X*pyixxby7=IPM5$=GwvryJ;l~a z*x7AJlzmrg7xSI4=e#WY>+I^D-{OVm@i=~k-!goI@;)FIz-;+hAD)#tce@= z84AD@_3wd5`DX(L18mb>=m^LvHcdz)4r)cMD=Bc=*a6R%3|>cs4#b)1-#=>fj%Sap zxoOjF9DCGaih^laWpu4UyxT*OdWX$_zgLMqQmDv5PG*RUGa2irvY@9|3Q|+O1w3K< zCY&LP2y@1kIMV}Fe+i?{rvd`uRx&Z>jMMKZX|N%x?%`m)#VYPB#Y#L0*}UnP(jaTU z#-tBy@e7`wJk|H2cOntekRq4ucSrf%(x|z56p8z4^YLB~qZYDC$wjj>@gf&d-LH@1 z3igV1in!&b`C)JsWs6kEtn~`A!QjV7_=>VQANAM$L(D!%1921?*!{!I8Ph1aLM#OY ze4*3PeME=vLhcZO47Q0UCbf3fwP*JA&%^};rJSPR z*?&3ZvhV7t@hY)vQPCo#fjnR2Hddo~aNk=P!{J&sVPb$?jQvLKG#+}Jx7Ykyt0Ts3caH6k8@A!TYi zBlXzI)1PtAQ0@Sw@n4byYruNUb0jJYTQy0e;lf z^u5LsPuQ0z^TxeOwrs^W8Q5WO$Nv`p+H*m8_o}#aAe&AHb)k!(^D1nce~fU~0_*L3 z^o?D~Z%6Wzx`0RYJICj=T1OZxbMNi*^HcU4;cm$4*W?a&hRa*6WG6g&vNK*{iI}N8 zkypSk!D-t9MZ}d>PXwiT_2QbLAaIvi#FD%ocRk1{DNyuCi1W8zz2KztH;9Yu@CWPA zUuUB|6u8gBD;;B(1uvzdpdB2Us%q@%Aq+a-*8I4WvMSx8*FuVPLcGX)xUvr!(qMMR zL$?H81)x+_^tZdHWlmVkI0V273F81&;^|oY{`TByPd8<=fy$OgUf@2Oh+5LBx$Z~|H)l;A+5VfCwMpa26PBd1H1opSo73GTsaf1 zQ7!G6IzOqvO~G2G2T8TIE_%EdE?V`yFa0U~>(`=YgOG51U2>EHN?yJGRc;c@F4;5Z zlE2=0ZqlQlE6bF$eW(&Lw1 zf+LTn4}`EnuMEi9d41d2Um5JXM8czm98Cp+19r9|UT*W3qT5aO%Y#6Ogf zZ%{A!i=AgDK9qp&@-Q({r{xS>XEh&L#MoozCk-xVPtlwa%Al3k^Ci#UT&VGqvpp&& zo!YK_(XYSTvl3^anl7ere11}xXm@9@wK*(=(7kXpLBLH$6(b)J;Ses% zXPoY2K-}n)6C|CHON>95)x;@msd7tfA%3aG-9_BuOK-CK=XjrzP8`m!-Zk{Mh`@5c zc-i0+f5(gFwkvWw6)gvnhQP7Yc$;oee|MKTe}mUmlz5GRLj*x6$oxiNXM)OJKTM=K zU=#MX$gL0ol@FvZd3pswJ$LHe`}%cZL_e6X(66{lUlMsyd>HF2Fbjq4e(R(8?ksYi z8oB-<(7NV(8m%A!s!eAC>kl(jcBf%Z50W<_?ZByhvgg_7$^7r{<^GO5YNb8EqCJCT zEI(wr@Kc5gpI_N|vXtC+Z<%vq%&u_QUGt|5o;<;REsaN+1&*{R?QcVC6Q{vP6Z;6L z2r{1V41~42_vL;+_RR;!d4B8{myw`@#-2nqknvjLfkR(GAT-|O_UYT}3|?rTC*)z8 zY9ISR0;Z zp<~il`}_@?>{CF?dW{RKw{BB@tQqo(w*2#7B-r;d7!%OD>3^X+*xY+vVb+1Ztr>W5F?$--v z`yuqQLv&StS!B-xOd0>_yfA9}N~|^VKd@eJA`ULKnuJ7)zsB`s+6M)>hGB$rDVm|LG8h z-2a#JzsDeXiP|nFxS3DXERW0z9f$~H>2^C+*XOC;n!*%0+Cgxygs4@y;pUnR2K0IG z-b_b(EOKnQlHP2QxpAUt{wpJD`k-D;f&h|lZkh#T*^a^DNq|(GPLa06&i`Guo)44uoh95q2rnnZ5zP3N{71Db>>^nIs$yHW zf`NS3reU!|XX`$xUXjwEwSRO%0AeJ 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 dEX* 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ųoe#rFgn$82BZrMrgi-X<(dz<;@VZv z3cc{i{C022Z>jxw-bNa)z;<8R8mG@vo;t`dW^b$qLZh}JrJ+9D!NJ_3K-X|+VF4O+ z5)Mk3v#~^{tyfPLPP>|!Wy^LUAiCz|joAvu0B23}*qFisR;Q3q`aF7FhKEP(v7;3q zcT$9h=Wk2gB12&>Tw$TRCl9zk-h13|{BHDMi}ZFgT90hf(l(zuv(W^{MT6$vDsl!5 z9;&pQMM+k+Jhjq*r8?&1LEbDt@4<39%6_>1ddW+olr@tZh~z(Q%jrPELjsRT!-FRw zfs8IKk6gc?@Nd@YM?pCVO7Za-TaGz)OdsaRFy-j9l$85S=8)4)5)(p#g8F+X!`11o zLQl6*=~z2gP~%aW(~aJv_666p@?+n@C&^!Oa!qEh*ZO5Q@f`HyLDpoL1MrwglVSTGu< z=NB6;&Zus0D<}3O*=!hW8Jn-%+$3fVTv0MYPlja~mw#(kjCCuA-diHV4Q)SS&)-2Rr=esH)CL4ynp0sUwZ%>l?+F z_4=WqR2b?YSOA$Lso)QD>p0j30x1IP_d7V7uJxy5D6~c8Ps2U zxQfVPfxkg^Iu>*Yzku2EgBbg(wi`(dPZApDHdsl7{ypu21S`n`movQ3_%lLmDoW?; z`1$BB6oTxT!y_UEpz;uU%8C^W!PFE)`~$x|pKfJ{kAhLp`!qAnyv`WPei-!EOIuu) zNQma!N|1QbOC)$OA7*ADJ{7zq@JO@*L?kg$^~%W9{5EBBD>!RBB=32aqKVttLb16# zYohsNXNSxkmvgMmUvfqwB{%Rd%?L(i=MF=Ix%-JK`7hNN*dHjNO483)T5)@NxXv23 zGSQI;7t0cK+n%X3NKq`RMx(YgUn8<;uL}C_I`J;j7XNSejcom| + + + + + + + +cluster_backend + +backend + + +cluster_hello_world + +hello-world + + + +backend/backend-app[Deployment] + +backend-app[Deployment] + + + +0.0.0.0-255.255.255.255 + +0.0.0.0-255.255.255.255 + + + +backend/backend-app[Deployment]->0.0.0.0-255.255.255.255 + + +All Connections + + + +entire-cluster + +entire-cluster + + + +backend/backend-app[Deployment]->entire-cluster + + +All Connections + + + +pod with {app=backend-new}_in_backend + +pod with {app=backend-new} + + + +hello-world/workload-a[Deployment] + +workload-a[Deployment] + + + +pod with {app=backend-new}_in_backend->hello-world/workload-a[Deployment] + + +TCP 8050 + + + +hello-world/workload-a[Deployment]->backend/backend-app[Deployment] + + +All Connections + + + +hello-world/workload-a[Deployment]->entire-cluster + + +All Connections + + + +0.0.0.0-255.255.255.255->backend/backend-app[Deployment] + + +All Connections + + + +entire-cluster->backend/backend-app[Deployment] + + +All Connections + + + diff --git a/test_outputs/connlist/exposure_test_conn_to_new_pod_in_an_existing_ns_connlist_output.txt b/test_outputs/connlist/exposure_test_conn_to_new_pod_in_an_existing_ns_connlist_output.txt new file mode 100644 index 00000000..0187cf17 --- /dev/null +++ b/test_outputs/connlist/exposure_test_conn_to_new_pod_in_an_existing_ns_connlist_output.txt @@ -0,0 +1,18 @@ +0.0.0.0-255.255.255.255 => backend/backend-app[Deployment] : All Connections +backend/backend-app[Deployment] => 0.0.0.0-255.255.255.255 : All Connections +hello-world/workload-a[Deployment] => backend/backend-app[Deployment] : All Connections + +Exposure Analysis Result: +Egress Exposure: +backend/backend-app[Deployment] => 0.0.0.0-255.255.255.255 : All Connections +backend/backend-app[Deployment] => entire-cluster : All Connections +hello-world/workload-a[Deployment] => entire-cluster : All Connections + +Ingress Exposure: +backend/backend-app[Deployment] <= 0.0.0.0-255.255.255.255 : All Connections +backend/backend-app[Deployment] <= entire-cluster : All Connections +hello-world/workload-a[Deployment] <= backend/[pod with {app=backend-new}] : TCP 8050 + +Workloads not protected by network policies: +backend/backend-app[Deployment] is not protected on Egress +backend/backend-app[Deployment] is not protected on Ingress diff --git a/tests/test_conn_to_all_pods_in_an_existing_ns/backend.yaml b/tests/test_conn_to_all_pods_in_an_existing_ns/backend.yaml new file mode 100644 index 00000000..82209327 --- /dev/null +++ b/tests/test_conn_to_all_pods_in_an_existing_ns/backend.yaml @@ -0,0 +1,40 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: backend-app + namespace: backend +spec: + selector: + matchLabels: + app: backendservice + template: + metadata: + labels: + app: backendservice + spec: + containers: + - name: server + image: backendservice + ports: + - containerPort: 9090 + readinessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 9090 + livenessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 9090 + env: + - name: PORT + value: "9090" + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi diff --git a/tests/test_conn_to_all_pods_in_an_existing_ns/netpol.yaml b/tests/test_conn_to_all_pods_in_an_existing_ns/netpol.yaml new file mode 100644 index 00000000..7b2e3e86 --- /dev/null +++ b/tests/test_conn_to_all_pods_in_an_existing_ns/netpol.yaml @@ -0,0 +1,25 @@ +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: allow-ingress-to-unknown-ns + namespace: hello-world +spec: + podSelector: + matchLabels: + app: a-app + policyTypes: + - Ingress + - Egress + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: backend + podSelector: {} + ports: + - port: 8050 + protocol: TCP + egress: + - to: + - namespaceSelector: {} + podSelector: {} \ No newline at end of file diff --git a/tests/test_conn_to_all_pods_in_an_existing_ns/ns_and_deployments.yaml b/tests/test_conn_to_all_pods_in_an_existing_ns/ns_and_deployments.yaml new file mode 100644 index 00000000..3fc694b8 --- /dev/null +++ b/tests/test_conn_to_all_pods_in_an_existing_ns/ns_and_deployments.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: hello-world +spec: {} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: workload-a + namespace: hello-world + labels: + app: a-app +spec: + selector: + matchLabels: + app: a-app + template: + metadata: + labels: + app: a-app + spec: + containers: + - name: hello-world + image: quay.io/shfa/hello-world:latest + ports: + - containerPort: 8000 # containerport1 + - containerPort: 8050 # containerport2 + - containerPort: 8090 # containerport3 +--- diff --git a/tests/test_conn_to_new_pod_in_an_existing_ns/backend.yaml b/tests/test_conn_to_new_pod_in_an_existing_ns/backend.yaml new file mode 100644 index 00000000..82209327 --- /dev/null +++ b/tests/test_conn_to_new_pod_in_an_existing_ns/backend.yaml @@ -0,0 +1,40 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: backend-app + namespace: backend +spec: + selector: + matchLabels: + app: backendservice + template: + metadata: + labels: + app: backendservice + spec: + containers: + - name: server + image: backendservice + ports: + - containerPort: 9090 + readinessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 9090 + livenessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 9090 + env: + - name: PORT + value: "9090" + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi diff --git a/tests/test_conn_to_new_pod_in_an_existing_ns/netpol.yaml b/tests/test_conn_to_new_pod_in_an_existing_ns/netpol.yaml new file mode 100644 index 00000000..c9941e9b --- /dev/null +++ b/tests/test_conn_to_new_pod_in_an_existing_ns/netpol.yaml @@ -0,0 +1,27 @@ +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: allow-ingress-to-unknown-ns + namespace: hello-world +spec: + podSelector: + matchLabels: + app: a-app + policyTypes: + - Ingress + - Egress + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: backend + podSelector: + matchLabels: + app: backend-new + ports: + - port: 8050 + protocol: TCP + egress: + - to: + - namespaceSelector: {} + podSelector: {} \ No newline at end of file diff --git a/tests/test_conn_to_new_pod_in_an_existing_ns/ns_and_deployments.yaml b/tests/test_conn_to_new_pod_in_an_existing_ns/ns_and_deployments.yaml new file mode 100644 index 00000000..3fc694b8 --- /dev/null +++ b/tests/test_conn_to_new_pod_in_an_existing_ns/ns_and_deployments.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: hello-world +spec: {} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: workload-a + namespace: hello-world + labels: + app: a-app +spec: + selector: + matchLabels: + app: a-app + template: + metadata: + labels: + app: a-app + spec: + containers: + - name: hello-world + image: quay.io/shfa/hello-world:latest + ports: + - containerPort: 8000 # containerport1 + - containerPort: 8050 # containerport2 + - containerPort: 8090 # containerport3 +--- From e134fa15783f43d4e391623925c7ebc87cafe7ed Mon Sep 17 00:00:00 2001 From: shireenf-ibm <82180114+shireenf-ibm@users.noreply.github.com> Date: Thu, 16 May 2024 12:28:10 +0300 Subject: [PATCH 04/12] Update pkg/netpol/eval/exposure.go Co-authored-by: Adi Sosnovich <82078442+adisos@users.noreply.github.com> --- pkg/netpol/eval/exposure.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/netpol/eval/exposure.go b/pkg/netpol/eval/exposure.go index 78cce765..5b1e2b46 100644 --- a/pkg/netpol/eval/exposure.go +++ b/pkg/netpol/eval/exposure.go @@ -75,7 +75,9 @@ func (pe *PolicyEngine) refineRepresentativePeersMatchingLabels(realPodLabels, r for key, peer := range pe.representativePeersMap { potentialPodSelector := labels.SelectorFromSet(labels.Set(peer.Pod.Labels)) potentialNsSelector := labels.SelectorFromSet(labels.Set(peer.PotentialNamespaceLabels)) - if potentialNsSelector.Empty() { // representative peer that matches any-namespace, will not be removed + if potentialNsSelector.Empty() { + // empty --representative peer that matches any-namespace, thus will not be removed + // note that if the policy had nil namespaceSelector, it would be converted to the namespace of the policy continue } // remove representative peer matching both realPodLabels and realNsLabels. From 722964f75258742f0da37c3ff1987a6a788862d5 Mon Sep 17 00:00:00 2001 From: shireenf-ibm Date: Thu, 16 May 2024 13:36:48 +0300 Subject: [PATCH 05/12] don't refine rep. peers matching any pod in a namespace + changing some tests to keep initial purpose+updating results of existing tests --- pkg/netpol/eval/exposure.go | 15 ++- ...pods_in_an_existing_ns_connlist_output.dot | 2 + ..._in_an_existing_ns_connlist_output.dot.png | Bin 39303 -> 49282 bytes ..._in_an_existing_ns_connlist_output.dot.svg | 107 ++++++++++-------- ...pods_in_an_existing_ns_connlist_output.txt | 1 + .../netpol.yaml | 3 + .../netpol.yaml | 3 + tests/test_only_matched_rules/netpol.yaml | 6 + 8 files changed, 85 insertions(+), 52 deletions(-) diff --git a/pkg/netpol/eval/exposure.go b/pkg/netpol/eval/exposure.go index 5b1e2b46..59c263a5 100644 --- a/pkg/netpol/eval/exposure.go +++ b/pkg/netpol/eval/exposure.go @@ -75,14 +75,19 @@ func (pe *PolicyEngine) refineRepresentativePeersMatchingLabels(realPodLabels, r for key, peer := range pe.representativePeersMap { potentialPodSelector := labels.SelectorFromSet(labels.Set(peer.Pod.Labels)) potentialNsSelector := labels.SelectorFromSet(labels.Set(peer.PotentialNamespaceLabels)) - if potentialNsSelector.Empty() { - // empty --representative peer that matches any-namespace, thus will not be removed - // note that if the policy had nil namespaceSelector, it would be converted to the namespace of the policy + if potentialNsSelector.Empty() { + // empty --representative peer that matches any-namespace, thus will not be removed + // note that if the policy had nil namespaceSelector, it would be converted to the namespace of the policy + continue + } + if potentialPodSelector.Empty() { + // empty/nil podSelector means representative peer that matches any-pod in the representative namespace, + // thus will not be removed + // note that there is no representative peer with both empty namespace and pod selector; that case was handled + // in the general conns compute and won't get here. continue } // remove representative peer matching both realPodLabels and realNsLabels. - // a representative peer that matches any-pod in a specific namespace, and real Labels are for a specific pod in same namespace, - // the representative peer will be removed (we have at least one real pod in that namespace) if potentialPodSelector.Matches(labels.Set(realPodLabels)) && potentialNsSelector.Matches(labels.Set(realNsLabels)) { keysToDelete = append(keysToDelete, key) } diff --git a/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot index 070b7ca5..3fc76e6a 100644 --- a/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot +++ b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot @@ -2,6 +2,7 @@ digraph { subgraph "cluster_backend" { color="black" fontcolor="black" + "all pods_in_backend" [label="all pods" color="red2" fontcolor="red2"] "backend/backend-app[Deployment]" [label="backend-app[Deployment]" color="blue" fontcolor="blue"] label="backend" } @@ -14,6 +15,7 @@ digraph { "0.0.0.0-255.255.255.255" [label="0.0.0.0-255.255.255.255" color="red2" fontcolor="red2"] "entire-cluster" [label="entire-cluster" color="red2" fontcolor="red2" shape=diamond] "0.0.0.0-255.255.255.255" -> "backend/backend-app[Deployment]" [label="All Connections" color="gold2" fontcolor="darkgreen"] + "all pods_in_backend" -> "hello-world/workload-a[Deployment]" [label="TCP 8050" color="gold2" fontcolor="darkgreen" weight=1] "backend/backend-app[Deployment]" -> "0.0.0.0-255.255.255.255" [label="All Connections" color="gold2" fontcolor="darkgreen"] "backend/backend-app[Deployment]" -> "entire-cluster" [label="All Connections" color="gold2" fontcolor="darkgreen" weight=0.5] "backend/backend-app[Deployment]" -> "hello-world/workload-a[Deployment]" [label="TCP 8050" color="gold2" fontcolor="darkgreen"] diff --git a/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot.png b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.dot.png index a6827e79c44f61abce6e4cda49f2197a23ca8ee0..77e1833bd0eb4dadc9b776d85c17d125a7be637a 100644 GIT binary patch literal 49282 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 literal 39303 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�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�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 - + - + cluster_backend - -backend + +backend cluster_hello_world - -hello-world + +hello-world - + -backend/backend-app[Deployment] - -backend-app[Deployment] +all pods_in_backend + +all pods - + hello-world/workload-a[Deployment] - -workload-a[Deployment] + +workload-a[Deployment] + + + +all pods_in_backend->hello-world/workload-a[Deployment] + + +TCP 8050 + + + +backend/backend-app[Deployment] + +backend-app[Deployment] - + backend/backend-app[Deployment]->hello-world/workload-a[Deployment] - - -TCP 8050 + + +TCP 8050 - + 0.0.0.0-255.255.255.255 - -0.0.0.0-255.255.255.255 + +0.0.0.0-255.255.255.255 - + backend/backend-app[Deployment]->0.0.0.0-255.255.255.255 - - -All Connections + + +All Connections - + entire-cluster - -entire-cluster + +entire-cluster - + backend/backend-app[Deployment]->entire-cluster - - -All Connections + + +All Connections - + hello-world/workload-a[Deployment]->backend/backend-app[Deployment] - - -All Connections + + +All Connections - + hello-world/workload-a[Deployment]->entire-cluster - - -All Connections + + +All Connections 0.0.0.0-255.255.255.255->backend/backend-app[Deployment] - - -All Connections + + +All Connections - + entire-cluster->backend/backend-app[Deployment] - - -All Connections + + +All Connections diff --git a/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.txt b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.txt index 153efa65..3b1ca9dd 100644 --- a/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.txt +++ b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_connlist_output.txt @@ -12,6 +12,7 @@ hello-world/workload-a[Deployment] => entire-cluster : All Connections Ingress Exposure: backend/backend-app[Deployment] <= 0.0.0.0-255.255.255.255 : All Connections backend/backend-app[Deployment] <= entire-cluster : All Connections +hello-world/workload-a[Deployment] <= backend/[all pods] : TCP 8050 Workloads not protected by network policies: backend/backend-app[Deployment] is not protected on Egress diff --git a/tests/test_matched_and_unmatched_rules/netpol.yaml b/tests/test_matched_and_unmatched_rules/netpol.yaml index af82e507..84ff8c6d 100644 --- a/tests/test_matched_and_unmatched_rules/netpol.yaml +++ b/tests/test_matched_and_unmatched_rules/netpol.yaml @@ -12,6 +12,9 @@ spec: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: hello-world + podSelector: + matchLabels: + app: b-app - from: - namespaceSelector: matchExpressions: diff --git a/tests/test_new_namespace_conn_and_entire_cluster/netpol.yaml b/tests/test_new_namespace_conn_and_entire_cluster/netpol.yaml index 998347d3..e943b025 100644 --- a/tests/test_new_namespace_conn_and_entire_cluster/netpol.yaml +++ b/tests/test_new_namespace_conn_and_entire_cluster/netpol.yaml @@ -12,6 +12,9 @@ spec: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: hello-world + podSelector: + matchLabels: + app: b-app - from: - namespaceSelector: matchExpressions: diff --git a/tests/test_only_matched_rules/netpol.yaml b/tests/test_only_matched_rules/netpol.yaml index 4a71abea..224a1100 100644 --- a/tests/test_only_matched_rules/netpol.yaml +++ b/tests/test_only_matched_rules/netpol.yaml @@ -12,8 +12,14 @@ spec: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: hello-world + podSelector: + matchLabels: + app: b-app egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: hello-world + podSelector: + matchLabels: + app: b-app From e4276e419855e4678e7f94e1bea32bc29e648d26 Mon Sep 17 00:00:00 2001 From: shireenf-ibm Date: Thu, 16 May 2024 13:50:00 +0300 Subject: [PATCH 06/12] adding same test with nil podSelector instead of empty one --- pkg/netpol/connlist/connlist_test.go | 5 + ..._with_ns_selector_only_connlist_output.dot | 25 ++++ ...h_ns_selector_only_connlist_output.dot.png | Bin 0 -> 49282 bytes ...h_ns_selector_only_connlist_output.dot.svg | 108 ++++++++++++++++++ ..._with_ns_selector_only_connlist_output.txt | 19 +++ .../backend.yaml | 40 +++++++ .../netpol.yaml | 24 ++++ .../ns_and_deployments.yaml | 31 +++++ 8 files changed, 252 insertions(+) create mode 100644 test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.dot create mode 100644 test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.dot.png create mode 100644 test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.dot.svg create mode 100644 test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.txt create mode 100644 tests/test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only/backend.yaml create mode 100644 tests/test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only/netpol.yaml create mode 100644 tests/test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only/ns_and_deployments.yaml diff --git a/pkg/netpol/connlist/connlist_test.go b/pkg/netpol/connlist/connlist_test.go index 3a0934dc..50c0114c 100644 --- a/pkg/netpol/connlist/connlist_test.go +++ b/pkg/netpol/connlist/connlist_test.go @@ -935,4 +935,9 @@ var goodPathTests = []struct { exposureAnalysis: true, outputFormats: ExposureValidFormats, }, + { + testDirName: "test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only", + exposureAnalysis: true, + outputFormats: ExposureValidFormats, + }, } diff --git a/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.dot b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.dot new file mode 100644 index 00000000..3fc76e6a --- /dev/null +++ b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.dot @@ -0,0 +1,25 @@ +digraph { + subgraph "cluster_backend" { + color="black" + fontcolor="black" + "all pods_in_backend" [label="all pods" color="red2" fontcolor="red2"] + "backend/backend-app[Deployment]" [label="backend-app[Deployment]" color="blue" fontcolor="blue"] + label="backend" + } + subgraph "cluster_hello_world" { + color="black" + fontcolor="black" + "hello-world/workload-a[Deployment]" [label="workload-a[Deployment]" color="blue" fontcolor="blue"] + label="hello-world" + } + "0.0.0.0-255.255.255.255" [label="0.0.0.0-255.255.255.255" color="red2" fontcolor="red2"] + "entire-cluster" [label="entire-cluster" color="red2" fontcolor="red2" shape=diamond] + "0.0.0.0-255.255.255.255" -> "backend/backend-app[Deployment]" [label="All Connections" color="gold2" fontcolor="darkgreen"] + "all pods_in_backend" -> "hello-world/workload-a[Deployment]" [label="TCP 8050" color="gold2" fontcolor="darkgreen" weight=1] + "backend/backend-app[Deployment]" -> "0.0.0.0-255.255.255.255" [label="All Connections" color="gold2" fontcolor="darkgreen"] + "backend/backend-app[Deployment]" -> "entire-cluster" [label="All Connections" color="gold2" fontcolor="darkgreen" weight=0.5] + "backend/backend-app[Deployment]" -> "hello-world/workload-a[Deployment]" [label="TCP 8050" color="gold2" fontcolor="darkgreen"] + "entire-cluster" -> "backend/backend-app[Deployment]" [label="All Connections" color="gold2" fontcolor="darkgreen" weight=1] + "hello-world/workload-a[Deployment]" -> "backend/backend-app[Deployment]" [label="All Connections" color="gold2" fontcolor="darkgreen"] + "hello-world/workload-a[Deployment]" -> "entire-cluster" [label="All Connections" color="gold2" fontcolor="darkgreen" weight=0.5] +} \ No newline at end of file diff --git a/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.dot.png b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.dot.png new file mode 100644 index 0000000000000000000000000000000000000000..77e1833bd0eb4dadc9b776d85c17d125a7be637a GIT binary patch literal 49282 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 literal 0 HcmV?d00001 diff --git a/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.dot.svg b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.dot.svg new file mode 100644 index 00000000..fe622eff --- /dev/null +++ b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.dot.svg @@ -0,0 +1,108 @@ + + + + + + + + +cluster_backend + +backend + + +cluster_hello_world + +hello-world + + + +all pods_in_backend + +all pods + + + +hello-world/workload-a[Deployment] + +workload-a[Deployment] + + + +all pods_in_backend->hello-world/workload-a[Deployment] + + +TCP 8050 + + + +backend/backend-app[Deployment] + +backend-app[Deployment] + + + +backend/backend-app[Deployment]->hello-world/workload-a[Deployment] + + +TCP 8050 + + + +0.0.0.0-255.255.255.255 + +0.0.0.0-255.255.255.255 + + + +backend/backend-app[Deployment]->0.0.0.0-255.255.255.255 + + +All Connections + + + +entire-cluster + +entire-cluster + + + +backend/backend-app[Deployment]->entire-cluster + + +All Connections + + + +hello-world/workload-a[Deployment]->backend/backend-app[Deployment] + + +All Connections + + + +hello-world/workload-a[Deployment]->entire-cluster + + +All Connections + + + +0.0.0.0-255.255.255.255->backend/backend-app[Deployment] + + +All Connections + + + +entire-cluster->backend/backend-app[Deployment] + + +All Connections + + + diff --git a/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.txt b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.txt new file mode 100644 index 00000000..3b1ca9dd --- /dev/null +++ b/test_outputs/connlist/exposure_test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only_connlist_output.txt @@ -0,0 +1,19 @@ +0.0.0.0-255.255.255.255 => backend/backend-app[Deployment] : All Connections +backend/backend-app[Deployment] => 0.0.0.0-255.255.255.255 : All Connections +backend/backend-app[Deployment] => hello-world/workload-a[Deployment] : TCP 8050 +hello-world/workload-a[Deployment] => backend/backend-app[Deployment] : All Connections + +Exposure Analysis Result: +Egress Exposure: +backend/backend-app[Deployment] => 0.0.0.0-255.255.255.255 : All Connections +backend/backend-app[Deployment] => entire-cluster : All Connections +hello-world/workload-a[Deployment] => entire-cluster : All Connections + +Ingress Exposure: +backend/backend-app[Deployment] <= 0.0.0.0-255.255.255.255 : All Connections +backend/backend-app[Deployment] <= entire-cluster : All Connections +hello-world/workload-a[Deployment] <= backend/[all pods] : TCP 8050 + +Workloads not protected by network policies: +backend/backend-app[Deployment] is not protected on Egress +backend/backend-app[Deployment] is not protected on Ingress diff --git a/tests/test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only/backend.yaml b/tests/test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only/backend.yaml new file mode 100644 index 00000000..82209327 --- /dev/null +++ b/tests/test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only/backend.yaml @@ -0,0 +1,40 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: backend-app + namespace: backend +spec: + selector: + matchLabels: + app: backendservice + template: + metadata: + labels: + app: backendservice + spec: + containers: + - name: server + image: backendservice + ports: + - containerPort: 9090 + readinessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 9090 + livenessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 9090 + env: + - name: PORT + value: "9090" + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi diff --git a/tests/test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only/netpol.yaml b/tests/test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only/netpol.yaml new file mode 100644 index 00000000..35b7d588 --- /dev/null +++ b/tests/test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only/netpol.yaml @@ -0,0 +1,24 @@ +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: allow-ingress-to-unknown-ns + namespace: hello-world +spec: + podSelector: + matchLabels: + app: a-app + policyTypes: + - Ingress + - Egress + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: backend + ports: + - port: 8050 + protocol: TCP + egress: + - to: + - namespaceSelector: {} + podSelector: {} \ No newline at end of file diff --git a/tests/test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only/ns_and_deployments.yaml b/tests/test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only/ns_and_deployments.yaml new file mode 100644 index 00000000..3fc694b8 --- /dev/null +++ b/tests/test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only/ns_and_deployments.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: hello-world +spec: {} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: workload-a + namespace: hello-world + labels: + app: a-app +spec: + selector: + matchLabels: + app: a-app + template: + metadata: + labels: + app: a-app + spec: + containers: + - name: hello-world + image: quay.io/shfa/hello-world:latest + ports: + - containerPort: 8000 # containerport1 + - containerPort: 8050 # containerport2 + - containerPort: 8090 # containerport3 +--- From b7c498a4732e2aac25b7e50251863859a0cb17a5 Mon Sep 17 00:00:00 2001 From: shireenf-ibm Date: Thu, 16 May 2024 14:23:14 +0300 Subject: [PATCH 07/12] adding test with inaccurate output --- pkg/netpol/connlist/connlist_test.go | 13 ++++ ...routes_and_ingress_connlist_output.dot.svg | 22 +++--- ...ce_except_specific_pod_connlist_output.dot | 20 +++++ ...xcept_specific_pod_connlist_output.dot.png | Bin 0 -> 30725 bytes ...xcept_specific_pod_connlist_output.dot.svg | 73 ++++++++++++++++++ ...ce_except_specific_pod_connlist_output.txt | 11 +++ .../backend.yaml | 40 ++++++++++ .../backend_netpol.yaml | 15 ++++ .../hello_world_netpol.yaml | 20 +++++ .../ns_and_deployments.yaml | 31 ++++++++ 10 files changed, 234 insertions(+), 11 deletions(-) create mode 100644 test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.dot create mode 100644 test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.dot.png create mode 100644 test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.dot.svg create mode 100644 test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.txt create mode 100644 tests/test_exposure_to_namespace_except_specific_pod/backend.yaml create mode 100644 tests/test_exposure_to_namespace_except_specific_pod/backend_netpol.yaml create mode 100644 tests/test_exposure_to_namespace_except_specific_pod/hello_world_netpol.yaml create mode 100644 tests/test_exposure_to_namespace_except_specific_pod/ns_and_deployments.yaml diff --git a/pkg/netpol/connlist/connlist_test.go b/pkg/netpol/connlist/connlist_test.go index 50c0114c..3a81857d 100644 --- a/pkg/netpol/connlist/connlist_test.go +++ b/pkg/netpol/connlist/connlist_test.go @@ -940,4 +940,17 @@ var goodPathTests = []struct { exposureAnalysis: true, outputFormats: ExposureValidFormats, }, + { + // following test resources : contains two pods in different namespaces, and two policies, one for each namespace + // first policy captures: hello-world/workload-a and exposes it on Ingress to all pods in backend namespace + // second policy captures: backend/backend-app and denies all egress from it + // so as result hello-world/workload-a is actually exposed to all backend pods except for backend-app + // @TODO: following exposure line in output : + // `hello-world/workload-a[Deployment] <= backend/[all pods] : TCP 8050` + // should be replaced with : + // `hello-world/workload-a[Deployment] <= backend/[all pods except backend/backend-app] : TCP 8050` + testDirName: "test_exposure_to_namespace_except_specific_pod", + exposureAnalysis: true, + outputFormats: ExposureValidFormats, + }, } diff --git a/test_outputs/connlist/demo_app_with_routes_and_ingress_connlist_output.dot.svg b/test_outputs/connlist/demo_app_with_routes_and_ingress_connlist_output.dot.svg index 1aaa9161..692eb64e 100644 --- a/test_outputs/connlist/demo_app_with_routes_and_ingress_connlist_output.dot.svg +++ b/test_outputs/connlist/demo_app_with_routes_and_ingress_connlist_output.dot.svg @@ -8,16 +8,16 @@ viewBox="0.00 0.00 885.00 262.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - -cluster_helloworld - -helloworld - cluster_routeworld routeworld + +cluster_helloworld + +helloworld + cluster_ingressworld @@ -51,9 +51,9 @@ helloworld/hello-world[Deployment]->routeworld/route-world[Deployment] - - -All Connections + + +All Connections @@ -92,9 +92,9 @@ routeworld/route-world[Deployment]->helloworld/hello-world[Deployment] - - -All Connections + + +All Connections diff --git a/test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.dot b/test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.dot new file mode 100644 index 00000000..cbe1157c --- /dev/null +++ b/test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.dot @@ -0,0 +1,20 @@ +digraph { + subgraph "cluster_backend" { + color="black" + fontcolor="black" + "all pods_in_backend" [label="all pods" color="red2" fontcolor="red2"] + "backend/backend-app[Deployment]" [label="backend-app[Deployment]" color="blue" fontcolor="blue"] + label="backend" + } + subgraph "cluster_hello_world" { + color="black" + fontcolor="black" + "hello-world/workload-a[Deployment]" [label="workload-a[Deployment]" color="blue" fontcolor="blue"] + label="hello-world" + } + "0.0.0.0-255.255.255.255" [label="0.0.0.0-255.255.255.255" color="red2" fontcolor="red2"] + "entire-cluster" [label="entire-cluster" color="red2" fontcolor="red2" shape=diamond] + "0.0.0.0-255.255.255.255" -> "backend/backend-app[Deployment]" [label="All Connections" color="gold2" fontcolor="darkgreen"] + "all pods_in_backend" -> "hello-world/workload-a[Deployment]" [label="TCP 8050" color="gold2" fontcolor="darkgreen" weight=1] + "entire-cluster" -> "backend/backend-app[Deployment]" [label="All Connections" color="gold2" fontcolor="darkgreen" weight=1] +} \ No newline at end of file diff --git a/test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.dot.png b/test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.dot.png new file mode 100644 index 0000000000000000000000000000000000000000..fde76eca90570be4410cbfae30fb218b30c39c4c GIT binary patch literal 30725 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 HW}p5C)Qo0g literal 0 HcmV?d00001 diff --git a/test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.dot.svg b/test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.dot.svg new file mode 100644 index 00000000..83f6fef9 --- /dev/null +++ b/test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.dot.svg @@ -0,0 +1,73 @@ + + + + + + + + +cluster_backend + +backend + + +cluster_hello_world + +hello-world + + + +all pods_in_backend + +all pods + + + +hello-world/workload-a[Deployment] + +workload-a[Deployment] + + + +all pods_in_backend->hello-world/workload-a[Deployment] + + +TCP 8050 + + + +backend/backend-app[Deployment] + +backend-app[Deployment] + + + +0.0.0.0-255.255.255.255 + +0.0.0.0-255.255.255.255 + + + +0.0.0.0-255.255.255.255->backend/backend-app[Deployment] + + +All Connections + + + +entire-cluster + +entire-cluster + + + +entire-cluster->backend/backend-app[Deployment] + + +All Connections + + + diff --git a/test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.txt b/test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.txt new file mode 100644 index 00000000..fb00eb6c --- /dev/null +++ b/test_outputs/connlist/exposure_test_exposure_to_namespace_except_specific_pod_connlist_output.txt @@ -0,0 +1,11 @@ +0.0.0.0-255.255.255.255 => backend/backend-app[Deployment] : All Connections + +Exposure Analysis Result: + +Ingress Exposure: +backend/backend-app[Deployment] <= 0.0.0.0-255.255.255.255 : All Connections +backend/backend-app[Deployment] <= entire-cluster : All Connections +hello-world/workload-a[Deployment] <= backend/[all pods] : TCP 8050 + +Workloads not protected by network policies: +backend/backend-app[Deployment] is not protected on Ingress diff --git a/tests/test_exposure_to_namespace_except_specific_pod/backend.yaml b/tests/test_exposure_to_namespace_except_specific_pod/backend.yaml new file mode 100644 index 00000000..5f42d362 --- /dev/null +++ b/tests/test_exposure_to_namespace_except_specific_pod/backend.yaml @@ -0,0 +1,40 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: backend-app + namespace: backend +spec: + selector: + matchLabels: + app: backend-app + template: + metadata: + labels: + app: backend-app + spec: + containers: + - name: server + image: backend-app + ports: + - containerPort: 9090 + readinessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 9090 + livenessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 9090 + env: + - name: PORT + value: "9090" + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi diff --git a/tests/test_exposure_to_namespace_except_specific_pod/backend_netpol.yaml b/tests/test_exposure_to_namespace_except_specific_pod/backend_netpol.yaml new file mode 100644 index 00000000..7712b319 --- /dev/null +++ b/tests/test_exposure_to_namespace_except_specific_pod/backend_netpol.yaml @@ -0,0 +1,15 @@ +# this policy denies any egress from backend/backend-app +# however hello_world_netpol.yaml allows ingress to hello-world/workload-a from all pods in backend +# so the result we should see is that hello-world/workload-a is exposed on Ingress to backend/[all pods except backend-app] + +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: deny-egress-from-backend-app + namespace: backend +spec: + podSelector: + matchLabels: + app: backend-app + policyTypes: + - Egress diff --git a/tests/test_exposure_to_namespace_except_specific_pod/hello_world_netpol.yaml b/tests/test_exposure_to_namespace_except_specific_pod/hello_world_netpol.yaml new file mode 100644 index 00000000..6a20dfb5 --- /dev/null +++ b/tests/test_exposure_to_namespace_except_specific_pod/hello_world_netpol.yaml @@ -0,0 +1,20 @@ +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: allow-ingress-to-backend-ns + namespace: hello-world +spec: + podSelector: + matchLabels: + app: a-app + policyTypes: + - Ingress + - Egress + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: backend + ports: + - port: 8050 + protocol: TCP diff --git a/tests/test_exposure_to_namespace_except_specific_pod/ns_and_deployments.yaml b/tests/test_exposure_to_namespace_except_specific_pod/ns_and_deployments.yaml new file mode 100644 index 00000000..3fc694b8 --- /dev/null +++ b/tests/test_exposure_to_namespace_except_specific_pod/ns_and_deployments.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: hello-world +spec: {} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: workload-a + namespace: hello-world + labels: + app: a-app +spec: + selector: + matchLabels: + app: a-app + template: + metadata: + labels: + app: a-app + spec: + containers: + - name: hello-world + image: quay.io/shfa/hello-world:latest + ports: + - containerPort: 8000 # containerport1 + - containerPort: 8050 # containerport2 + - containerPort: 8090 # containerport3 +--- From 124a4f60e4dd21331ba2f4fbfa0723bba5087e05 Mon Sep 17 00:00:00 2001 From: shireenf-ibm Date: Mon, 20 May 2024 09:15:47 +0300 Subject: [PATCH 08/12] fixing comment syntax --- pkg/netpol/connlist/connlist_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/netpol/connlist/connlist_test.go b/pkg/netpol/connlist/connlist_test.go index 3a81857d..3f05d1ff 100644 --- a/pkg/netpol/connlist/connlist_test.go +++ b/pkg/netpol/connlist/connlist_test.go @@ -948,7 +948,7 @@ var goodPathTests = []struct { // @TODO: following exposure line in output : // `hello-world/workload-a[Deployment] <= backend/[all pods] : TCP 8050` // should be replaced with : - // `hello-world/workload-a[Deployment] <= backend/[all pods except backend/backend-app] : TCP 8050` + // `hello-world/workload-a[Deployment] <= backend/[pods without app: backend-app] : TCP 8050` testDirName: "test_exposure_to_namespace_except_specific_pod", exposureAnalysis: true, outputFormats: ExposureValidFormats, From 256ed88143ae15860b9c0384a579f8b3c68e7f82 Mon Sep 17 00:00:00 2001 From: shireenf-ibm <82180114+shireenf-ibm@users.noreply.github.com> Date: Mon, 20 May 2024 18:35:48 +0300 Subject: [PATCH 09/12] Update pkg/netpol/connlist/connlist_test.go Co-authored-by: Adi Sosnovich <82078442+adisos@users.noreply.github.com> --- pkg/netpol/connlist/connlist_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pkg/netpol/connlist/connlist_test.go b/pkg/netpol/connlist/connlist_test.go index 3f05d1ff..0da48122 100644 --- a/pkg/netpol/connlist/connlist_test.go +++ b/pkg/netpol/connlist/connlist_test.go @@ -945,10 +945,13 @@ var goodPathTests = []struct { // first policy captures: hello-world/workload-a and exposes it on Ingress to all pods in backend namespace // second policy captures: backend/backend-app and denies all egress from it // so as result hello-world/workload-a is actually exposed to all backend pods except for backend-app - // @TODO: following exposure line in output : + // note: following exposure line in output : // `hello-world/workload-a[Deployment] <= backend/[all pods] : TCP 8050` - // should be replaced with : + // could have been more accurate with: // `hello-world/workload-a[Deployment] <= backend/[pods without app: backend-app] : TCP 8050` + // but the goal is to hint where policy can be tightened, thus it is ok to ignore policies that capture + // representative peers in the analysis + testDirName: "test_exposure_to_namespace_except_specific_pod", exposureAnalysis: true, outputFormats: ExposureValidFormats, From 58c5df1d15cdf18c0cf272568cae70c1d59b3fdc Mon Sep 17 00:00:00 2001 From: shireenf-ibm Date: Tue, 21 May 2024 08:33:54 +0300 Subject: [PATCH 10/12] gofmt --- pkg/netpol/connlist/connlist_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/netpol/connlist/connlist_test.go b/pkg/netpol/connlist/connlist_test.go index 0da48122..5f4df51f 100644 --- a/pkg/netpol/connlist/connlist_test.go +++ b/pkg/netpol/connlist/connlist_test.go @@ -949,9 +949,9 @@ var goodPathTests = []struct { // `hello-world/workload-a[Deployment] <= backend/[all pods] : TCP 8050` // could have been more accurate with: // `hello-world/workload-a[Deployment] <= backend/[pods without app: backend-app] : TCP 8050` - // but the goal is to hint where policy can be tightened, thus it is ok to ignore policies that capture - // representative peers in the analysis - + // but the goal is to hint where policy can be tightened, thus it is ok to ignore policies that capture + // representative peers in the analysis + testDirName: "test_exposure_to_namespace_except_specific_pod", exposureAnalysis: true, outputFormats: ExposureValidFormats, From 025ee8f7cbf5c4670712403f649e523d41d8960d Mon Sep 17 00:00:00 2001 From: shireenf-ibm Date: Tue, 21 May 2024 08:39:25 +0300 Subject: [PATCH 11/12] updating comments in yaml --- .../backend_netpol.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_exposure_to_namespace_except_specific_pod/backend_netpol.yaml b/tests/test_exposure_to_namespace_except_specific_pod/backend_netpol.yaml index 7712b319..39391215 100644 --- a/tests/test_exposure_to_namespace_except_specific_pod/backend_netpol.yaml +++ b/tests/test_exposure_to_namespace_except_specific_pod/backend_netpol.yaml @@ -1,7 +1,8 @@ # this policy denies any egress from backend/backend-app # however hello_world_netpol.yaml allows ingress to hello-world/workload-a from all pods in backend -# so the result we should see is that hello-world/workload-a is exposed on Ingress to backend/[all pods except backend-app] - +# still, in the results we see that there is no connection between backend/backend-app but hello-world/workload-a +# is exposed to all pods in backend namespace, because its policy accepts that; +# and our goal is to emphasize cases where the policy better be tighten (hello_world_netpol in this case) kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: From 7e0595f108024c936dece6b0ca60bb441d5d9453 Mon Sep 17 00:00:00 2001 From: shireenf-ibm Date: Tue, 21 May 2024 08:41:00 +0300 Subject: [PATCH 12/12] tiny fix --- .../backend_netpol.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_exposure_to_namespace_except_specific_pod/backend_netpol.yaml b/tests/test_exposure_to_namespace_except_specific_pod/backend_netpol.yaml index 39391215..22da7c46 100644 --- a/tests/test_exposure_to_namespace_except_specific_pod/backend_netpol.yaml +++ b/tests/test_exposure_to_namespace_except_specific_pod/backend_netpol.yaml @@ -2,7 +2,7 @@ # however hello_world_netpol.yaml allows ingress to hello-world/workload-a from all pods in backend # still, in the results we see that there is no connection between backend/backend-app but hello-world/workload-a # is exposed to all pods in backend namespace, because its policy accepts that; -# and our goal is to emphasize cases where the policy better be tighten (hello_world_netpol in this case) +# and our goal is to emphasize cases where the policy better be tightened (hello_world_netpol in this case) kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: