Files
security-alert-center/backend/app/api/v1/agent.py
T
PTah cd2f27792d feat: agent updates from SAC, poll config, SSH/WinRM fallback (0.12.0)
Add agent update settings, pending self-update via poll, desired config per host, and automatic or manual SSH/WinRM fallback when agents do not report agent.update events.
2026-06-20 15:52:10 +10:00

62 lines
1.9 KiB
Python

from typing import Any
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from app.auth.api_key import get_api_key_auth
from app.database import get_db
from app.services.agent_commands import (
complete_command,
resolve_host_by_agent_instance_id,
)
from app.services.agent_poll import build_agent_poll_payload
router = APIRouter(prefix="/agent", tags=["agent"])
class AgentCommandResultBody(BaseModel):
status: str = Field(pattern="^(completed|failed)$")
stdout: str | None = None
stderr: str | None = None
class AgentCommandsPollResponse(BaseModel):
config_revision: int = 0
config: dict[str, Any] = Field(default_factory=dict)
update: dict[str, Any] = Field(default_factory=dict)
commands: list[dict[str, Any]] = Field(default_factory=list)
@router.get("/commands", response_model=AgentCommandsPollResponse)
def poll_agent_commands(
agent_instance_id: str = Query(..., min_length=1),
db: Session = Depends(get_db),
_api_key: str = Depends(get_api_key_auth),
) -> AgentCommandsPollResponse:
host = resolve_host_by_agent_instance_id(db, agent_instance_id)
if host is None:
raise HTTPException(status_code=404, detail="Unknown agent_instance_id")
payload = build_agent_poll_payload(db, host)
return AgentCommandsPollResponse(**payload)
@router.post("/commands/{command_uuid}/result")
def post_agent_command_result(
command_uuid: str,
body: AgentCommandResultBody,
db: Session = Depends(get_db),
_api_key: str = Depends(get_api_key_auth),
) -> dict[str, str]:
cmd = complete_command(
db,
command_uuid,
status=body.status,
stdout=body.stdout,
stderr=body.stderr,
)
if cmd is None:
raise HTTPException(status_code=404, detail="Command not found")
db.commit()
return {"status": cmd.status, "command_uuid": cmd.command_uuid}