feat(fleet): endpoints /agents/enroll|uninstall|fleet + SQLite

Endpoints REST pour le fleet management (utilisés par installeur Inno Setup) :
  POST /api/v1/agents/enroll    -> 201 {status, machine_id, api_token, agent}
  POST /api/v1/agents/uninstall -> 200 {status, machine_id, agent}
  GET  /api/v1/agents/fleet     -> 200 {active, uninstalled, totals}

Tous protégés par Bearer token (conforme _PUBLIC_PATHS existant).

Nouveau module agent_v0/server_v1/agent_registry.py :
  - Classe AgentRegistry (sqlite3 stdlib, WAL, thread-safe via Lock)
  - CRUD + soft-delete (uninstall = status="uninstalled", historique préservé)
  - Table enrolled_agents créée via IF NOT EXISTS (pas de migration nécessaire)
  - Ré-enrollment après uninstall = réactivation auto (allow_reactivate=True)
  - Chemin DB configurable via RPA_AGENTS_DB_PATH (défaut data/databases/rpa_data.db)

Fix fixture test_stream_processor : autouse RPA_API_TOKEN dans
TestAPIEndpoints pour éviter SystemExit P0-C au module load.

13 tests intégration (enroll/uninstall/fleet + auth + edge cases).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dom
2026-04-15 09:07:19 +02:00
parent 78ee962918
commit b808e48b1f
4 changed files with 825 additions and 0 deletions

View File

@@ -6,6 +6,7 @@ Sans GPU/modèles lourds (mocks pour ScreenAnalyzer et CLIP).
"""
import json
import os
import shutil
import sys
import tempfile
@@ -457,6 +458,27 @@ class TestStreamProcessorListMethods:
class TestAPIEndpoints:
"""Tests pour les endpoints GET sessions et workflows."""
# Token de test fixe utilisé pour tous les tests d'API.
# Doit être défini AVANT le premier import de agent_v0.server_v1.api_stream
# car le module fail-closed (sys.exit 1) si RPA_API_TOKEN est absent.
_TEST_API_TOKEN = "test_token_for_api_endpoints_0123456789abcdef"
@pytest.fixture(autouse=True)
def _ensure_api_token(self, monkeypatch):
"""Garantit que RPA_API_TOKEN est défini avant l'import de api_stream.
Le module agent_v0.server_v1.api_stream applique un fail-closed P0-C
(sys.exit 1) à l'import si RPA_API_TOKEN est absent. On force donc
une valeur de test ici avant tout import lazy dans la fixture client.
"""
monkeypatch.setenv("RPA_API_TOKEN", self._TEST_API_TOKEN)
# Si api_stream est déjà chargé dans sys.modules avec un autre token
# (par ex. depuis un précédent test), on aligne sa valeur API_TOKEN
# pour que les requêtes Bearer du test passent l'auth.
api_stream_mod = sys.modules.get("agent_v0.server_v1.api_stream")
if api_stream_mod is not None:
monkeypatch.setattr(api_stream_mod, "API_TOKEN", self._TEST_API_TOKEN)
@pytest.fixture
def client(self, temp_dir):
"""Client de test FastAPI."""