cc4c3fcecb
- 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
72 lines
1.5 KiB
Python
72 lines
1.5 KiB
Python
"""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
|