Hedronite · Dev Lesson · Polyglot-Dev / Python · Wed 2026-09-09

Python NetworkPolicy inventory — kubernetes client census across namespaces

List first. Guessing which policy is live is how east-west holes survive review.

Lesson Class: Dev (Python + kubernetes client + NetworkPolicy)
Paired Ops: EKS NetworkPolicy VPC CNI isolation
Paired Cert: CKA Network Policies
Paired Go: client-go NetworkPolicy informer
List
All namespaces.
Flag
Wide peers.
Read-only
No PATCH tonight.
Census is read-only until the change window opens.

List first. Guessing which policy is live is how east-west holes survive review.

§I — Frame

Use the official Python kubernetes client to inventory networking.k8s.io/v1 NetworkPolicy objects. Emit a census: namespace, name, podSelector empty-or-not, ingress rule count, and whether any ingress peer is "all namespaces." Pair with Ops enforcement work. Do not reopen IRSA annotation walking (09-06).

§II — Client bootstrap

from kubernetes import client, config

config.load_kube_config()  # or load_incluster_config()
v1 = client.NetworkingV1Api()
policies = v1.list_network_policy_for_all_namespaces()

Prefer list_network_policy_for_all_namespaces for cluster review. Namespace-scoped list is for a single tenancy window.

§III — Census row shape

For each item, record:

Print WARN when wide_peer is True or when ingress_count == 0 while policyTypes includes Ingress (default deny for selected pods). Empty ingress with Ingress type is a deliberate deny, not a missing object.

§IV — Worked filter

rows = []
for item in policies.items:
    spec = item.spec
    sel = spec.pod_selector
    empty_sel = not (sel.match_labels or sel.match_expressions)
    ingress = spec.ingress or []
    wide = False
    for rule in ingress:
        peers = rule._from or []
        if not peers:
            wide = True
            continue
        for peer in peers:
            if peer.namespace_selector is None and peer.pod_selector is None and peer.ip_block is None:
                wide = True
    rows.append({
        "ns": item.metadata.namespace,
        "name": item.metadata.name,
        "empty_sel": empty_sel,
        "ingress": len(ingress),
        "wide": wide,
    })

Note the client attribute _from (Python reserved word from). That detail belongs in the lesson so the census does not crash on first contact.

§V — What not to invent

§VI — Relation to Cert and Go

Cert trains human comparison of three YAML candidates (Q13). This census flags wide peers in live clusters. Go companion watches via informer for the same object family.

§VII — Closing

Ship a table ops can sort. Flag wide peers. Leave mutation for a later change window.

Related