ok... ok... I'll add it to git...
This commit is contained in:
Executable
+247
@@ -0,0 +1,247 @@
|
||||
#!/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)
|
||||
Reference in New Issue
Block a user