Keep API not-found and 401 responses usable behind Ingress and in the Web UI.

Return native JSON with the missing id in the message, clear stale sessions on
401, and document ingress-nginx annotations so branded HTML 404/405 pages do
not rewrite simulator bodies.
This commit is contained in:
2026-07-22 06:52:35 +03:00
parent 131e2e63d2
commit e8b08526d1
13 changed files with 260 additions and 62 deletions
+5 -16
View File
@@ -19,7 +19,6 @@ from app.dependencies import get_database
from app.vsphere import inventory
from app.vsphere.domain import api_state, tagging
from app.vsphere.domain import content as content_domain
from app.vsphere.errors import not_found
from app.vsphere.rest.coverage import IMPLEMENTED
from app.vsphere.security.authz import require_read
from app.vsphere.security.session import SessionInfo
@@ -61,9 +60,7 @@ async def _live_get(database: Database, template: str, concrete: str) -> Any | N
vm = params.get("vm")
if vm and "/hardware/" in template:
obj = await inventory.get_object(database, vm)
if obj is None:
raise not_found(f"VM {vm} not found")
obj = await inventory.require_object(database, vm, type_name="VirtualMachine", resource="vm")
props = obj.props or {}
def _live_list(key: str) -> list[Any] | None:
@@ -107,9 +104,7 @@ async def _live_get(database: Database, template: str, concrete: str) -> Any | N
return nic
if vm and "/guest/" in template:
obj = await inventory.get_object(database, vm)
if obj is None:
raise not_found(f"VM {vm} not found")
obj = await inventory.require_object(database, vm, type_name="VirtualMachine", resource="vm")
props = obj.props or {}
if template.endswith("/guest/local-filesystem"):
if "guest_filesystems" in props:
@@ -130,15 +125,11 @@ async def _live_get(database: Database, template: str, concrete: str) -> Any | N
host = params.get("host")
if host and template.endswith("/networking"):
obj = await inventory.get_object(database, host)
if obj is None:
raise not_found(f"Host {host} not found")
obj = await inventory.require_object(database, host, type_name="HostSystem", resource="host")
networking = (obj.props or {}).get("networking")
return networking if networking is not None else None
if host and "storage-device" in template:
obj = await inventory.get_object(database, host)
if obj is None:
raise not_found(f"Host {host} not found")
obj = await inventory.require_object(database, host, type_name="HostSystem", resource="host")
devices = (obj.props or {}).get("storage_devices")
return devices if devices is not None else None
@@ -156,9 +147,7 @@ async def _mutate_vm_hardware(
vm = params.get("vm")
if not vm or "/hardware/" not in template:
return False
obj = await inventory.get_object(database, vm)
if obj is None:
raise not_found(f"VM {vm} not found")
obj = await inventory.require_object(database, vm, type_name="VirtualMachine", resource="vm")
props = dict(obj.props or {})
if verb == "POST" and template.endswith("/hardware/cdrom"):