Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,19 @@ def find_connections(vertex: KubernetesBlock, vertices: list[KubernetesBlock]) -
"""

connections: list[int] = []
network_policy = vertex
network_policy_namespace = (network_policy.attributes.get("metadata") or {}).get("namespace") or "default"

for potential_pod_index, potential_vertex in enumerate(vertices):
if potential_vertex.id == vertex.id or potential_vertex.attributes.get("kind") != "Pod":
continue

network_policy = vertex
pod = potential_vertex
pod_namespace = (pod.attributes.get("metadata") or {}).get("namespace") or "default"

# NetworkPolicies are namespace-scoped and only apply to pods in the same namespace
if pod_namespace != network_policy_namespace:
continue

pod_spec = network_policy.attributes.get("spec", {})
if pod_spec is None:
Expand All @@ -54,7 +61,7 @@ def find_connections(vertex: KubernetesBlock, vertices: list[KubernetesBlock]) -
shared_labels = [k for k in match_labels if k in pod_labels and match_labels[k] == pod_labels[k]]
if len(shared_labels) == len(match_labels):
connections.append(potential_pod_index)
# the network policy has a podSelector property with no labels and should apply for all pods
# the network policy has a podSelector property with no labels and should apply for all pods in the namespace
else:
connections.append(potential_pod_index)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
apiVersion: v1
kind: Pod
metadata:
name: pod-in-namespace-a
namespace: namespace-a
labels:
app: myapp
spec:
containers:
- name: app
image: nginx:1.7.9
---
apiVersion: v1
kind: Pod
metadata:
name: pod-in-namespace-b
namespace: namespace-b
labels:
app: myapp
spec:
containers:
- name: app
image: nginx:1.7.9
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-in-namespace-a
namespace: namespace-a
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: label-policy-in-namespace-a
namespace: namespace-a
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Ingress
17 changes: 17 additions & 0 deletions tests/kubernetes/graph/test_local_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,23 @@ def test_LabelSelectorEdgeBuilder_on_templates_with_network_policy(self) -> None
self.assertEqual(5, len(local_graph.vertices))
self.assertEqual(4, len(local_graph.edges))

def test_NetworkPolicyEdgeBuilder_respects_namespace_scoping(self) -> None:
relative_file_path = "resources/Keyword/network-policy-namespace-scoping.yaml"
definitions = {}
file = os.path.realpath(os.path.join(TEST_DIRNAME, relative_file_path))
(definitions[relative_file_path], definitions_raw) = parse(file)
graph_flags = K8sGraphFlags(create_complex_vertices=True, create_edges=True)

local_graph = KubernetesLocalGraph(definitions)
local_graph.edge_builders = [NetworkPolicyEdgeBuilder]
local_graph.build_graph(render_variables=False, graph_flags=graph_flags)
# 2 pods + 2 network policies = 4 vertices
self.assertEqual(4, len(local_graph.vertices))
# Only pod-in-namespace-a should be connected; pod-in-namespace-b is in a different namespace
# allow-all-in-namespace-a -> pod-in-namespace-a (empty podSelector, same namespace)
# label-policy-in-namespace-a -> pod-in-namespace-a (matchLabels match, same namespace)
self.assertEqual(2, len(local_graph.edges))

def test_extracting_pod_from_container_types(self) -> None:
relative_file_path = "resources/statefulstate_nested_resource.yaml"
definitions = {}
Expand Down