feat: add infrastructure automation scripts and master improvement plan
This commit is contained in:
79
scripts/audit_zabbix_hosts.py
Normal file
79
scripts/audit_zabbix_hosts.py
Normal file
@@ -0,0 +1,79 @@
|
||||
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})")
|
||||
Reference in New Issue
Block a user