Files
vmware-api-simulator/app/vsphere/rest/tasks.py
T

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