Files
nest/uvm/routers/vms.py
T
2026-09-04 20:56:18 +00:00

71 lines
2.3 KiB
Python

"""VM lifecycle endpoints backed by the existing UVM lifecycle service."""
from __future__ import annotations
from fastapi import APIRouter, Depends, HTTPException, status
from ..api_models import DestroyResponse, VmCreateRequest, VmResponse, vm_response
from ..app import Application
from ..domain import VmSpec
from ..validation import parse_cpu, parse_password, parse_ram, parse_username
from .dependencies import get_authorized_application
router = APIRouter(prefix="/vms", tags=["vms"])
@router.get("", response_model=list[VmResponse])
def list_vms(
application: Application = Depends(get_authorized_application),
) -> list[VmResponse]:
return [
vm_response(listed.vm, observed_status=listed.observed_status)
for listed in application.lifecycle.list_vms()
]
@router.post("", response_model=VmResponse, status_code=status.HTTP_201_CREATED)
def create_vm(
request: VmCreateRequest,
application: Application = Depends(get_authorized_application),
) -> VmResponse:
vm = application.lifecycle.create(
VmSpec(
cpu=parse_cpu(str(request.cpu)),
ram_mib=parse_ram(str(request.ram)),
guest_ip=request.guest_ip,
username=parse_username(request.username),
password=parse_password(request.password.get_secret_value()),
)
)
return vm_response(vm)
@router.post("/{vm_id}/stop", response_model=VmResponse)
def stop_vm(
vm_id: str,
application: Application = Depends(get_authorized_application),
) -> VmResponse:
return vm_response(application.lifecycle.stop(vm_id))
@router.delete("/{vm_id}", response_model=DestroyResponse)
def destroy_vm(
vm_id: str,
application: Application = Depends(get_authorized_application),
) -> DestroyResponse:
vm = application.lifecycle.destroy(vm_id)
return DestroyResponse(id=vm.id)
@router.get("/{identifier}", response_model=VmResponse)
def get_vm(
identifier: str,
application: Application = Depends(get_authorized_application),
) -> VmResponse:
for listed in application.lifecycle.list_vms():
vm = listed.vm
if identifier in {vm.id, vm.guest_ip}:
return vm_response(vm, observed_status=listed.observed_status)
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="VM not found")