cd2f27792d
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.
62 lines
1.9 KiB
Python
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}
|