b981c06d59
- Fix unit test imports: add env setup in conftest.py before module imports - Add 24 new auth router tests (RBAC, preferences, password validation) - Add 16 new tests for litellm and chat_summary routers - Apply black formatting and ruff linting across codebase - Add pre-commit hooks configuration (black, ruff, file checks) - Increase CI coverage threshold from 40% to 50% Test Results: - 206 tests passing (91 unit + 115 integration) - Coverage: 58.79% on core modules - auth.py: 57% → 85%, litellm.py: 23% → 87%, chat_summary.py: 41% → 100% - auth_service: 96.51%, config: 100%, rbac: 93.48%
51 lines
1.5 KiB
Python
51 lines
1.5 KiB
Python
import docker
|
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
|
|
from config import DOCKER_HOST
|
|
from rbac import require_admin
|
|
|
|
router = APIRouter()
|
|
|
|
_client = None
|
|
|
|
|
|
def get_docker_client():
|
|
"""Get or create Docker client (lazy initialization)."""
|
|
global _client
|
|
if _client is None:
|
|
_client = docker.DockerClient(base_url=DOCKER_HOST)
|
|
return _client
|
|
|
|
|
|
@router.get("/containers")
|
|
def list_containers():
|
|
client = get_docker_client()
|
|
return [
|
|
{
|
|
"id": c.short_id,
|
|
"name": c.name,
|
|
"status": c.status,
|
|
"health": (c.attrs.get("State", {}).get("Health", {}) or {}).get("Status", ""),
|
|
"image": c.image.tags[0] if c.image.tags else str(c.image.id)[:20],
|
|
"ports": c.ports,
|
|
}
|
|
for c in client.containers.list(all=True)
|
|
]
|
|
|
|
|
|
@router.post("/containers/{container_id}/{action}", dependencies=[Depends(require_admin())])
|
|
def container_action(container_id: str, action: str):
|
|
if action not in ("start", "stop", "restart"):
|
|
raise HTTPException(status_code=400, detail="Invalid action. Must be one of: start, stop, restart")
|
|
client = get_docker_client()
|
|
c = client.containers.get(container_id)
|
|
getattr(c, action)()
|
|
return {"ok": True}
|
|
|
|
|
|
@router.get("/containers/{container_id}/logs")
|
|
def container_logs(container_id: str, tail: int = Query(200, le=10000)):
|
|
client = get_docker_client()
|
|
c = client.containers.get(container_id)
|
|
return {"logs": c.logs(tail=tail, timestamps=True).decode(errors="replace")}
|