- Add MITRE sync service via TAXII 2.0 with GitHub fallback - Upsert attack-pattern objects into techniques table (691 techniques) - Detect name/description changes and flag review_required on re-sync - Add APScheduler background job running every 24h - Add POST /system/sync-mitre endpoint (admin only) - Add GET /system/scheduler-status endpoint (admin only) - Configure logging for scheduler and sync visibility - Update README with new endpoints and project structure
54 lines
1.7 KiB
Python
54 lines
1.7 KiB
Python
"""Scheduled job for periodic MITRE ATT&CK synchronisation.
|
|
|
|
Uses APScheduler's ``BackgroundScheduler`` to run :func:`sync_mitre` every
|
|
24 hours. The job manages its own database session (created on entry,
|
|
closed in ``finally``) so it is fully independent from FastAPI's
|
|
request-scoped sessions.
|
|
"""
|
|
|
|
import logging
|
|
|
|
from apscheduler.schedulers.background import BackgroundScheduler
|
|
|
|
from app.database import SessionLocal
|
|
from app.services.mitre_sync_service import sync_mitre
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Module-level scheduler instance
|
|
# ---------------------------------------------------------------------------
|
|
|
|
scheduler = BackgroundScheduler()
|
|
|
|
|
|
def _run_mitre_sync() -> None:
|
|
"""Execute a MITRE sync inside its own DB session."""
|
|
logger.info("Scheduled MITRE sync job starting...")
|
|
db = SessionLocal()
|
|
try:
|
|
summary = sync_mitre(db)
|
|
logger.info("Scheduled MITRE sync job finished — %s", summary)
|
|
except Exception:
|
|
logger.exception("Scheduled MITRE sync job failed")
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
def start_scheduler() -> None:
|
|
"""Register the MITRE sync job and start the background scheduler.
|
|
|
|
The job runs every **24 hours**. It does **not** fire immediately on
|
|
startup — the first execution happens 24 h after the application boots.
|
|
"""
|
|
scheduler.add_job(
|
|
_run_mitre_sync,
|
|
trigger="interval",
|
|
hours=24,
|
|
id="mitre_sync",
|
|
name="MITRE ATT&CK sync (every 24h)",
|
|
replace_existing=True,
|
|
)
|
|
scheduler.start()
|
|
logger.info("MITRE sync scheduler started (interval=24h)")
|