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
+9 -19
View File
@@ -12,7 +12,7 @@ from app.db.pool import Database
from app.dependencies import get_database
from app.vsphere import inventory
from app.vsphere.domain import vm_ops
from app.vsphere.errors import invalid_argument, not_found, unauthenticated
from app.vsphere.errors import invalid_argument, unauthenticated
from app.vsphere.rest import mappers
from app.vsphere.security.authz import require_privilege, require_read
from app.vsphere.security.session import (
@@ -200,9 +200,7 @@ async def get_vm(
database: Database = Depends(get_database),
_: SessionInfo = Depends(require_read),
) -> dict[str, Any]:
obj = await inventory.get_object(database, vm)
if obj is None or obj.type != "VirtualMachine":
raise not_found(f"VM {vm} not found")
obj = await inventory.require_object(database, vm, type_name="VirtualMachine", resource="vm")
return mappers.vm_info(obj)
@@ -286,9 +284,7 @@ async def delete_vm(
database: Database = Depends(get_database),
_: SessionInfo = Depends(require_privilege("VirtualMachine.Inventory.Delete")),
) -> Response:
obj = await inventory.get_object(database, vm)
if obj is None or obj.type != "VirtualMachine":
raise not_found(f"VM {vm} not found")
obj = await inventory.require_object(database, vm, type_name="VirtualMachine", resource="vm")
if obj.props.get("power_state") == "POWERED_ON":
raise invalid_argument("VM must be powered off before delete")
await inventory.delete_object(database, vm)
@@ -301,9 +297,7 @@ async def get_vm_power(
database: Database = Depends(get_database),
_: SessionInfo = Depends(require_read),
) -> dict[str, str]:
obj = await inventory.get_object(database, vm)
if obj is None or obj.type != "VirtualMachine":
raise not_found(f"VM {vm} not found")
obj = await inventory.require_object(database, vm, type_name="VirtualMachine", resource="vm")
state = str(obj.props.get("power_state") or "POWERED_OFF")
return {"state": state}
@@ -334,9 +328,7 @@ async def get_host(
database: Database = Depends(get_database),
_: SessionInfo = Depends(require_read),
) -> dict[str, Any]:
obj = await inventory.get_object(database, host)
if obj is None or obj.type != "HostSystem":
raise not_found(f"Host {host} not found")
obj = await inventory.require_object(database, host, type_name="HostSystem", resource="host")
return mappers.host_info(obj)
@@ -355,9 +347,9 @@ async def get_datastore(
database: Database = Depends(get_database),
_: SessionInfo = Depends(require_read),
) -> dict[str, Any]:
obj = await inventory.get_object(database, datastore)
if obj is None or obj.type != "Datastore":
raise not_found(f"Datastore {datastore} not found")
obj = await inventory.require_object(
database, datastore, type_name="Datastore", resource="datastore"
)
props = obj.props
return {
"name": obj.name,
@@ -421,9 +413,7 @@ async def vm_guest_identity(
database: Database = Depends(get_database),
_: SessionInfo = Depends(require_read),
) -> dict[str, Any]:
obj = await inventory.get_object(database, vm)
if obj is None or obj.type != "VirtualMachine":
raise not_found(f"VM {vm} not found")
obj = await inventory.require_object(database, vm, type_name="VirtualMachine", resource="vm")
return {
"name": obj.name,
"family": "LINUX",