Archived
Harden cleanup scheduler and audit cleanup deletions
This commit is contained in:
1 parent
24747866bc
commit
23ab466c52
4 files changed
+100
-1
No files matched your search
+6
-1
@@ -104,7 +104,12 @@ def make_app(settings: DdnsSettings | None = None) -> FastAPI:
|
||||
async def _scheduler_loop(store: DdnsStore, settings: DdnsSettings) -> None:
|
||||
poll_seconds = min(settings.cleanup_interval_seconds, 60)
|
||||
while True:
|
||||
await _run_cleanup_if_due(store, settings)
|
||||
try:
|
||||
await _run_cleanup_if_due(store, settings)
|
||||
except asyncio.CancelledError:
|
||||
raise
|
||||
except Exception:
|
||||
LOGGER.exception("Scheduled cleanup loop crashed; continuing")
|
||||
await asyncio.sleep(poll_seconds)
|
||||
|
||||
|
||||
|
||||
@@ -16,3 +16,6 @@ DASHBOARD_HOSTNAME_ACTIVATED = "dashboard_hostname_activated"
|
||||
ADMIN_HOSTNAME_DELETED = "admin_hostname_deleted"
|
||||
ADMIN_UPDATE_URL_ROTATED = "admin_update_url_rotated"
|
||||
ADMIN_MANAGEMENT_URL_ROTATED = "admin_management_url_rotated"
|
||||
|
||||
CLEANUP_PENDING_HOSTNAME_DELETED = "cleanup_pending_hostname_deleted"
|
||||
CLEANUP_UNUSED_HOSTNAME_DELETED = "cleanup_unused_hostname_deleted"
|
||||
@@ -4,6 +4,7 @@ import threading
|
||||
import time
|
||||
from datetime import UTC, datetime, timedelta
|
||||
|
||||
from ..event_statuses import CLEANUP_PENDING_HOSTNAME_DELETED, CLEANUP_UNUSED_HOSTNAME_DELETED
|
||||
from .base import StoreConnectionMixin
|
||||
from .types import CleanupRunRow, cleanup_run_row
|
||||
|
||||
@@ -134,6 +135,28 @@ class RateLimitCleanupMixin(StoreConnectionMixin):
|
||||
pending_account_cutoff = (datetime.now(UTC) - timedelta(hours=pending_account_hours)).isoformat()
|
||||
event_history_cutoff = (datetime.now(UTC) - timedelta(hours=event_history_hours)).isoformat()
|
||||
with self.connect() as conn:
|
||||
deleted_accounts = conn.execute(
|
||||
"""
|
||||
SELECT hostname,
|
||||
CASE
|
||||
WHEN accepted_at IS NULL THEN 'pending'
|
||||
ELSE 'unused'
|
||||
END AS cleanup_reason
|
||||
FROM accounts
|
||||
WHERE (
|
||||
accepted_at IS NULL
|
||||
AND created_at < ?
|
||||
)
|
||||
OR (
|
||||
accepted_at IS NOT NULL
|
||||
AND created_at < ?
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM records WHERE records.hostname = accounts.hostname
|
||||
)
|
||||
)
|
||||
""",
|
||||
(pending_account_cutoff, unused_account_cutoff),
|
||||
).fetchall()
|
||||
account_cursor = conn.execute(
|
||||
"""
|
||||
DELETE FROM accounts
|
||||
@@ -168,6 +191,24 @@ class RateLimitCleanupMixin(StoreConnectionMixin):
|
||||
""",
|
||||
(datetime.now(UTC).isoformat(), account_cursor.rowcount),
|
||||
)
|
||||
conn.executemany(
|
||||
"""
|
||||
INSERT INTO update_events(hostname, ipv4, ipv6, status, detail, source_ip, created_at)
|
||||
VALUES (?, NULL, NULL, ?, ?, ?, ?)
|
||||
""",
|
||||
[
|
||||
(
|
||||
row["hostname"],
|
||||
CLEANUP_PENDING_HOSTNAME_DELETED
|
||||
if row["cleanup_reason"] == "pending"
|
||||
else CLEANUP_UNUSED_HOSTNAME_DELETED,
|
||||
"cleanup deleted abandoned hostname",
|
||||
"127.0.0.1",
|
||||
datetime.now(UTC).isoformat(),
|
||||
)
|
||||
for row in deleted_accounts
|
||||
],
|
||||
)
|
||||
return {
|
||||
"unused_accounts": account_cursor.rowcount,
|
||||
"event_rollups": rollup_cursor.rowcount,
|
||||
|
||||
Reference in new issue
Block a user