248 lines
7.5 KiB
Python
Executable File
248 lines
7.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Automated Uptime Kuma Monitor Setup for tower-of-joy Infrastructure
|
|
|
|
This script automatically creates monitors for all infrastructure services in Uptime Kuma.
|
|
It is idempotent - safe to run multiple times without creating duplicates.
|
|
|
|
Usage:
|
|
source .venv/bin/activate
|
|
python3 scripts/setup-kuma-monitors.py
|
|
|
|
Environment Variables:
|
|
KUMA_URL: Uptime Kuma URL (default: http://192.168.86.149:3001)
|
|
KUMA_USERNAME: Uptime Kuma admin username (will prompt if not set)
|
|
KUMA_PASSWORD: Uptime Kuma admin password (will prompt if not set)
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
from getpass import getpass
|
|
|
|
try:
|
|
from uptime_kuma_api import UptimeKumaApi, MonitorType
|
|
except ImportError:
|
|
print("\033[0;31mError: uptime-kuma-api package not installed\033[0m")
|
|
print("\nInstall dependencies:")
|
|
print(" source .venv/bin/activate")
|
|
print(" pip install -r requirements.txt")
|
|
sys.exit(1)
|
|
|
|
# Configuration
|
|
KUMA_URL = os.getenv("KUMA_URL", "http://192.168.86.149:3001")
|
|
|
|
# Service definitions
|
|
MONITORS = [
|
|
{
|
|
"name": "Portainer",
|
|
"url": "http://192.168.86.149:8001",
|
|
"interval": 60,
|
|
"type": MonitorType.HTTP,
|
|
"description": "Container management interface"
|
|
},
|
|
{
|
|
"name": "Nginx Proxy Manager",
|
|
"url": "http://192.168.86.149:81",
|
|
"interval": 60,
|
|
"type": MonitorType.HTTP,
|
|
"description": "Reverse proxy admin interface"
|
|
},
|
|
{
|
|
"name": "Ollama API",
|
|
"url": "http://192.168.86.149:11434",
|
|
"interval": 60,
|
|
"type": MonitorType.HTTP,
|
|
"description": "ML model API endpoint"
|
|
},
|
|
{
|
|
"name": "Headscale",
|
|
"url": "http://192.168.86.149:8085/health",
|
|
"interval": 60,
|
|
"type": MonitorType.HTTP,
|
|
"description": "Mesh VPN control server"
|
|
},
|
|
{
|
|
"name": "Uptime Kuma",
|
|
"url": "http://192.168.86.149:3001",
|
|
"interval": 120,
|
|
"type": MonitorType.HTTP,
|
|
"description": "Service monitoring (self-check)"
|
|
},
|
|
{
|
|
"name": "Netdata",
|
|
"url": "http://192.168.86.149:19999",
|
|
"interval": 60,
|
|
"type": MonitorType.HTTP,
|
|
"description": "System metrics dashboard"
|
|
},
|
|
{
|
|
"name": "Heimdall",
|
|
"url": "http://192.168.86.149:8888",
|
|
"interval": 60,
|
|
"type": MonitorType.HTTP,
|
|
"description": "Application dashboard"
|
|
},
|
|
{
|
|
"name": "Organizr",
|
|
"url": "http://192.168.86.149:9999",
|
|
"interval": 60,
|
|
"type": MonitorType.HTTP,
|
|
"description": "Unified dashboard"
|
|
},
|
|
{
|
|
"name": "Jellyfin",
|
|
"url": "http://192.168.86.149:8096",
|
|
"interval": 60,
|
|
"type": MonitorType.HTTP,
|
|
"description": "Media streaming server"
|
|
},
|
|
]
|
|
|
|
|
|
def print_color(text, color="reset"):
|
|
"""Print colored text"""
|
|
colors = {
|
|
"red": "\033[0;31m",
|
|
"green": "\033[0;32m",
|
|
"yellow": "\033[1;33m",
|
|
"blue": "\033[0;34m",
|
|
"cyan": "\033[0;36m",
|
|
"reset": "\033[0m"
|
|
}
|
|
print(f"{colors.get(color, '')}{text}{colors['reset']}")
|
|
|
|
|
|
def get_credentials():
|
|
"""Get credentials from environment or prompt user"""
|
|
username = os.getenv("KUMA_USERNAME")
|
|
password = os.getenv("KUMA_PASSWORD")
|
|
|
|
if not username:
|
|
print_color("\nUptime Kuma credentials required", "yellow")
|
|
username = input("Username: ").strip()
|
|
|
|
if not password:
|
|
password = getpass("Password: ").strip()
|
|
|
|
return username, password
|
|
|
|
|
|
def setup_monitors():
|
|
"""Configure all monitors in Uptime Kuma"""
|
|
print_color("╔════════════════════════════════════════════╗", "blue")
|
|
print_color("║ Uptime Kuma Automated Monitor Setup ║", "blue")
|
|
print_color("╚════════════════════════════════════════════╝", "blue")
|
|
print()
|
|
print(f"Target: {KUMA_URL}")
|
|
print(f"Monitors to configure: {len(MONITORS)}")
|
|
print()
|
|
|
|
# Get credentials
|
|
username, password = get_credentials()
|
|
|
|
# Connect to Uptime Kuma
|
|
print_color("\nConnecting to Uptime Kuma...", "blue")
|
|
try:
|
|
api = UptimeKumaApi(KUMA_URL)
|
|
api.login(username, password)
|
|
print_color("✓ Connected successfully", "green")
|
|
except Exception as e:
|
|
print_color(f"✗ Connection failed: {e}", "red")
|
|
print()
|
|
print("Troubleshooting:")
|
|
print(" 1. Verify Uptime Kuma is running: docker ps | grep uptime-kuma")
|
|
print(f" 2. Check URL is correct: {KUMA_URL}")
|
|
print(" 3. Verify credentials are correct")
|
|
sys.exit(1)
|
|
|
|
print()
|
|
|
|
# Get existing monitors
|
|
print_color("Fetching existing monitors...", "blue")
|
|
existing_monitors = api.get_monitors()
|
|
existing_names = {m["name"] for m in existing_monitors}
|
|
print(f"Found {len(existing_monitors)} existing monitor(s)")
|
|
print()
|
|
|
|
# Configure each monitor
|
|
print_color("Configuring monitors...", "blue")
|
|
print()
|
|
|
|
created = 0
|
|
skipped = 0
|
|
failed = 0
|
|
|
|
for monitor_def in MONITORS:
|
|
name = monitor_def["name"]
|
|
|
|
if name in existing_names:
|
|
print(f"⊙ {name} - Already exists (skipping)")
|
|
skipped += 1
|
|
continue
|
|
|
|
try:
|
|
# Create the monitor
|
|
api.add_monitor(
|
|
type=monitor_def["type"],
|
|
name=name,
|
|
url=monitor_def["url"],
|
|
interval=monitor_def["interval"],
|
|
description=monitor_def.get("description", ""),
|
|
retryInterval=60,
|
|
resendInterval=0,
|
|
maxretries=1,
|
|
upsideDown=False,
|
|
notificationIDList=[],
|
|
httpBodyEncoding="utf8",
|
|
method="GET",
|
|
maxredirects=10,
|
|
accepted_statuscodes=["200-299"]
|
|
)
|
|
print_color(f"✓ {name} - Created", "green")
|
|
print(f" URL: {monitor_def['url']}")
|
|
print(f" Interval: {monitor_def['interval']}s")
|
|
created += 1
|
|
except Exception as e:
|
|
print_color(f"✗ {name} - Failed: {e}", "red")
|
|
failed += 1
|
|
|
|
print()
|
|
|
|
# Disconnect
|
|
api.disconnect()
|
|
|
|
# Summary
|
|
print_color("═══════════════════════════════════════════", "blue")
|
|
print_color("Summary:", "green")
|
|
print_color("═══════════════════════════════════════════", "blue")
|
|
print(f"Created: {created}")
|
|
print(f"Skipped (already exist): {skipped}")
|
|
print(f"Failed: {failed}")
|
|
print()
|
|
|
|
if created > 0:
|
|
print_color("✓ Setup complete! Monitors are now active.", "green")
|
|
print()
|
|
print("View monitors at:", KUMA_URL)
|
|
print("Refresh Organizr to see status widgets update")
|
|
elif skipped == len(MONITORS):
|
|
print_color("✓ All monitors already configured", "green")
|
|
else:
|
|
print_color("⚠ Some monitors could not be created", "yellow")
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
setup_monitors()
|
|
except KeyboardInterrupt:
|
|
print()
|
|
print_color("Setup cancelled by user", "yellow")
|
|
sys.exit(130)
|
|
except Exception as e:
|
|
print()
|
|
print_color(f"Unexpected error: {e}", "red")
|
|
import traceback
|
|
traceback.print_exc()
|
|
sys.exit(1)
|