"""HTTP routes for Agent enrollment and bootstrap.""" from typing import Annotated from uuid import UUID from fastapi import APIRouter, Depends, HTTPException, Query, Response, status from app.agent_enrollment.dependencies import get_agent_enrollment_service from app.agent_enrollment.exceptions import ( AgentEnrollmentConflict, AgentEnrollmentNotFound, AgentEnrollmentTokenInvalid, ) from app.agent_enrollment.models import ( AgentEnrollmentCreateRequest, AgentEnrollmentCreateResponse, AgentEnrollmentListResponse, AgentEnrollRequest, AgentEnrollResponse, ) from app.agent_enrollment.service import AgentEnrollmentService from app.identity import require_permission router = APIRouter(tags=["agent-enrollment"]) EnrollmentService = Annotated[ AgentEnrollmentService, Depends(get_agent_enrollment_service), ] EnrollmentViewer = Annotated[ dict, Depends(require_permission("agents.view")), ] EnrollmentManager = Annotated[ dict, Depends(require_permission("agents.manage")), ] @router.post( "/api/agent-enrollments", response_model=AgentEnrollmentCreateResponse, status_code=status.HTTP_201_CREATED, ) def create_agent_enrollment( request: AgentEnrollmentCreateRequest, response: Response, current_user: EnrollmentManager, service: EnrollmentService, ) -> AgentEnrollmentCreateResponse: response.headers["Cache-Control"] = "no-store" try: enrollment = service.create_enrollment( request, actor_user_id=UUID(str(current_user["id"])), ) return AgentEnrollmentCreateResponse(data=enrollment) except AgentEnrollmentNotFound as exc: raise HTTPException(status_code=404, detail=str(exc)) from exc except AgentEnrollmentConflict as exc: raise HTTPException(status_code=409, detail=str(exc)) from exc @router.get( "/api/agent-enrollments", response_model=AgentEnrollmentListResponse, ) def list_agent_enrollments( current_user: EnrollmentViewer, service: EnrollmentService, site_id: UUID | None = Query(default=None), agent_zone_id: UUID | None = Query(default=None), limit: int = Query(default=100, ge=1, le=500), ) -> AgentEnrollmentListResponse: del current_user return AgentEnrollmentListResponse( data=service.list_enrollments( site_id=site_id, agent_zone_id=agent_zone_id, limit=limit, ) ) @router.post( "/api/agent/enroll", response_model=AgentEnrollResponse, status_code=status.HTTP_201_CREATED, ) def enroll_agent( request: AgentEnrollRequest, response: Response, service: EnrollmentService, ) -> AgentEnrollResponse: response.headers["Cache-Control"] = "no-store" try: return AgentEnrollResponse(data=service.redeem(request)) except AgentEnrollmentTokenInvalid as exc: raise HTTPException( status_code=401, detail="Invalid or expired enrollment token", ) from exc except AgentEnrollmentConflict as exc: raise HTTPException(status_code=409, detail=str(exc)) from exc