POST /api/v1/settings persisted the new status check interval and echoed it back, but never rescheduled the running job: reschedule_status_checks() is defined in app/core/scheduler.py and has no caller anywhere. The UI and scan_config.json show the new value while the scheduler keeps firing at the old one until the backend restarts. On our install this went unnoticed for three weeks: 3600s was configured but 30s stayed in effect, so ~120 nodes were pinged 120x more often than intended with no visible symptom. Also add ge=10 to interval_seconds, mirroring the floor already enforced by reschedule_status_checks(). Without it a value below 10 is written to scan_config.json first and only then raises, which surfaces as a 500 and leaves the invalid value to be reloaded on the next boot. Both new tests fail without the fix: the first with AttributeError (the route does not import the function), the second with 200 instead of 422. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
53 lines
2.0 KiB
Python
53 lines
2.0 KiB
Python
"""App-level settings (status checker interval, etc.)."""
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from pydantic import BaseModel, Field
|
|
|
|
from app.api.deps import get_current_user
|
|
from app.core.config import settings
|
|
from app.core.scheduler import (
|
|
reschedule_service_checks,
|
|
reschedule_status_checks,
|
|
set_service_checks_enabled,
|
|
)
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class AppSettings(BaseModel):
|
|
# Mirrors the floor enforced by reschedule_status_checks(): rejecting here
|
|
# returns 422 instead of persisting the value and then failing with a 500.
|
|
interval_seconds: int = Field(ge=10)
|
|
service_check_enabled: bool = False
|
|
service_check_interval: int = Field(default=300, ge=30)
|
|
|
|
|
|
@router.get("", response_model=AppSettings)
|
|
async def get_settings(_: str = Depends(get_current_user)) -> AppSettings:
|
|
return AppSettings(
|
|
interval_seconds=settings.status_checker_interval,
|
|
service_check_enabled=settings.service_check_enabled,
|
|
service_check_interval=settings.service_check_interval,
|
|
)
|
|
|
|
|
|
@router.post("", response_model=AppSettings)
|
|
async def update_settings(
|
|
payload: AppSettings, _: str = Depends(get_current_user)
|
|
) -> AppSettings:
|
|
try:
|
|
settings.status_checker_interval = payload.interval_seconds
|
|
settings.service_check_enabled = payload.service_check_enabled
|
|
settings.service_check_interval = payload.service_check_interval
|
|
settings.save_overrides()
|
|
# Apply the status-check schedule live. Without this the new interval is
|
|
# persisted and shown in the UI, but the running job keeps the old one
|
|
# until the backend restarts.
|
|
reschedule_status_checks(payload.interval_seconds)
|
|
# Apply the service-check schedule live.
|
|
set_service_checks_enabled(payload.service_check_enabled)
|
|
if payload.service_check_enabled:
|
|
reschedule_service_checks(payload.service_check_interval)
|
|
return payload
|
|
except Exception as exc:
|
|
raise HTTPException(status_code=500, detail=str(exc)) from exc
|