"""CIS tasks REST.""" from __future__ import annotations from typing import Any from fastapi import APIRouter, Depends, Query from app.db.pool import Database from app.dependencies import get_database from app.vsphere.domain import tasks as task_store from app.vsphere.errors import not_found from app.vsphere.security.authz import require_read from app.vsphere.security.session import SessionInfo router = APIRouter(tags=["vSphere Tasks"]) async def _ensure_seed_task(database: Database) -> list[dict[str, Any]]: tasks = await task_store.list_tasks(database) if tasks: return tasks # Fresh lab DB — ensure callers always see at least one completed task. await task_store.create_task( database, description="Lab inventory seed", service="com.vmware.vcenter", operation="seed", result={"status": "SUCCEEDED"}, ) return await task_store.list_tasks(database) @router.get("/api/cis/tasks") async def list_tasks( database: Database = Depends(get_database), _: SessionInfo = Depends(require_read), ) -> list[dict[str, Any]]: # Lab convenience: return recent Cis Task Info objects (non-empty after seed). return await _ensure_seed_task(database) @router.post("/api/cis/tasks") async def list_tasks_action( body: dict[str, Any] | None = None, action: str = Query("list"), database: Database = Depends(get_database), _: SessionInfo = Depends(require_read), ) -> dict[str, Any] | None: """Official Automation list: POST /api/cis/tasks?action=list → map id→info.""" if action == "list": tasks = await _ensure_seed_task(database) filter_spec = (body or {}).get("filter_spec") or (body or {}) wanted_tasks = set(filter_spec.get("tasks") or []) wanted_services = set(filter_spec.get("services") or []) wanted_status = set(filter_spec.get("status") or []) out: dict[str, Any] = {} for task in tasks: tid = str(task.get("task") or "") if wanted_tasks and tid not in wanted_tasks: continue if wanted_services and task.get("service") not in wanted_services: continue if wanted_status and task.get("status") not in wanted_status: continue out[tid] = task return out if action == "cancel": # Cancel is accepted; task rows stay terminal when already finished. return None from app.vsphere.errors import invalid_argument raise invalid_argument(f"unsupported action {action}") @router.get("/api/cis/tasks/{task}") async def get_task( task: str, database: Database = Depends(get_database), _: SessionInfo = Depends(require_read), ) -> dict[str, Any]: payload = await task_store.get_task(database, task) if payload is None: raise not_found(f"Task {task} not found") return payload