Hub-and-Spoke Umbau: Multi-Tenant Zentrale + Satellite-Agent
- Backend: Customer/Satellite Models, customer_id auf Server/Job/Audit - Satellite-API: heartbeat, poll (atomares Claiming), logs, result, scan-result, health-report - Auth via X-Api-Key (SHA-256 gehasht) - Job-Queue: pending/claimed/running/success/failed + Stale-Janitor - Batch-Trigger: ein Job pro Server, Satellite arbeitet sequenziell ab - Credentials bleiben lokal: nur symbolische credential_ref zentral - Neues Paket satellite/: Pull-Loop, WinRM/SSH/CAU/Scanner, PyInstaller-tauglich - Frontend: Kunden-Switcher, Satelliten-View, Polling statt WebSocket - Entfernt: WebSocket/Socket.io, Redis, zentrale Credentials, JobRunner - Docs: README/AGENTS/PROMPT auf neue Architektur aktualisiert
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
"""Satellite-facing schemas (agent API)."""
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from app.models.update_job import JobType
|
||||
|
||||
|
||||
class HeartbeatRequest(BaseModel):
|
||||
version: str = Field(max_length=50)
|
||||
hostname: str = Field(max_length=255)
|
||||
|
||||
|
||||
class PollResponse(BaseModel):
|
||||
"""Jobs handed to the satellite on poll. Empty list = nothing to do."""
|
||||
|
||||
jobs: list["SatelliteJob"]
|
||||
|
||||
|
||||
class SatelliteJob(BaseModel):
|
||||
job_id: int
|
||||
type: JobType
|
||||
# Target info (absent for network scans)
|
||||
server_id: int | None = None
|
||||
server_name: str | None = None
|
||||
hostname: str | None = None
|
||||
port: int | None = None
|
||||
server_type: str | None = None
|
||||
credential_ref: str | None = None
|
||||
# Parameters
|
||||
reboot_if_required: bool = False
|
||||
scan_subnet: str | None = None
|
||||
|
||||
|
||||
class LogLine(BaseModel):
|
||||
timestamp: datetime
|
||||
level: str = "info"
|
||||
line: str
|
||||
|
||||
|
||||
class LogBatchRequest(BaseModel):
|
||||
job_id: int
|
||||
lines: list[LogLine]
|
||||
progress_percent: int | None = None
|
||||
current_phase: str | None = None
|
||||
|
||||
|
||||
class JobResultRequest(BaseModel):
|
||||
job_id: int
|
||||
status: str # "success" | "failed"
|
||||
error: str | None = None
|
||||
|
||||
|
||||
class ScanResultHost(BaseModel):
|
||||
hostname: str
|
||||
ip: str
|
||||
os_guess: str | None = None # "windows" | "linux" | None
|
||||
winrm_open: bool = False
|
||||
ssh_open: bool = False
|
||||
|
||||
|
||||
class ScanResultRequest(BaseModel):
|
||||
job_id: int
|
||||
hosts: list[ScanResultHost]
|
||||
|
||||
|
||||
class HealthReportRequest(BaseModel):
|
||||
server_id: int
|
||||
ok: bool
|
||||
message: str
|
||||
Reference in New Issue
Block a user