Add local SQLite database and sync with Uptime Kuma
All checks were successful
Build and Push Container / build (push) Successful in 1m4s

Features:
- SQLite database to track monitors and hosts locally
- Uses Uptime Kuma tags to mark monitors as managed by Kuma Strapper
- Sync on startup, before each scan, and on-demand via API
- Shows existing monitors when re-scanning a host

New files:
- backend/services/database.py - SQLite database service
- backend/services/sync.py - Sync service for Uptime Kuma reconciliation

API endpoints:
- POST /api/sync - Full sync with Uptime Kuma
- POST /api/sync/host/<hostname> - Sync specific host
- GET /api/hosts - List tracked hosts
- GET /api/hosts/<hostname>/monitors - Get monitors for host
- GET /api/monitors/tracked - Get all tracked monitors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-01-06 09:10:26 +00:00
parent a65997a391
commit 1fd29e449f
11 changed files with 1044 additions and 47 deletions

View File

@@ -283,6 +283,50 @@ class UptimeKumaClient:
self._disconnect()
return False
# Tag management methods
def get_tags(self) -> list[dict]:
"""Get all tags."""
try:
api = self._get_api()
return api.get_tags()
except Exception as e:
self._disconnect()
raise Exception(f"Failed to get tags: {str(e)}")
def add_tag(self, name: str, color: str) -> dict:
"""Create a new tag."""
try:
api = self._get_api()
return api.add_tag(name=name, color=color)
except Exception as e:
self._disconnect()
raise Exception(f"Failed to add tag: {str(e)}")
def add_monitor_tag(self, tag_id: int, monitor_id: int, value: str = "") -> dict:
"""Add a tag to a monitor.
Args:
tag_id: The tag ID
monitor_id: The monitor ID
value: Optional value for the tag (e.g., hostname)
"""
try:
api = self._get_api()
return api.add_monitor_tag(tag_id=tag_id, monitor_id=monitor_id, value=value)
except Exception as e:
self._disconnect()
raise Exception(f"Failed to add tag to monitor: {str(e)}")
def delete_monitor_tag(self, tag_id: int, monitor_id: int, value: str = "") -> dict:
"""Remove a tag from a monitor."""
try:
api = self._get_api()
return api.delete_monitor_tag(tag_id=tag_id, monitor_id=monitor_id, value=value)
except Exception as e:
self._disconnect()
raise Exception(f"Failed to remove tag from monitor: {str(e)}")
def get_push_url(self, push_token: str) -> str:
"""Build the full push URL for a push monitor.