Refactor history sync into history_service and update docs/tests
This commit is contained in:
@@ -12,13 +12,10 @@ from typing import TYPE_CHECKING
|
||||
import structlog
|
||||
|
||||
from app.db import open_db
|
||||
from app.repositories import fail2ban_db_repo
|
||||
from app.repositories.history_archive_repo import archive_ban_event
|
||||
from app.utils.fail2ban_db_utils import get_fail2ban_db_path
|
||||
from app.services import history_service
|
||||
from app.utils.runtime_state import get_effective_settings
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import aiosqlite
|
||||
from fastapi import FastAPI
|
||||
|
||||
from app.config import Settings
|
||||
@@ -35,73 +32,17 @@ HISTORY_SYNC_INTERVAL: int = 300
|
||||
BACKFILL_WINDOW: int = 648000
|
||||
|
||||
|
||||
async def _get_db(settings: Settings) -> tuple[aiosqlite.Connection, bool]:
|
||||
db = await open_db(settings.database_path)
|
||||
return db, True
|
||||
|
||||
|
||||
async def _get_last_archive_ts(db) -> int | None:
|
||||
async with db.execute("SELECT MAX(timeofban) FROM history_archive") as cur:
|
||||
row = await cur.fetchone()
|
||||
if row is None or row[0] is None:
|
||||
return None
|
||||
return int(row[0])
|
||||
|
||||
|
||||
async def _run_sync_with_settings(settings: Settings) -> None:
|
||||
socket_path: str = settings.fail2ban_socket
|
||||
db, close_db = await _get_db(settings)
|
||||
db = await open_db(settings.database_path)
|
||||
|
||||
try:
|
||||
last_ts = await _get_last_archive_ts(db)
|
||||
now_ts = int(datetime.datetime.now(datetime.UTC).timestamp())
|
||||
|
||||
if last_ts is None:
|
||||
last_ts = now_ts - BACKFILL_WINDOW
|
||||
log.info("history_sync_backfill", window_seconds=BACKFILL_WINDOW)
|
||||
|
||||
per_page = 500
|
||||
next_since = last_ts + 1
|
||||
total_synced = 0
|
||||
|
||||
while True:
|
||||
fail2ban_db_path = await get_fail2ban_db_path(socket_path)
|
||||
rows, total = await fail2ban_db_repo.get_history_page(
|
||||
db_path=fail2ban_db_path,
|
||||
since=next_since,
|
||||
page=1,
|
||||
page_size=per_page,
|
||||
)
|
||||
|
||||
if not rows:
|
||||
break
|
||||
|
||||
for row in rows:
|
||||
await archive_ban_event(
|
||||
db=db,
|
||||
jail=row.jail,
|
||||
ip=row.ip,
|
||||
timeofban=row.timeofban,
|
||||
bancount=row.bancount,
|
||||
data=row.data,
|
||||
action="ban",
|
||||
)
|
||||
total_synced += 1
|
||||
|
||||
# Continue where we left off by max timeofban + 1.
|
||||
max_time = max(row.timeofban for row in rows)
|
||||
next_since = max_time + 1
|
||||
|
||||
if len(rows) < per_page:
|
||||
break
|
||||
|
||||
log.info("history_sync_complete", synced=total_synced)
|
||||
|
||||
synced = await history_service.sync_from_fail2ban_db(db, socket_path)
|
||||
log.info("history_sync_complete", synced=synced)
|
||||
except Exception:
|
||||
log.exception("history_sync_failed")
|
||||
finally:
|
||||
if close_db:
|
||||
await db.close()
|
||||
await db.close()
|
||||
|
||||
|
||||
async def _run_sync(app: FastAPI) -> None:
|
||||
|
||||
Reference in New Issue
Block a user