Move fleet health into admin settings and tidy landing page
This commit is contained in:
@@ -11,7 +11,6 @@ from fastapi.responses import StreamingResponse
|
||||
|
||||
from ..auth import get_current_user_event_stream
|
||||
from . import requests as requests_router
|
||||
from .status import services_status
|
||||
|
||||
router = APIRouter(prefix="/events", tags=["events"])
|
||||
|
||||
@@ -85,9 +84,7 @@ async def events_stream(
|
||||
async def event_generator():
|
||||
yield "retry: 2000\n\n"
|
||||
last_recent_signature: Optional[str] = None
|
||||
last_services_signature: Optional[str] = None
|
||||
next_recent_at = 0.0
|
||||
next_services_at = 0.0
|
||||
heartbeat_counter = 0
|
||||
|
||||
while True:
|
||||
@@ -129,27 +126,6 @@ async def events_stream(
|
||||
yield _sse_json(payload)
|
||||
sent_any = True
|
||||
|
||||
if now >= next_services_at:
|
||||
next_services_at = now + 30.0
|
||||
try:
|
||||
status_payload = await services_status()
|
||||
payload = {
|
||||
"type": "home_services",
|
||||
"ts": datetime.now(timezone.utc).isoformat(),
|
||||
"status": status_payload,
|
||||
}
|
||||
except Exception as exc:
|
||||
payload = {
|
||||
"type": "home_services",
|
||||
"ts": datetime.now(timezone.utc).isoformat(),
|
||||
"error": str(exc),
|
||||
}
|
||||
signature = json.dumps(payload, ensure_ascii=True, separators=(",", ":"), default=str)
|
||||
if signature != last_services_signature:
|
||||
last_services_signature = signature
|
||||
yield _sse_json(payload)
|
||||
sent_any = True
|
||||
|
||||
if sent_any:
|
||||
heartbeat_counter = 0
|
||||
else:
|
||||
|
||||
@@ -2,7 +2,7 @@ from typing import Any, Dict
|
||||
import httpx
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
|
||||
from ..auth import get_current_user
|
||||
from ..auth import require_admin
|
||||
from ..runtime import get_runtime_settings
|
||||
from ..clients.jellyseerr import JellyseerrClient
|
||||
from ..clients.sonarr import SonarrClient
|
||||
@@ -11,7 +11,7 @@ from ..clients.prowlarr import ProwlarrClient
|
||||
from ..clients.qbittorrent import QBittorrentClient
|
||||
from ..clients.jellyfin import JellyfinClient
|
||||
|
||||
router = APIRouter(prefix="/status", tags=["status"], dependencies=[Depends(get_current_user)])
|
||||
router = APIRouter(prefix="/status", tags=["status"], dependencies=[Depends(require_admin)])
|
||||
|
||||
|
||||
async def _check(name: str, configured: bool, func) -> Dict[str, Any]:
|
||||
|
||||
@@ -9,6 +9,7 @@ from fastapi import HTTPException
|
||||
from starlette.requests import Request
|
||||
|
||||
from backend.app import db
|
||||
from backend.app.auth import require_admin
|
||||
from backend.app.config import settings
|
||||
from backend.app.network_security import request_trusts_forwarded_headers, validate_notification_target_url
|
||||
from backend.app.models import NormalizedState, RequestType, Snapshot, TimelineHop
|
||||
@@ -102,6 +103,11 @@ class NetworkSecurityTests(unittest.TestCase):
|
||||
|
||||
|
||||
class ServiceStatusTests(unittest.IsolatedAsyncioTestCase):
|
||||
def test_status_router_requires_admin(self) -> None:
|
||||
dependencies = [getattr(dependency, "dependency", None) for dependency in status_router.router.dependencies]
|
||||
|
||||
self.assertIn(require_admin, dependencies)
|
||||
|
||||
async def test_qbittorrent_login_accepts_modern_empty_response_with_session_cookie(self) -> None:
|
||||
class FakeClient:
|
||||
def __init__(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user