Rewrite Application Sites page to reflect real k8s state
modules/sites.py was still a fully Docker-era hardcoded registry: container names (odoo-clean-odoo-1, frappe-erpnext, nextcloud-app, mautic-app, n8n-app) that no longer exist post-migration, checked via `docker inspect` over SSH, plus hardcoded domain/port fields - nextcloud and mautic even had domain: None, silently falling back to dead Docker host-port URLs while their real Ingress domains (next.cloud.nav.ovh, mautics.nav.ovh) sat unused. Now sources everything live from the cluster: - Domain + TLS from the actual Ingress object per app (via the new get_ingress_info() in modules/kubernetes.py), not a static guess. Odoo/Nextcloud's Ingress lives in `default` (see prior commit for the RBAC this needed); n8n/mautic/erpnext's lives in their own namespace. - App/DB/cache/worker/scheduler status from real Deployment state (list_deployments_for_namespace(), new in modules/kubernetes.py) instead of `docker inspect`. - Health probe now hits the real domain directly from the pod (it has normal internet egress) instead of SSH-ing back out to the host to curl a public HTTPS URL, which is what the RUNNING_ON_MAIN_SERVER branch would have done for a pod whose hostname never matches the main-server hostname check. Same API/template contract as before (get_sites_list/get_site_health return the same field shapes) - templates/pages/sites.html needs no changes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017avLHFqkiti3g62Anq9sVA
This commit is contained in:
@@ -21,11 +21,12 @@ NAMESPACES = [
|
||||
_core_v1 = None
|
||||
_apps_v1 = None
|
||||
_custom_objects = None
|
||||
_networking_v1 = None
|
||||
K8S_AVAILABLE = False
|
||||
|
||||
|
||||
def _init_client():
|
||||
global _core_v1, _apps_v1, _custom_objects, K8S_AVAILABLE
|
||||
global _core_v1, _apps_v1, _custom_objects, _networking_v1, K8S_AVAILABLE
|
||||
if _core_v1 is not None or not _K8S_IMPORT_OK:
|
||||
return
|
||||
try:
|
||||
@@ -33,6 +34,7 @@ def _init_client():
|
||||
_core_v1 = client.CoreV1Api()
|
||||
_apps_v1 = client.AppsV1Api()
|
||||
_custom_objects = client.CustomObjectsApi()
|
||||
_networking_v1 = client.NetworkingV1Api()
|
||||
K8S_AVAILABLE = True
|
||||
except Exception as e:
|
||||
print(f"[kubernetes] in-cluster config unavailable: {e}")
|
||||
@@ -181,6 +183,54 @@ def list_deployments():
|
||||
return deployments
|
||||
|
||||
|
||||
def get_ingress_info(name, namespace):
|
||||
"""Real domain/TLS for one Ingress, or None if unavailable/not found.
|
||||
Used by modules/sites.py instead of the old hardcoded Docker-era
|
||||
domain fields — reflects actual live k8s Ingress state."""
|
||||
_init_client()
|
||||
if not K8S_AVAILABLE:
|
||||
return None
|
||||
try:
|
||||
ing = _networking_v1.read_namespaced_ingress(name, namespace)
|
||||
except Exception:
|
||||
return None
|
||||
host = None
|
||||
if ing.spec and ing.spec.rules:
|
||||
for rule in ing.spec.rules:
|
||||
if rule.host:
|
||||
host = rule.host
|
||||
break
|
||||
tls = bool(ing.spec and ing.spec.tls)
|
||||
return {'host': host, 'tls': tls}
|
||||
|
||||
|
||||
def list_deployments_for_namespace(ns):
|
||||
"""Targeted single-namespace deployment list (vs. list_deployments()'s
|
||||
fixed NAMESPACES sweep) — used by modules/sites.py per app."""
|
||||
_init_client()
|
||||
if not K8S_AVAILABLE:
|
||||
return []
|
||||
try:
|
||||
resp = _apps_v1.list_namespaced_deployment(ns)
|
||||
except Exception as e:
|
||||
print(f"[kubernetes] list deployments failed for {ns}: {e}")
|
||||
return []
|
||||
out = []
|
||||
for dep in resp.items:
|
||||
desired = dep.spec.replicas or 0
|
||||
ready = dep.status.ready_replicas or 0
|
||||
containers = dep.spec.template.spec.containers or []
|
||||
image = containers[0].image if containers else '—'
|
||||
out.append({
|
||||
'name': dep.metadata.name,
|
||||
'desired': desired,
|
||||
'ready': ready,
|
||||
'health': _deploy_health(desired, ready),
|
||||
'image': image,
|
||||
})
|
||||
return out
|
||||
|
||||
|
||||
def get_pod_metrics():
|
||||
"""Best-effort CPU/mem per pod via metrics-server. Returns {} if it's not
|
||||
installed or unreachable — callers must treat an empty dict as 'no data',
|
||||
|
||||
Reference in New Issue
Block a user