Skip to content

Commit

Permalink
Endpoint /confidential/initialize return json error now and proper ht…
Browse files Browse the repository at this point in the history
…tps status

return json errors for missing field
  • Loading branch information
olethanh committed Oct 8, 2024
1 parent 0aeb39e commit 90bae31
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 8 deletions.
22 changes: 17 additions & 5 deletions src/aleph/vm/orchestrator/views/operator.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
import logging
from datetime import timedelta
from http import HTTPStatus

import aiohttp.web_exceptions
import pydantic
Expand Down Expand Up @@ -187,10 +188,15 @@ async def operate_confidential_initialize(request: web.Request, authenticated_se
return web.Response(status=403, body="Unauthorized sender")

if execution.is_running:
return web.Response(status=403, body=f"VM with ref {vm_hash} already running")

return web.json_response(
{"code": "vm_running", "description": "Operation not allowed, instance already running"},
status=HTTPStatus.BAD_REQUEST,
)
if not execution.is_confidential:
return web.Response(status=403, body=f"Operation not allowed for VM {vm_hash} because it isn't confidential")
return web.json_response(
{"code": "not_confidential", "description": "Instance is not a confidential instance"},
status=HTTPStatus.BAD_REQUEST,
)

post = await request.post()

Expand All @@ -199,14 +205,20 @@ async def operate_confidential_initialize(request: web.Request, authenticated_se

session_file_content = post.get("session")
if not session_file_content:
return web.Response(status=403, body=f"Session file required for VM with ref {vm_hash}")
return web.json_response(
{"code": "field_missing", "description": "Session field is missing"},
status=HTTPStatus.BAD_REQUEST,
)

session_file_path = vm_session_path / "vm_session.b64"
session_file_path.write_bytes(session_file_content.file.read())

godh_file_content = post.get("godh")
if not godh_file_content:
return web.Response(status=403, body=f"GODH file required for VM with ref {vm_hash}")
return web.json_response(
{"code": "field_missing", "description": "godh field is missing. Please provide a GODH file"},
status=HTTPStatus.BAD_REQUEST,
)

godh_file_path = vm_session_path / "vm_godh.b64"
godh_file_path.write_bytes(godh_file_content.file.read())
Expand Down
52 changes: 49 additions & 3 deletions tests/supervisor/views/test_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,59 @@ async def test_operator_confidential_initialize_already_running(aiohttp_client,
)
app = setup_webapp()
app["vm_pool"] = fake_vm_pool
client = await aiohttp_client(app)
client: TestClient = await aiohttp_client(app)
response = await client.post(
f"/control/machine/{vm_hash}/confidential/initialize",
json={"persistent_vms": []},
)
assert response.status == 403
assert await response.text() == f"VM with ref {vm_hash} already running"
assert response.status == 400
assert response.content_type == "application/json"
assert await response.json() == {
"code": "vm_running",
"description": "Operation not allowed, instance already running",
}


@pytest.mark.asyncio
async def test_operator_confidential_initialize_not_confidential(aiohttp_client, mocker):
"""Test that the confidential initialize endpoint rejects if the VM is not confidential"""

settings.ENABLE_QEMU_SUPPORT = True
settings.ENABLE_CONFIDENTIAL_COMPUTING = True
settings.setup()

vm_hash = ItemHash(settings.FAKE_INSTANCE_ID)
instance_message = await get_message(ref=vm_hash)

fake_vm_pool = mocker.Mock(
executions={
vm_hash: mocker.Mock(
vm_hash=vm_hash,
message=instance_message.content,
is_confidential=False,
is_running=False,
),
},
)

# Disable auth
mocker.patch(
"aleph.vm.orchestrator.views.authentication.authenticate_jwk",
return_value=instance_message.sender,
)
app = setup_webapp()
app["vm_pool"] = fake_vm_pool
client: TestClient = await aiohttp_client(app)
response = await client.post(
f"/control/machine/{vm_hash}/confidential/initialize",
json={"persistent_vms": []},
)
assert response.status == 400
assert response.content_type == "application/json"
assert await response.json() == {
"code": "not_confidential",
"description": "Instance is not a confidential instance",
}


@pytest.mark.asyncio
Expand Down

0 comments on commit 90bae31

Please sign in to comment.