82 lines
2.6 KiB
Python
82 lines
2.6 KiB
Python
import os
|
|
import paramiko
|
|
import requests
|
|
from datetime import datetime
|
|
from collections import defaultdict
|
|
|
|
# === CONFIG ===
|
|
NODES = {
|
|
"shredderv2": {"host": "shredderv2.sshjunkie.com", "user": "doc"},
|
|
"thevault": {"host": "209.209.9.128", "user": "doc"},
|
|
"technodrome1": {"host": "38.102.127.165", "user": "doc"},
|
|
"technodrome2": {"host": "38.102.127.166", "user": "doc"},
|
|
}
|
|
|
|
SSH_KEY = "~/.ssh/genesis_healthcheck"
|
|
ZFS_CMD = "zfs list -t snapshot -o name,creation -s creation"
|
|
|
|
# === TELEGRAM CONFIG ===
|
|
TELEGRAM_BOT_TOKEN="8178867489:AAH0VjN7VnZSCIWasSz_y97iBLLjPJA751k"
|
|
TELEGRAM_CHAT_ID="1559582356"
|
|
|
|
def send_to_telegram(message):
|
|
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
|
|
data = {
|
|
"chat_id": TELEGRAM_CHAT_ID,
|
|
"text": message,
|
|
"parse_mode": "Markdown"
|
|
}
|
|
try:
|
|
requests.post(url, data=data, timeout=10)
|
|
except Exception as e:
|
|
print(f"Telegram send failed: {e}")
|
|
|
|
def ssh_run(host, user, cmd):
|
|
ssh = paramiko.SSHClient()
|
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
ssh.connect(hostname=host, username=user, key_filename=os.path.expanduser(SSH_KEY), timeout=10)
|
|
stdin, stdout, stderr = ssh.exec_command(cmd)
|
|
out = stdout.read().decode().strip()
|
|
ssh.close()
|
|
return out
|
|
|
|
def parse_snapshot_output(output):
|
|
lines = output.strip().split("\n")[1:] # skip header
|
|
snaps = defaultdict(list)
|
|
|
|
for line in lines:
|
|
try:
|
|
name, creation = line.strip().split(None, 1)
|
|
dataset, _ = name.split("@")
|
|
dt = datetime.strptime(creation.strip(), "%a %b %d %H:%M %Y")
|
|
snaps[dataset].append(dt)
|
|
except Exception:
|
|
continue
|
|
return snaps
|
|
|
|
def summarize(node_name, dataset_snaps):
|
|
if not dataset_snaps:
|
|
send_to_telegram(f"⚠️ *No snapshots found* on `{node_name}`")
|
|
return
|
|
|
|
msg = [f"📦 *ZFS Snapshot Report — {node_name}*"]
|
|
for dataset, times in sorted(dataset_snaps.items()):
|
|
age = (datetime.now() - max(times)).total_seconds() / 3600
|
|
msg.append(
|
|
f"*{dataset}*\n"
|
|
f"- Count: {len(times)}\n"
|
|
f"- Oldest: {min(times)}\n"
|
|
f"- Newest: {max(times)}\n"
|
|
f"- Recent age: {age:.2f}h\n"
|
|
)
|
|
send_to_telegram("\n".join(msg))
|
|
|
|
if __name__ == "__main__":
|
|
for name, node in NODES.items():
|
|
try:
|
|
output = ssh_run(node["host"], node["user"], ZFS_CMD)
|
|
data = parse_snapshot_output(output)
|
|
summarize(name.upper(), data)
|
|
except Exception as e:
|
|
send_to_telegram(f"❌ Failed to check `{name}`: {e}")
|