Refactor VM lifecycle management and enhance validation
- Introduced a new method `installed_kernel` in `ImageStore` to handle kernel verification and checksum validation. - Updated `Installer` to include additional packages: `nftables` and `conntrack`. - Refined `LifecycleService` to improve error handling and state management during VM creation, starting, stopping, and deletion. - Enhanced port management with new methods for setting and syncing ports, including validation for port rules. - Improved error handling in `StateStore` to raise specific `NotFoundError` and `ConflictError` exceptions. - Updated network management to ensure proper TAP device handling and firewall integration. - Enhanced API responses in `vms.py` to include policy status for better client-side handling. - Added validation for VM names and ports in `validation.py` to enforce stricter rules and prevent conflicts.
This commit is contained in:
+24
-11
@@ -2,12 +2,12 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from fastapi import APIRouter, Depends, 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 ..domain import PortRule, VmSpec
|
||||
from ..validation import parse_cpu, parse_name, parse_password, parse_ports, parse_ram, parse_username
|
||||
from .dependencies import get_authorized_application
|
||||
|
||||
|
||||
@@ -19,7 +19,11 @@ def list_vms(
|
||||
application: Application = Depends(get_authorized_application),
|
||||
) -> list[VmResponse]:
|
||||
return [
|
||||
vm_response(listed.vm, observed_status=listed.observed_status)
|
||||
vm_response(
|
||||
listed.vm,
|
||||
observed_status=listed.observed_status,
|
||||
policy_status=listed.policy_status,
|
||||
)
|
||||
for listed in application.lifecycle.list_vms()
|
||||
]
|
||||
|
||||
@@ -29,6 +33,9 @@ def create_vm(
|
||||
request: VmCreateRequest,
|
||||
application: Application = Depends(get_authorized_application),
|
||||
) -> VmResponse:
|
||||
ports = parse_ports([f"{rule.port}:{rule.protocol}" for rule in request.ports or ()])
|
||||
if not request.no_default_ports and not any(rule.port == 22 for rule in ports):
|
||||
ports = tuple(sorted((*ports, PortRule(22)), key=lambda rule: rule.port))
|
||||
vm = application.lifecycle.create(
|
||||
VmSpec(
|
||||
cpu=parse_cpu(str(request.cpu)),
|
||||
@@ -36,9 +43,14 @@ def create_vm(
|
||||
guest_ip=request.guest_ip,
|
||||
username=parse_username(request.username),
|
||||
password=parse_password(request.password.get_secret_value()),
|
||||
name=parse_name(request.name) if request.name is not None else None,
|
||||
ports=ports,
|
||||
)
|
||||
)
|
||||
return vm_response(vm)
|
||||
policy_status = "unmanaged" if vm.ports is None else "unknown"
|
||||
if vm.ports is not None and vm.status == "running" and vm.operation is None:
|
||||
policy_status = "enforced"
|
||||
return vm_response(vm, policy_status=policy_status)
|
||||
|
||||
|
||||
@router.post("/{vm_id}/stop", response_model=VmResponse)
|
||||
@@ -46,7 +58,7 @@ def stop_vm(
|
||||
vm_id: str,
|
||||
application: Application = Depends(get_authorized_application),
|
||||
) -> VmResponse:
|
||||
return vm_response(application.lifecycle.stop(vm_id))
|
||||
return vm_response(application.lifecycle.stop(vm_id), policy_status="inactive")
|
||||
|
||||
|
||||
@router.delete("/{vm_id}", response_model=DestroyResponse)
|
||||
@@ -63,8 +75,9 @@ 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")
|
||||
listed = application.lifecycle.inspect(identifier)
|
||||
return vm_response(
|
||||
listed.vm,
|
||||
observed_status=listed.observed_status,
|
||||
policy_status=listed.policy_status,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user