import json import ssl import urllib.request ZABBIX_URL = "http://140.44.4.60:8888/api_jsonrpc.php" ZABBIX_USER = "Admin" ZABBIX_PASS = "zabbix" ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE def zbx_call(method, params, auth=None): payload = {"jsonrpc": "2.0", "method": method, "params": params, "id": 1} headers = {"Content-Type": "application/json-rpc"} if auth: headers["Authorization"] = f"Bearer {auth}" req = urllib.request.Request(ZABBIX_URL, data=json.dumps(payload).encode("utf-8"), headers=headers, method="POST") with urllib.request.urlopen(req, timeout=10, context=ctx) as r: resp = json.loads(r.read().decode("utf-8")) if "error" in resp: raise RuntimeError(f"Zabbix error in {method}: {resp['error']}") return resp["result"] # 1. Login auth_token = zbx_call("user.login", {"username": ZABBIX_USER, "password": ZABBIX_PASS}) print("Zabbix Auth OK!") # 2. Get all hosts hosts = zbx_call("host.get", { "output": ["hostid", "host", "name", "status"], "selectInterfaces": ["interfaceid", "ip", "port", "type", "main"], "selectParentTemplates": ["templateid", "name"] }, auth_token) print(f"\nTotal Registered Hosts in Zabbix: {len(hosts)}") registered_ips = {} for h in sorted(hosts, key=lambda x: x["host"]): ips = [i["ip"] for i in h.get("interfaces", []) if i.get("ip")] ip_str = ", ".join(ips) if ips else "N/A" status_str = "MONITORED" if h["status"] == "0" else "DISABLED" templates = [t["name"] for t in h.get("parentTemplates", [])] tpl_str = ", ".join(templates) if templates else "None" print(f"[{status_str}] {h['host']} ({h['name']}) -> {ip_str} | Templates: {tpl_str}") for ip in ips: registered_ips[ip] = h["host"] # Compare with our 28 target hosts target_hosts = { # Aerodrome (10) "140.44.4.11": "sninfr2lnxctl01", "140.44.4.12": "sninfr2lnxctl02", "140.44.4.13": "sninfr2lnxctl03", "140.44.4.21": "sninfr2lnxwrk01", "140.44.4.22": "sninfr2lnxwrk02", "140.44.4.23": "sninfr2lnxwrk03", "140.44.4.24": "sninfr2lnxwrk04", "140.44.4.25": "sninfr2lnxwrk05", "140.44.4.26": "sninfr2lnxwrk06", "140.44.4.27": "sninfr2lnxwrk07", # Spaceport (10) "140.44.4.41": "sninfr0lnxctl01", "140.44.4.42": "sninfr0lnxctl02", "140.44.4.43": "sninfr0lnxctl03", "140.44.4.44": "sninfr0lnxctl04", "140.44.4.51": "sninfr0lnxwrk01", "140.44.4.52": "sninfr0lnxwrk02", "140.44.4.53": "sninfr0lnxwrk03", "140.44.4.54": "sninfr0lnxwrk04", "140.44.4.55": "sninfr0lnxwrk05", "140.44.4.56": "sninfr0lnxwrk06", # Shipyard (5) "140.44.4.71": "snshpd4lnxswm01", "140.44.4.72": "snshpd4lnxswm02", "140.44.4.73": "snshpd4lnxswm03", "140.44.4.74": "snshpd4lnxswm04", "140.44.4.75": "snshpd4lnxswm05", # AI & NUT Master (3) "140.44.4.7": "sninfr4lnxaih01", "140.44.4.8": "sninfr4lnxaih02", "14.4.4.44": "nutserver", # Synology NAS (2) "14.10.10.71": "SN-NAS", "14.10.10.72": "SnarfNAS" } print("\n=== COVERAGE AUDIT ACROSS 28 TARGET HOSTS ===") missing = [] for ip, name in sorted(target_hosts.items()): if ip in registered_ips: print(f" [OK] {ip} -> {name} (Zabbix Host: {registered_ips[ip]})") else: print(f" [MISSING] {ip} -> {name}") missing.append((ip, name)) print(f"\nTotal Missing from Target 28 Scope: {len(missing)}") for ip, name in missing: print(f" - {name} ({ip})")