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
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:
@@ -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", "?"),
|
||||||
|
|||||||
Reference in New Issue
Block a user