86 lines
2.9 KiB
Python
86 lines
2.9 KiB
Python
"""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
|