fix(daily-infra-report): complete Zulip nested-key fix + Proxmox port/auth fix (PR #64 review fix 1-2)
PR Pipeline — Authorize → Validate → Review → Merge / auth (pull_request) Successful in 4s
PR Pipeline — Authorize → Validate → Review → Merge / validate (pull_request) Successful in 3s
PR Pipeline — Authorize → Validate → Review → Merge / lint (pull_request) Successful in 3s
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (pull_request) Successful in 2s
PR Pipeline — Authorize → Validate → Review → Merge / gate (pull_request) Successful in 1s

This commit is contained in:
root
2026-09-10 22:03:48 +00:00
parent 25cf2f5eef
commit 32fe7c0652
+34 -18
View File
@@ -15,7 +15,7 @@ import smtplib, json, subprocess, os, sys, datetime, re
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
PVE = "https://minipve.sysloggh.net" PVE = "https://192.168.68.12:8006"
AUTH = "Authorization: PVEAPIToken=monitoring@pve!mumuni=eafd56c5-93d4-4d40-a41d-e688be0987f3" AUTH = "Authorization: PVEAPIToken=monitoring@pve!mumuni=eafd56c5-93d4-4d40-a41d-e688be0987f3"
# ── Shared credentials —─ # ── Shared credentials —─
@@ -38,10 +38,16 @@ TIME_STR = NOW.strftime("%Y-%m-%d %H:%M UTC")
# ── Helpers ── # ── Helpers ──
def pve_get(path): def pve_get(path):
cmd = f'curl -sfk --connect-timeout 10 "{PVE}{path}" -H "{AUTH}"' """Fetch PVE API data. Returns list on success, None on error (to distinguish from empty list)."""
cmd = f'curl -sk --connect-timeout 10 "{PVE}{path}" -H "{AUTH}"'
try: try:
return json.loads(subprocess.check_output(cmd, shell=True))["data"] r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=12)
except: return [] if r.returncode != 0:
return None
data = json.loads(r.stdout)
return data.get("data", [])
except:
return None
def ssh(host, cmd): def ssh(host, cmd):
try: try:
@@ -97,21 +103,31 @@ def collect():
# ── Proxmox Nodes ── # ── Proxmox Nodes ──
nodes = pve_get("/api2/json/nodes") nodes = pve_get("/api2/json/nodes")
report["nodes"] = {n["node"]: { if nodes is None:
"cpu_pct": round(n.get('cpu',0)*100, 1), report["nodes"] = {}
"ram": f"{n.get('mem',0)//1024//1024}/{n.get('maxmem',0)//1024//1024}MB", report["node_count"] = 0
"ram_pct": round(n.get('mem',0)/n.get('maxmem',1)*100, 0), report["nodes_online"] = 0
"disk": f"{n.get('disk',0)//1024//1024//1024}/{n.get('maxdisk',0)//1024//1024//1024}GB", report["pve_probe_status"] = "unreachable"
"disk_pct": round(n.get('disk',0)/n.get('maxdisk',1)*100, 0), else:
"uptime_h": n.get('uptime',0)//3600, report["nodes"] = {n["node"]: {
"status": n["status"] "cpu_pct": round(n.get('cpu',0)*100, 1),
} for n in nodes} "ram": f"{n.get('mem',0)//1024//1024}/{n.get('maxmem',0)//1024//1024}MB",
report["node_count"] = len(nodes) "ram_pct": round(n.get('mem',0)/n.get('maxmem',1)*100, 0),
report["nodes_online"] = sum(1 for n in nodes if n["status"] == "online") "disk": f"{n.get('disk',0)//1024//1024//1024}/{n.get('maxdisk',0)//1024//1024//1024}GB",
"disk_pct": round(n.get('disk',0)/n.get('maxdisk',1)*100, 0),
"uptime_h": n.get('uptime',0)//3600,
"status": n["status"]
} for n in nodes}
report["node_count"] = len(nodes)
report["nodes_online"] = sum(1 for n in nodes if n["status"] == "online")
report["pve_probe_status"] = "ok"
# ── VMs/CTs ── # ── VMs/CTs ──
resources = pve_get("/api2/json/cluster/resources") resources = pve_get("/api2/json/cluster/resources")
vms = [r for r in resources if r.get("type") in ("qemu","lxc")] if resources is None:
vms = []
else:
vms = [r for r in resources if r.get("type") in ("qemu","lxc")]
report["total_vms"] = len(vms) report["total_vms"] = len(vms)
report["running_vms"] = sum(1 for v in vms if v.get("status") == "running") report["running_vms"] = sum(1 for v in vms if v.get("status") == "running")
stopped = [v for v in vms if v.get("status") != "running"] stopped = [v for v in vms if v.get("status") != "running"]
@@ -291,8 +307,8 @@ def collect():
# Abiba (pi) # Abiba (pi)
report["agents"]["abiba"] = { report["agents"]["abiba"] = {
"platform": "pi", "ct": 100, "ip": "192.168.68.24", "platform": "pi", "ct": 100, "ip": "192.168.68.24",
"zulip_connected": zulip_health.get("connected", False), "zulip_connected": zulip_state.get("connected", False),
"zulip_processed": zulip_health.get("messages_processed", 0), "zulip_processed": zulip_state.get("messages_processed", 0),
"pm2_status": pm2.get("status", "unknown"), "pm2_status": pm2.get("status", "unknown"),
"pm2_restarts": pm2.get("restarts", "?"), "pm2_restarts": pm2.get("restarts", "?"),
"pm2_uptime": pm2.get("uptime", "?"), "pm2_uptime": pm2.get("uptime", "?"),