Python kubernetes client — Gateway API HTTPRoute census
List parentRefs before you cut over Ingress. Guessing Accepted parents is how silent 404s survive review.
<!-- hal:authoritative:yaml -->
List parentRefs before you cut over Ingress. Guessing which HTTPRoutes are Accepted is how silent 404s survive review.
§I — Frame
Use the official Python kubernetes client CustomObjectsApi to inventory Gateway and HTTPRoute objects under gateway.networking.k8s.io. Pair with Ops GKE Gateway work. Do not reopen PSA label walking (09-12) or NetworkPolicy listing (09-09).
§II — Client bootstrap
from kubernetes import client, config
config.load_kube_config()
cust = client.CustomObjectsApi()
GROUP = "gateway.networking.k8s.io"
VERSION = "v1"
Prefer v1 when the cluster CRDs are v1. Fall back to v1beta1 only if list calls 404 on v1.
§III — Gateway census row
gws = cust.list_cluster_custom_object(GROUP, VERSION, "gateways")
rows = []
for item in gws.get("items", []):
md = item["metadata"]
spec = item.get("spec", {})
status = item.get("status", {})
listeners = [
{
"name": L.get("name"),
"port": L.get("port"),
"protocol": L.get("protocol"),
"hostname": L.get("hostname"),
}
for L in spec.get("listeners", [])
]
addrs = [a.get("value") for a in status.get("addresses", [])]
rows.append({
"ns": md["namespace"],
"name": md["name"],
"class": spec.get("gatewayClassName"),
"listeners": listeners,
"addresses": addrs,
})
Print WARN when addresses is empty on an external class you expect to be live.
§IV — HTTPRoute parent and backend census
routes = cust.list_cluster_custom_object(GROUP, VERSION, "httproutes")
for item in routes.get("items", []):
md = item["metadata"]
spec = item.get("spec", {})
status = item.get("status", {})
parents = spec.get("parentRefs", [])
accepted = []
for p in status.get("parents", []):
conds = p.get("conditions", [])
ok = any(c.get("type") == "Accepted" and c.get("status") == "True" for c in conds)
accepted.append({"parent": p.get("parentRef"), "accepted": ok})
backends = []
for rule in spec.get("rules", []):
for b in rule.get("backendRefs", []):
backends.append({"name": b.get("name"), "port": b.get("port"), "ns": b.get("namespace")})
print({
"ns": md["namespace"],
"name": md["name"],
"parentRefs": parents,
"accepted": accepted,
"backends": backends,
"hostnames": spec.get("hostnames"),
})
Highest priority WARN: HTTPRoute with parentRefs set but no Accepted=True parent, or backendRefs pointing at a Service name that does not exist in the route namespace.
§V — What not to invent
- Do not PATCH Gateway or HTTPRoute from the census script unless operator asks. Census is read-only tonight.
- Do not treat missing GatewayClass as "Ingress still works." Missing class means this Gateway API path will not program.
- Namespace-scoped list helpers exist; cluster list is fine for a fleet census. Paginate if the API returns continue tokens.
§VI — Relation to Cert
Cert trains migrating an Ingress named web into Gateway web-gateway and HTTPRoute web-route (Bootcamp Q11). This census finds live Gateway API objects (and orphans) before and after that cutover pattern on GKE.
§VII — Closing
Ship a table ops can sort by Accepted parent and empty addresses. Flag routes that still have no programmed parent. Leave mutation for a change window.
Related
- Ops
- Cert