diff --git a/gns3server/api/routes/compute/atm_switch_nodes.py b/gns3server/api/routes/compute/atm_switch_nodes.py index 44dbc57a..4dcab777 100644 --- a/gns3server/api/routes/compute/atm_switch_nodes.py +++ b/gns3server/api/routes/compute/atm_switch_nodes.py @@ -20,7 +20,7 @@ API routes for ATM switch nodes. import os -from fastapi import APIRouter, Depends, Body, Path, status +from fastapi import APIRouter, Depends, Body, Path, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from uuid import UUID @@ -109,42 +109,43 @@ async def update_atm_switch( @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_atm_switch_node(node: ATMSwitch = Depends(dep_node)) -> None: +async def delete_atm_switch_node(node: ATMSwitch = Depends(dep_node)) -> Response: """ Delete an ATM switch node. """ await Dynamips.instance().delete_node(node.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -def start_atm_switch(node: ATMSwitch = Depends(dep_node)): +def start_atm_switch(node: ATMSwitch = Depends(dep_node)) -> Response: """ Start an ATM switch node. This endpoint results in no action since ATM switch nodes are always on. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -def stop_atm_switch(node: ATMSwitch = Depends(dep_node)) -> None: +def stop_atm_switch(node: ATMSwitch = Depends(dep_node)) -> Response: """ Stop an ATM switch node. This endpoint results in no action since ATM switch nodes are always on. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -def suspend_atm_switch(node: ATMSwitch = Depends(dep_node)) -> None: +def suspend_atm_switch(node: ATMSwitch = Depends(dep_node)) -> Response: """ Suspend an ATM switch node. This endpoint results in no action since ATM switch nodes are always on. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -170,7 +171,7 @@ async def create_nio( @router.delete("/{node_id}/adapters/{adapter_number}/ports/{port_number}/nio", status_code=status.HTTP_204_NO_CONTENT) -async def delete_nio(adapter_number: int, port_number: int, node: ATMSwitch = Depends(dep_node)) -> None: +async def delete_nio(adapter_number: int, port_number: int, node: ATMSwitch = Depends(dep_node)) -> Response: """ Remove a NIO (Network Input/Output) from the node. The adapter number on the switch is always 0. @@ -178,6 +179,7 @@ async def delete_nio(adapter_number: int, port_number: int, node: ATMSwitch = De nio = await node.remove_nio(port_number) await nio.delete() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -207,13 +209,14 @@ async def stop_capture( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: ATMSwitch = Depends(dep_node) -) -> None: +) -> Response: """ Stop a packet capture on the node. The adapter number on the switch is always 0. """ await node.stop_capture(port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream") diff --git a/gns3server/api/routes/compute/cloud_nodes.py b/gns3server/api/routes/compute/cloud_nodes.py index 65ad686f..5ec5ea00 100644 --- a/gns3server/api/routes/compute/cloud_nodes.py +++ b/gns3server/api/routes/compute/cloud_nodes.py @@ -20,7 +20,7 @@ API routes for cloud nodes. import os -from fastapi import APIRouter, Depends, Path, status +from fastapi import APIRouter, Depends, Path, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from typing import Union @@ -99,41 +99,43 @@ def update_cloud(node_data: schemas.CloudUpdate, node: Cloud = Depends(dep_node) @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_cloud(node: Cloud = Depends(dep_node)) -> None: +async def delete_cloud(node: Cloud = Depends(dep_node)) -> Response: """ Delete a cloud node. """ await Builtin.instance().delete_node(node.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -async def start_cloud(node: Cloud = Depends(dep_node)) -> None: +async def start_cloud(node: Cloud = Depends(dep_node)) -> Response: """ Start a cloud node. """ await node.start() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -async def stop_cloud(node: Cloud = Depends(dep_node)) -> None: +async def stop_cloud(node: Cloud = Depends(dep_node)) -> Response: """ Stop a cloud node. This endpoint results in no action since cloud nodes cannot be stopped. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -async def suspend_cloud(node: Cloud = Depends(dep_node)) -> None: +async def suspend_cloud(node: Cloud = Depends(dep_node)) -> Response: """ Suspend a cloud node. This endpoint results in no action since cloud nodes cannot be suspended. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -188,13 +190,14 @@ async def delete_cloud_nio( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: Cloud = Depends(dep_node) -) -> None: +) -> Response: """ Remove a NIO (Network Input/Output) from the node. The adapter number on the cloud is always 0. """ await node.remove_nio(port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -223,13 +226,14 @@ async def stop_cloud_capture( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: Cloud = Depends(dep_node) -) -> None: +) -> Response: """ Stop a packet capture on the node. The adapter number on the cloud is always 0. """ await node.stop_capture(port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap") diff --git a/gns3server/api/routes/compute/compute.py b/gns3server/api/routes/compute/compute.py index d97ab3f2..518f7441 100644 --- a/gns3server/api/routes/compute/compute.py +++ b/gns3server/api/routes/compute/compute.py @@ -34,7 +34,7 @@ from gns3server.compute.virtualbox import VirtualBox from gns3server.compute.vmware import VMware from gns3server import schemas -from fastapi import APIRouter, HTTPException, Body, status +from fastapi import APIRouter, HTTPException, Body, Response, status from fastapi.encoders import jsonable_encoder from uuid import UUID from typing import Optional, List @@ -150,7 +150,7 @@ async def get_qemu_capabilities() -> dict: status_code=status.HTTP_204_NO_CONTENT, responses={403: {"model": schemas.ErrorMessage, "description": "Forbidden to create Qemu image"}}, ) -async def create_qemu_image(image_data: schemas.QemuImageCreate) -> None: +async def create_qemu_image(image_data: schemas.QemuImageCreate) -> Response: """ Create a Qemu image. """ @@ -163,13 +163,15 @@ async def create_qemu_image(image_data: schemas.QemuImageCreate) -> None: image_data.qemu_img, image_data.path, jsonable_encoder(image_data, exclude_unset=True) ) + return Response(status_code=status.HTTP_204_NO_CONTENT) + @router.put( "/qemu/img", status_code=status.HTTP_204_NO_CONTENT, responses={403: {"model": schemas.ErrorMessage, "description": "Forbidden to update Qemu image"}}, ) -async def update_qemu_image(image_data: schemas.QemuImageUpdate) -> None: +async def update_qemu_image(image_data: schemas.QemuImageUpdate) -> Response: """ Update a Qemu image. """ @@ -181,6 +183,8 @@ async def update_qemu_image(image_data: schemas.QemuImageUpdate) -> None: if image_data.extend: await Qemu.instance().resize_disk(image_data.qemu_img, image_data.path, image_data.extend) + return Response(status_code=status.HTTP_204_NO_CONTENT) + @router.get("/virtualbox/vms", response_model=List[dict]) async def get_virtualbox_vms() -> List[dict]: diff --git a/gns3server/api/routes/compute/docker_nodes.py b/gns3server/api/routes/compute/docker_nodes.py index 042f2312..61426730 100644 --- a/gns3server/api/routes/compute/docker_nodes.py +++ b/gns3server/api/routes/compute/docker_nodes.py @@ -20,7 +20,7 @@ API routes for Docker nodes. import os -from fastapi import APIRouter, WebSocket, Depends, Body, status +from fastapi import APIRouter, WebSocket, Depends, Body, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from uuid import UUID @@ -132,66 +132,73 @@ async def update_docker_node(node_data: schemas.DockerUpdate, node: DockerVM = D @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -async def start_docker_node(node: DockerVM = Depends(dep_node)) -> None: +async def start_docker_node(node: DockerVM = Depends(dep_node)) -> Response: """ Start a Docker node. """ await node.start() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -async def stop_docker_node(node: DockerVM = Depends(dep_node)) -> None: +async def stop_docker_node(node: DockerVM = Depends(dep_node)) -> Response: """ Stop a Docker node. """ await node.stop() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -async def suspend_docker_node(node: DockerVM = Depends(dep_node)) -> None: +async def suspend_docker_node(node: DockerVM = Depends(dep_node)) -> Response: """ Suspend a Docker node. """ await node.pause() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT) -async def reload_docker_node(node: DockerVM = Depends(dep_node)) -> None: +async def reload_docker_node(node: DockerVM = Depends(dep_node)) -> Response: """ Reload a Docker node. """ await node.restart() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/pause", status_code=status.HTTP_204_NO_CONTENT) -async def pause_docker_node(node: DockerVM = Depends(dep_node)) -> None: +async def pause_docker_node(node: DockerVM = Depends(dep_node)) -> Response: """ Pause a Docker node. """ await node.pause() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/unpause", status_code=status.HTTP_204_NO_CONTENT) -async def unpause_docker_node(node: DockerVM = Depends(dep_node)) -> None: +async def unpause_docker_node(node: DockerVM = Depends(dep_node)) -> Response: """ Unpause a Docker node. """ await node.unpause() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_docker_node(node: DockerVM = Depends(dep_node)) -> None: +async def delete_docker_node(node: DockerVM = Depends(dep_node)) -> Response: """ Delete a Docker node. """ await node.delete() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/duplicate", response_model=schemas.Docker, status_code=status.HTTP_201_CREATED) @@ -250,13 +257,14 @@ async def delete_docker_node_nio( adapter_number: int, port_number: int, node: DockerVM = Depends(dep_node) -) -> None: +) -> Response: """ Delete a NIO (Network Input/Output) from the node. The port number on the Docker node is always 0. """ await node.adapter_remove_nio_binding(adapter_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -284,13 +292,14 @@ async def stop_docker_node_capture( adapter_number: int, port_number: int, node: DockerVM = Depends(dep_node) -) -> None: +) -> Response: """ Stop a packet capture on the node. The port number on the Docker node is always 0. """ await node.stop_capture(adapter_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream") @@ -319,6 +328,7 @@ async def console_ws(websocket: WebSocket, node: DockerVM = Depends(dep_node)) - @router.post("/{node_id}/console/reset", status_code=status.HTTP_204_NO_CONTENT) -async def reset_console(node: DockerVM = Depends(dep_node)) -> None: +async def reset_console(node: DockerVM = Depends(dep_node)) -> Response: await node.reset_console() + return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/gns3server/api/routes/compute/dynamips_nodes.py b/gns3server/api/routes/compute/dynamips_nodes.py index 81317fd6..981dd282 100644 --- a/gns3server/api/routes/compute/dynamips_nodes.py +++ b/gns3server/api/routes/compute/dynamips_nodes.py @@ -21,7 +21,7 @@ API routes for Dynamips nodes. import os import sys -from fastapi import APIRouter, WebSocket, Depends, status +from fastapi import APIRouter, WebSocket, Depends, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from typing import List @@ -105,16 +105,17 @@ async def update_router(node_data: schemas.DynamipsUpdate, node: Router = Depend @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_router(node: Router = Depends(dep_node)) -> None: +async def delete_router(node: Router = Depends(dep_node)) -> Response: """ Delete a Dynamips router. """ await Dynamips.instance().delete_node(node.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -async def start_router(node: Router = Depends(dep_node)) -> None: +async def start_router(node: Router = Depends(dep_node)) -> Response: """ Start a Dynamips router. """ @@ -124,39 +125,44 @@ async def start_router(node: Router = Depends(dep_node)) -> None: except GeneratorExit: pass await node.start() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -async def stop_router(node: Router = Depends(dep_node)) -> None: +async def stop_router(node: Router = Depends(dep_node)) -> Response: """ Stop a Dynamips router. """ await node.stop() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -async def suspend_router(node: Router = Depends(dep_node)) -> None: +async def suspend_router(node: Router = Depends(dep_node)) -> Response: await node.suspend() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/resume", status_code=status.HTTP_204_NO_CONTENT) -async def resume_router(node: Router = Depends(dep_node)) -> None: +async def resume_router(node: Router = Depends(dep_node)) -> Response: """ Resume a suspended Dynamips router. """ await node.resume() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT) -async def reload_router(node: Router = Depends(dep_node)) -> None: +async def reload_router(node: Router = Depends(dep_node)) -> Response: """ Reload a suspended Dynamips router. """ await node.reload() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -202,13 +208,14 @@ async def update_nio( @router.delete("/{node_id}/adapters/{adapter_number}/ports/{port_number}/nio", status_code=status.HTTP_204_NO_CONTENT) -async def delete_nio(adapter_number: int, port_number: int, node: Router = Depends(dep_node)) -> None: +async def delete_nio(adapter_number: int, port_number: int, node: Router = Depends(dep_node)) -> Response: """ Delete a NIO (Network Input/Output) from the node. """ nio = await node.slot_remove_nio_binding(adapter_number, port_number) await nio.delete() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -240,12 +247,13 @@ async def start_capture( @router.post( "/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop", status_code=status.HTTP_204_NO_CONTENT ) -async def stop_capture(adapter_number: int, port_number: int, node: Router = Depends(dep_node)) -> None: +async def stop_capture(adapter_number: int, port_number: int, node: Router = Depends(dep_node)) -> Response: """ Stop a packet capture on the node. """ await node.stop_capture(adapter_number, port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream") @@ -303,6 +311,7 @@ async def console_ws(websocket: WebSocket, node: Router = Depends(dep_node)) -> @router.post("/{node_id}/console/reset", status_code=status.HTTP_204_NO_CONTENT) -async def reset_console(node: Router = Depends(dep_node)) -> None: +async def reset_console(node: Router = Depends(dep_node)) -> Response: await node.reset_console() + return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/gns3server/api/routes/compute/ethernet_hub_nodes.py b/gns3server/api/routes/compute/ethernet_hub_nodes.py index 783cd397..fe7999ee 100644 --- a/gns3server/api/routes/compute/ethernet_hub_nodes.py +++ b/gns3server/api/routes/compute/ethernet_hub_nodes.py @@ -20,7 +20,7 @@ API routes for Ethernet hub nodes. import os -from fastapi import APIRouter, Depends, Body, Path, status +from fastapi import APIRouter, Depends, Body, Path, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from uuid import UUID @@ -108,42 +108,43 @@ async def update_ethernet_hub( @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> None: +async def delete_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> Response: """ Delete an Ethernet hub. """ await Dynamips.instance().delete_node(node.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -def start_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> None: +def start_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> Response: """ Start an Ethernet hub. This endpoint results in no action since Ethernet hub nodes are always on. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -def stop_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> None: +def stop_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> Response: """ Stop an Ethernet hub. This endpoint results in no action since Ethernet hub nodes are always on. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -def suspend_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> None: +def suspend_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> Response: """ Suspend an Ethernet hub. This endpoint results in no action since Ethernet hub nodes are always on. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -174,7 +175,7 @@ async def delete_nio( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: EthernetHub = Depends(dep_node) -) -> None: +) -> Response: """ Delete a NIO (Network Input/Output) from the node. The adapter number on the hub is always 0. @@ -182,6 +183,7 @@ async def delete_nio( nio = await node.remove_nio(port_number) await nio.delete() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -210,13 +212,14 @@ async def stop_capture( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: EthernetHub = Depends(dep_node) -) -> None: +) -> Response: """ Stop a packet capture on the node. The adapter number on the hub is always 0. """ await node.stop_capture(port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream") diff --git a/gns3server/api/routes/compute/ethernet_switch_nodes.py b/gns3server/api/routes/compute/ethernet_switch_nodes.py index 3375dd19..d3ca028b 100644 --- a/gns3server/api/routes/compute/ethernet_switch_nodes.py +++ b/gns3server/api/routes/compute/ethernet_switch_nodes.py @@ -20,7 +20,7 @@ API routes for Ethernet switch nodes. import os -from fastapi import APIRouter, Depends, Body, Path, status +from fastapi import APIRouter, Depends, Body, Path, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from uuid import UUID @@ -112,42 +112,43 @@ async def update_ethernet_switch( @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> None: +async def delete_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> Response: """ Delete an Ethernet switch. """ await Dynamips.instance().delete_node(node.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -def start_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> None: +def start_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> Response: """ Start an Ethernet switch. This endpoint results in no action since Ethernet switch nodes are always on. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -def stop_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> None: +def stop_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> Response: """ Stop an Ethernet switch. This endpoint results in no action since Ethernet switch nodes are always on. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -def suspend_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> None: +def suspend_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> Response: """ Suspend an Ethernet switch. This endpoint results in no action since Ethernet switch nodes are always on. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -174,7 +175,7 @@ async def delete_nio( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: EthernetSwitch = Depends(dep_node) -) -> None: +) -> Response: """ Delete a NIO (Network Input/Output) from the node. The adapter number on the switch is always 0. @@ -182,6 +183,7 @@ async def delete_nio( nio = await node.remove_nio(port_number) await nio.delete() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -210,13 +212,14 @@ async def stop_capture( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: EthernetSwitch = Depends(dep_node) -) -> None: +) -> Response: """ Stop a packet capture on the node. The adapter number on the switch is always 0. """ await node.stop_capture(port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream") diff --git a/gns3server/api/routes/compute/frame_relay_switch_nodes.py b/gns3server/api/routes/compute/frame_relay_switch_nodes.py index d0ea5537..9d0f61ce 100644 --- a/gns3server/api/routes/compute/frame_relay_switch_nodes.py +++ b/gns3server/api/routes/compute/frame_relay_switch_nodes.py @@ -20,7 +20,7 @@ API routes for Frame Relay switch nodes. import os -from fastapi import APIRouter, Depends, Body, Path, status +from fastapi import APIRouter, Depends, Body, Path, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from uuid import UUID @@ -112,42 +112,43 @@ async def update_frame_relay_switch( @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> None: +async def delete_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> Response: """ Delete a Frame Relay switch node. """ await Dynamips.instance().delete_node(node.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -def start_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> None: +def start_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> Response: """ Start a Frame Relay switch node. This endpoint results in no action since Frame Relay switch nodes are always on. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -def stop_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> None: +def stop_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> Response: """ Stop a Frame Relay switch node. This endpoint results in no action since Frame Relay switch nodes are always on. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -def suspend_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> None: +def suspend_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> Response: """ Suspend a Frame Relay switch node. This endpoint results in no action since Frame Relay switch nodes are always on. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -178,7 +179,7 @@ async def delete_nio( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: FrameRelaySwitch = Depends(dep_node) -) -> None: +) -> Response: """ Remove a NIO (Network Input/Output) from the node. The adapter number on the switch is always 0. @@ -186,6 +187,7 @@ async def delete_nio( nio = await node.remove_nio(port_number) await nio.delete() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -214,13 +216,14 @@ async def stop_capture( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: FrameRelaySwitch = Depends(dep_node) -) -> None: +) -> Response: """ Stop a packet capture on the node. The adapter number on the switch is always 0. """ await node.stop_capture(port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream") diff --git a/gns3server/api/routes/compute/images.py b/gns3server/api/routes/compute/images.py index e556c1d3..1d185949 100644 --- a/gns3server/api/routes/compute/images.py +++ b/gns3server/api/routes/compute/images.py @@ -21,7 +21,7 @@ API routes for images. import os import urllib.parse -from fastapi import APIRouter, Request, status, HTTPException +from fastapi import APIRouter, Request, status, Response, HTTPException from fastapi.responses import FileResponse from typing import List @@ -54,13 +54,14 @@ async def get_dynamips_images() -> List[str]: @router.post("/dynamips/images/{filename:path}", status_code=status.HTTP_204_NO_CONTENT) -async def upload_dynamips_image(filename: str, request: Request) -> None: +async def upload_dynamips_image(filename: str, request: Request) -> Response: """ Upload a Dynamips IOS image. """ dynamips_manager = Dynamips.instance() await dynamips_manager.write_image(urllib.parse.unquote(filename), request.stream()) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/dynamips/images/{filename:path}") @@ -95,13 +96,14 @@ async def get_iou_images() -> List[str]: @router.post("/iou/images/{filename:path}", status_code=status.HTTP_204_NO_CONTENT) -async def upload_iou_image(filename: str, request: Request) -> None: +async def upload_iou_image(filename: str, request: Request) -> Response: """ Upload an IOU image. """ iou_manager = IOU.instance() await iou_manager.write_image(urllib.parse.unquote(filename), request.stream()) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/iou/images/{filename:path}") @@ -132,10 +134,11 @@ async def get_qemu_images() -> List[str]: @router.post("/qemu/images/{filename:path}", status_code=status.HTTP_204_NO_CONTENT) -async def upload_qemu_image(filename: str, request: Request) -> None: +async def upload_qemu_image(filename: str, request: Request) -> Response: qemu_manager = Qemu.instance() await qemu_manager.write_image(urllib.parse.unquote(filename), request.stream()) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/qemu/images/{filename:path}") diff --git a/gns3server/api/routes/compute/iou_nodes.py b/gns3server/api/routes/compute/iou_nodes.py index 1234c10d..35d4f067 100644 --- a/gns3server/api/routes/compute/iou_nodes.py +++ b/gns3server/api/routes/compute/iou_nodes.py @@ -20,7 +20,7 @@ API routes for IOU nodes. import os -from fastapi import APIRouter, WebSocket, Depends, Body, status +from fastapi import APIRouter, WebSocket, Depends, Body, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from typing import Union @@ -113,12 +113,13 @@ async def update_iou_node(node_data: schemas.IOUUpdate, node: IOUVM = Depends(de @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_iou_node(node: IOUVM = Depends(dep_node)) -> None: +async def delete_iou_node(node: IOUVM = Depends(dep_node)) -> Response: """ Delete an IOU node. """ await IOU.instance().delete_node(node.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/duplicate", response_model=schemas.IOU, status_code=status.HTTP_201_CREATED) @@ -135,7 +136,7 @@ async def duplicate_iou_node( @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -async def start_iou_node(start_data: schemas.IOUStart, node: IOUVM = Depends(dep_node)) -> None: +async def start_iou_node(start_data: schemas.IOUStart, node: IOUVM = Depends(dep_node)) -> Response: """ Start an IOU node. """ @@ -146,35 +147,37 @@ async def start_iou_node(start_data: schemas.IOUStart, node: IOUVM = Depends(dep setattr(node, name, value) await node.start() - return node.asdict() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -async def stop_iou_node(node: IOUVM = Depends(dep_node)) -> None: +async def stop_iou_node(node: IOUVM = Depends(dep_node)) -> Response: """ Stop an IOU node. """ await node.stop() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -def suspend_iou_node(node: IOUVM = Depends(dep_node)) -> None: +def suspend_iou_node(node: IOUVM = Depends(dep_node)) -> Response: """ Suspend an IOU node. Does nothing since IOU doesn't support being suspended. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT) -async def reload_iou_node(node: IOUVM = Depends(dep_node)) -> None: +async def reload_iou_node(node: IOUVM = Depends(dep_node)) -> Response: """ Reload an IOU node. """ await node.reload() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -220,12 +223,13 @@ async def update_iou_node_nio( @router.delete("/{node_id}/adapters/{adapter_number}/ports/{port_number}/nio", status_code=status.HTTP_204_NO_CONTENT) -async def delete_iou_node_nio(adapter_number: int, port_number: int, node: IOUVM = Depends(dep_node)) -> None: +async def delete_iou_node_nio(adapter_number: int, port_number: int, node: IOUVM = Depends(dep_node)) -> Response: """ Delete a NIO (Network Input/Output) from the node. """ await node.adapter_remove_nio_binding(adapter_number, port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -247,12 +251,13 @@ async def start_iou_node_capture( @router.post( "/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop", status_code=status.HTTP_204_NO_CONTENT ) -async def stop_iou_node_capture(adapter_number: int, port_number: int, node: IOUVM = Depends(dep_node)) -> None: +async def stop_iou_node_capture(adapter_number: int, port_number: int, node: IOUVM = Depends(dep_node)) -> Response: """ Stop a packet capture on the node. """ await node.stop_capture(adapter_number, port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream") @@ -280,6 +285,7 @@ async def console_ws(websocket: WebSocket, node: IOUVM = Depends(dep_node)) -> N @router.post("/{node_id}/console/reset", status_code=status.HTTP_204_NO_CONTENT) -async def reset_console(node: IOUVM = Depends(dep_node)) -> None: +async def reset_console(node: IOUVM = Depends(dep_node)) -> Response: await node.reset_console() + return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/gns3server/api/routes/compute/nat_nodes.py b/gns3server/api/routes/compute/nat_nodes.py index c15f9225..8a0e930c 100644 --- a/gns3server/api/routes/compute/nat_nodes.py +++ b/gns3server/api/routes/compute/nat_nodes.py @@ -20,7 +20,7 @@ API routes for NAT nodes. import os -from fastapi import APIRouter, Depends, Path, status +from fastapi import APIRouter, Depends, Path, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from typing import Union @@ -94,41 +94,43 @@ def update_nat_node(node_data: schemas.NATUpdate, node: Nat = Depends(dep_node)) @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_nat_node(node: Nat = Depends(dep_node)) -> None: +async def delete_nat_node(node: Nat = Depends(dep_node)) -> Response: """ Delete a cloud node. """ await Builtin.instance().delete_node(node.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -async def start_nat_node(node: Nat = Depends(dep_node)) -> None: +async def start_nat_node(node: Nat = Depends(dep_node)) -> Response: """ Start a NAT node. """ await node.start() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -async def stop_nat_node(node: Nat = Depends(dep_node)) -> None: +async def stop_nat_node(node: Nat = Depends(dep_node)) -> Response: """ Stop a NAT node. This endpoint results in no action since cloud nodes cannot be stopped. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -async def suspend_nat_node(node: Nat = Depends(dep_node)) -> None: +async def suspend_nat_node(node: Nat = Depends(dep_node)) -> Response: """ Suspend a NAT node. This endpoint results in no action since NAT nodes cannot be suspended. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -183,13 +185,14 @@ async def delete_nat_node_nio( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: Nat = Depends(dep_node) -) -> None: +) -> Response: """ Remove a NIO (Network Input/Output) from the node. The adapter number on the cloud is always 0. """ await node.remove_nio(port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -218,13 +221,14 @@ async def stop_nat_node_capture( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: Nat = Depends(dep_node) -): +) -> Response: """ Stop a packet capture on the node. The adapter number on the cloud is always 0. """ await node.stop_capture(port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream") diff --git a/gns3server/api/routes/compute/projects.py b/gns3server/api/routes/compute/projects.py index a1ddbfc4..c35cbbe4 100644 --- a/gns3server/api/routes/compute/projects.py +++ b/gns3server/api/routes/compute/projects.py @@ -25,7 +25,7 @@ import logging log = logging.getLogger() -from fastapi import APIRouter, Depends, HTTPException, Request, status +from fastapi import APIRouter, Depends, HTTPException, Request, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import FileResponse from typing import List @@ -103,7 +103,7 @@ def get_compute_project(project: Project = Depends(dep_project)) -> schemas.Proj @router.post("/projects/{project_id}/close", status_code=status.HTTP_204_NO_CONTENT) -async def close_compute_project(project: Project = Depends(dep_project)) -> None: +async def close_compute_project(project: Project = Depends(dep_project)) -> Response: """ Close a project on the compute. """ @@ -118,17 +118,18 @@ async def close_compute_project(project: Project = Depends(dep_project)) -> None pass else: log.warning("Skip project closing, another client is listening for project notifications") + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.delete("/projects/{project_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_compute_project(project: Project = Depends(dep_project)) -> None: +async def delete_compute_project(project: Project = Depends(dep_project)) -> Response: """ Delete project from the compute. """ await project.delete() ProjectManager.instance().remove_project(project.id) - + return Response(status_code=status.HTTP_204_NO_CONTENT) # @Route.get( # r"/projects/{project_id}/notifications", @@ -214,7 +215,11 @@ async def get_compute_project_file(file_path: str, project: Project = Depends(de @router.post("/projects/{project_id}/files/{file_path:path}", status_code=status.HTTP_204_NO_CONTENT) -async def write_compute_project_file(file_path: str, request: Request, project: Project = Depends(dep_project)) -> None: +async def write_compute_project_file( + file_path: str, + request: Request, + project: Project = Depends(dep_project) +) -> Response: file_path = urllib.parse.unquote(file_path) path = os.path.normpath(file_path) @@ -238,3 +243,5 @@ async def write_compute_project_file(file_path: str, request: Request, project: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) except PermissionError: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN) + + return Response(status_code=status.HTTP_204_NO_CONTENT) \ No newline at end of file diff --git a/gns3server/api/routes/compute/qemu_nodes.py b/gns3server/api/routes/compute/qemu_nodes.py index 30bb2eef..66ce046a 100644 --- a/gns3server/api/routes/compute/qemu_nodes.py +++ b/gns3server/api/routes/compute/qemu_nodes.py @@ -20,7 +20,7 @@ API routes for Qemu nodes. import os -from fastapi import APIRouter, WebSocket, Depends, Body, Path, status +from fastapi import APIRouter, WebSocket, Depends, Body, Path, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from uuid import UUID @@ -104,12 +104,13 @@ async def update_qemu_node(node_data: schemas.QemuUpdate, node: QemuVM = Depends @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_qemu_node(node: QemuVM = Depends(dep_node)) -> None: +async def delete_qemu_node(node: QemuVM = Depends(dep_node)) -> Response: """ Delete a Qemu node. """ await Qemu.instance().delete_node(node.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/duplicate", response_model=schemas.Qemu, status_code=status.HTTP_201_CREATED) @@ -126,13 +127,14 @@ async def duplicate_qemu_node( @router.post("/{node_id}/resize_disk", status_code=status.HTTP_204_NO_CONTENT) -async def resize_qemu_node_disk(node_data: schemas.QemuDiskResize, node: QemuVM = Depends(dep_node)) -> None: +async def resize_qemu_node_disk(node_data: schemas.QemuDiskResize, node: QemuVM = Depends(dep_node)) -> Response: await node.resize_disk(node_data.drive_name, node_data.extend) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -async def start_qemu_node(node: QemuVM = Depends(dep_node)) -> None: +async def start_qemu_node(node: QemuVM = Depends(dep_node)) -> Response: """ Start a Qemu node. """ @@ -145,42 +147,47 @@ async def start_qemu_node(node: QemuVM = Depends(dep_node)) -> None: pass # FIXME: check this # raise ComputeError("Cannot start VM with hardware acceleration (KVM/HAX) enabled because hardware virtualization (VT-x/AMD-V) is already used by another software like VMware or VirtualBox") await node.start() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -async def stop_qemu_node(node: QemuVM = Depends(dep_node)) -> None: +async def stop_qemu_node(node: QemuVM = Depends(dep_node)) -> Response: """ Stop a Qemu node. """ await node.stop() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT) -async def reload_qemu_node(node: QemuVM = Depends(dep_node)) -> None: +async def reload_qemu_node(node: QemuVM = Depends(dep_node)) -> Response: """ Reload a Qemu node. """ await node.reload() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -async def suspend_qemu_node(node: QemuVM = Depends(dep_node)) -> None: +async def suspend_qemu_node(node: QemuVM = Depends(dep_node)) -> Response: """ Suspend a Qemu node. """ await node.suspend() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/resume", status_code=status.HTTP_204_NO_CONTENT) -async def resume_qemu_node(node: QemuVM = Depends(dep_node)) -> None: +async def resume_qemu_node(node: QemuVM = Depends(dep_node)) -> Response: """ Resume a Qemu node. """ await node.resume() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -236,13 +243,14 @@ async def delete_qemu_node_nio( adapter_number: int, port_number: int = Path(..., ge=0, le=0), node: QemuVM = Depends(dep_node) -) -> None: +) -> Response: """ Delete a NIO (Network Input/Output) from the node. The port number on the Qemu node is always 0. """ await node.adapter_remove_nio_binding(adapter_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -270,13 +278,14 @@ async def stop_qemu_node_capture( adapter_number: int, port_number: int = Path(..., ge=0, le=0), node: QemuVM = Depends(dep_node) -) -> None: +) -> Response: """ Stop a packet capture on the node. The port number on the Qemu node is always 0. """ await node.stop_capture(adapter_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream") @@ -304,6 +313,7 @@ async def console_ws(websocket: WebSocket, node: QemuVM = Depends(dep_node)) -> @router.post("/{node_id}/console/reset", status_code=status.HTTP_204_NO_CONTENT) -async def reset_console(node: QemuVM = Depends(dep_node)) -> None: +async def reset_console(node: QemuVM = Depends(dep_node)) -> Response: await node.reset_console() + return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/gns3server/api/routes/compute/virtualbox_nodes.py b/gns3server/api/routes/compute/virtualbox_nodes.py index 93b548a0..351ad58f 100644 --- a/gns3server/api/routes/compute/virtualbox_nodes.py +++ b/gns3server/api/routes/compute/virtualbox_nodes.py @@ -20,7 +20,7 @@ API routes for VirtualBox nodes. import os -from fastapi import APIRouter, WebSocket, Depends, Path, status +from fastapi import APIRouter, WebSocket, Depends, Path, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from uuid import UUID @@ -137,57 +137,63 @@ async def update_virtualbox_node( @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> None: +async def delete_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> Response: """ Delete a VirtualBox node. """ await VirtualBox.instance().delete_node(node.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -async def start_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> None: +async def start_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> Response: """ Start a VirtualBox node. """ await node.start() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -async def stop_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> None: +async def stop_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> Response: """ Stop a VirtualBox node. """ await node.stop() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -async def suspend_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> None: +async def suspend_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> Response: """ Suspend a VirtualBox node. """ await node.suspend() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/resume", status_code=status.HTTP_204_NO_CONTENT) -async def resume_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> None: +async def resume_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> Response: """ Resume a VirtualBox node. """ await node.resume() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT) -async def reload_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> None: +async def reload_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> Response: """ Reload a VirtualBox node. """ await node.reload() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -243,13 +249,14 @@ async def delete_virtualbox_node_nio( adapter_number: int, port_number: int = Path(..., ge=0, le=0), node: VirtualBoxVM = Depends(dep_node) -) -> None: +) -> Response: """ Delete a NIO (Network Input/Output) from the node. The port number on the VirtualBox node is always 0. """ await node.adapter_remove_nio_binding(adapter_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -277,13 +284,14 @@ async def stop_virtualbox_node_capture( adapter_number: int, port_number: int = Path(..., ge=0, le=0), node: VirtualBoxVM = Depends(dep_node) -) -> None: +) -> Response: """ Stop a packet capture on the node. The port number on the VirtualBox node is always 0. """ await node.stop_capture(adapter_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream") @@ -312,6 +320,7 @@ async def console_ws(websocket: WebSocket, node: VirtualBoxVM = Depends(dep_node @router.post("/{node_id}/console/reset", status_code=status.HTTP_204_NO_CONTENT) -async def reset_console(node: VirtualBoxVM = Depends(dep_node)) -> None: +async def reset_console(node: VirtualBoxVM = Depends(dep_node)) -> Response: await node.reset_console() + return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/gns3server/api/routes/compute/vmware_nodes.py b/gns3server/api/routes/compute/vmware_nodes.py index 976b749e..59c25927 100644 --- a/gns3server/api/routes/compute/vmware_nodes.py +++ b/gns3server/api/routes/compute/vmware_nodes.py @@ -20,7 +20,7 @@ API routes for VMware nodes. import os -from fastapi import APIRouter, WebSocket, Depends, Path, status +from fastapi import APIRouter, WebSocket, Depends, Path, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from uuid import UUID @@ -103,57 +103,63 @@ def update_vmware_node(node_data: schemas.VMwareUpdate, node: VMwareVM = Depends @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_vmware_node(node: VMwareVM = Depends(dep_node)) -> None: +async def delete_vmware_node(node: VMwareVM = Depends(dep_node)) -> Response: """ Delete a VMware node. """ await VMware.instance().delete_node(node.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -async def start_vmware_node(node: VMwareVM = Depends(dep_node)) -> None: +async def start_vmware_node(node: VMwareVM = Depends(dep_node)) -> Response: """ Start a VMware node. """ await node.start() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -async def stop_vmware_node(node: VMwareVM = Depends(dep_node)) -> None: +async def stop_vmware_node(node: VMwareVM = Depends(dep_node)) -> Response: """ Stop a VMware node. """ await node.stop() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -async def suspend_vmware_node(node: VMwareVM = Depends(dep_node)) -> None: +async def suspend_vmware_node(node: VMwareVM = Depends(dep_node)) -> Response: """ Suspend a VMware node. """ await node.suspend() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/resume", status_code=status.HTTP_204_NO_CONTENT) -async def resume_vmware_node(node: VMwareVM = Depends(dep_node)) -> None: +async def resume_vmware_node(node: VMwareVM = Depends(dep_node)) -> Response: """ Resume a VMware node. """ await node.resume() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT) -async def reload_vmware_node(node: VMwareVM = Depends(dep_node)) -> None: +async def reload_vmware_node(node: VMwareVM = Depends(dep_node)) -> Response: """ Reload a VMware node. """ await node.reload() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -207,13 +213,14 @@ async def delete_vmware_node_nio( adapter_number: int, port_number: int = Path(..., ge=0, le=0), node: VMwareVM = Depends(dep_node) -) -> None: +) -> Response: """ Delete a NIO (Network Input/Output) from the node. The port number on the VMware node is always 0. """ await node.adapter_remove_nio_binding(adapter_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -241,13 +248,14 @@ async def stop_vmware_node_capture( adapter_number: int, port_number: int = Path(..., ge=0, le=0), node: VMwareVM = Depends(dep_node) -) -> None: +) -> Response: """ Stop a packet capture on the node. The port number on the VMware node is always 0. """ await node.stop_capture(adapter_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream") @@ -289,6 +297,7 @@ async def console_ws(websocket: WebSocket, node: VMwareVM = Depends(dep_node)) - @router.post("/{node_id}/console/reset", status_code=status.HTTP_204_NO_CONTENT) -async def reset_console(node: VMwareVM = Depends(dep_node)) -> None: +async def reset_console(node: VMwareVM = Depends(dep_node)) -> Response: await node.reset_console() + return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/gns3server/api/routes/compute/vpcs_nodes.py b/gns3server/api/routes/compute/vpcs_nodes.py index 7d9ffab9..e505e78f 100644 --- a/gns3server/api/routes/compute/vpcs_nodes.py +++ b/gns3server/api/routes/compute/vpcs_nodes.py @@ -20,7 +20,7 @@ API routes for VPCS nodes. import os -from fastapi import APIRouter, WebSocket, Depends, Body, Path, status +from fastapi import APIRouter, WebSocket, Depends, Body, Path, Response, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from uuid import UUID @@ -93,12 +93,13 @@ def update_vpcs_node(node_data: schemas.VPCSUpdate, node: VPCSVM = Depends(dep_n @router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_vpcs_node(node: VPCSVM = Depends(dep_node)) -> None: +async def delete_vpcs_node(node: VPCSVM = Depends(dep_node)) -> Response: """ Delete a VPCS node. """ await VPCS.instance().delete_node(node.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/duplicate", response_model=schemas.VPCS, status_code=status.HTTP_201_CREATED) @@ -114,40 +115,43 @@ async def duplicate_vpcs_node( @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -async def start_vpcs_node(node: VPCSVM = Depends(dep_node)) -> None: +async def start_vpcs_node(node: VPCSVM = Depends(dep_node)) -> Response: """ Start a VPCS node. """ await node.start() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -async def stop_vpcs_node(node: VPCSVM = Depends(dep_node)) -> None: +async def stop_vpcs_node(node: VPCSVM = Depends(dep_node)) -> Response: """ Stop a VPCS node. """ await node.stop() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -async def suspend_vpcs_node(node: VPCSVM = Depends(dep_node)) -> None: +async def suspend_vpcs_node(node: VPCSVM = Depends(dep_node)) -> Response: """ Suspend a VPCS node. Does nothing, suspend is not supported by VPCS. """ - pass + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT) -async def reload_vpcs_node(node: VPCSVM = Depends(dep_node)) -> None: +async def reload_vpcs_node(node: VPCSVM = Depends(dep_node)) -> Response: """ Reload a VPCS node. """ await node.reload() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -202,13 +206,14 @@ async def delete_vpcs_node_nio( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: VPCSVM = Depends(dep_node) -) -> None: +) -> Response: """ Delete a NIO (Network Input/Output) from the node. The adapter number on the VPCS node is always 0. """ await node.port_remove_nio_binding(port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start") @@ -237,19 +242,21 @@ async def stop_vpcs_node_capture( adapter_number: int = Path(..., ge=0, le=0), port_number: int, node: VPCSVM = Depends(dep_node) -) -> None: +) -> Response: """ Stop a packet capture on the node. The adapter number on the VPCS node is always 0. """ await node.stop_capture(port_number) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/console/reset", status_code=status.HTTP_204_NO_CONTENT) -async def reset_console(node: VPCSVM = Depends(dep_node)) -> None: +async def reset_console(node: VPCSVM = Depends(dep_node)) -> Response: await node.reset_console() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream") diff --git a/gns3server/api/routes/controller/computes.py b/gns3server/api/routes/controller/computes.py index 2cc8727c..34e10f5c 100644 --- a/gns3server/api/routes/controller/computes.py +++ b/gns3server/api/routes/controller/computes.py @@ -18,7 +18,7 @@ API routes for computes. """ -from fastapi import APIRouter, Depends, status +from fastapi import APIRouter, Depends, Response, status from typing import List, Union from uuid import UUID @@ -93,12 +93,13 @@ async def update_compute( @router.delete("/{compute_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_compute( compute_id: Union[str, UUID], computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository)) -) -> None: +) -> Response: """ Delete a compute from the controller. """ await ComputesService(computes_repo).delete_compute(compute_id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{compute_id}/{emulator}/images") diff --git a/gns3server/api/routes/controller/controller.py b/gns3server/api/routes/controller/controller.py index b64501e1..0db1d6e2 100644 --- a/gns3server/api/routes/controller/controller.py +++ b/gns3server/api/routes/controller/controller.py @@ -18,7 +18,7 @@ import asyncio import signal import os -from fastapi import APIRouter, Depends, status +from fastapi import APIRouter, Depends, Response, status from fastapi.encoders import jsonable_encoder from typing import List @@ -72,12 +72,13 @@ def check_version(version: schemas.Version) -> dict: dependencies=[Depends(get_current_active_user)], status_code=status.HTTP_204_NO_CONTENT, ) -async def reload() -> None: +async def reload() -> Response: """ Reload the controller """ await Controller.instance().reload() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -86,7 +87,7 @@ async def reload() -> None: status_code=status.HTTP_204_NO_CONTENT, responses={403: {"model": schemas.ErrorMessage, "description": "Server shutdown not allowed"}}, ) -async def shutdown() -> None: +async def shutdown() -> Response: """ Shutdown the server """ @@ -114,6 +115,7 @@ async def shutdown() -> None: # then shutdown the server itself os.kill(os.getpid(), signal.SIGTERM) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get( diff --git a/gns3server/api/routes/controller/drawings.py b/gns3server/api/routes/controller/drawings.py index bce40ca7..accec9cf 100644 --- a/gns3server/api/routes/controller/drawings.py +++ b/gns3server/api/routes/controller/drawings.py @@ -18,7 +18,7 @@ API routes for drawings. """ -from fastapi import APIRouter, status +from fastapi import APIRouter, Response, status from fastapi.encoders import jsonable_encoder from typing import List from uuid import UUID @@ -76,10 +76,11 @@ async def update_drawing(project_id: UUID, drawing_id: UUID, drawing_data: schem @router.delete("/{drawing_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_drawing(project_id: UUID, drawing_id: UUID) -> None: +async def delete_drawing(project_id: UUID, drawing_id: UUID) -> Response: """ Delete a drawing. """ project = await Controller.instance().get_loaded_project(str(project_id)) await project.delete_drawing(str(drawing_id)) + return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/gns3server/api/routes/controller/groups.py b/gns3server/api/routes/controller/groups.py index a028985b..b9ac05c4 100644 --- a/gns3server/api/routes/controller/groups.py +++ b/gns3server/api/routes/controller/groups.py @@ -19,7 +19,7 @@ API routes for user groups. """ -from fastapi import APIRouter, Depends, status +from fastapi import APIRouter, Depends, Response, status from uuid import UUID from typing import List @@ -112,7 +112,7 @@ async def update_user_group( async def delete_user_group( user_group_id: UUID, users_repo: UsersRepository = Depends(get_repository(UsersRepository)), -) -> None: +) -> Response: """ Delete an user group """ @@ -128,6 +128,8 @@ async def delete_user_group( if not success: raise ControllerNotFoundError(f"User group '{user_group_id}' could not be deleted") + return Response(status_code=status.HTTP_204_NO_CONTENT) + @router.get("/{user_group_id}/members", response_model=List[schemas.User]) async def get_user_group_members( @@ -149,7 +151,7 @@ async def add_member_to_group( user_group_id: UUID, user_id: UUID, users_repo: UsersRepository = Depends(get_repository(UsersRepository)) -) -> None: +) -> Response: """ Add member to an user group. """ @@ -162,6 +164,8 @@ async def add_member_to_group( if not user_group: raise ControllerNotFoundError(f"User group '{user_group_id}' not found") + return Response(status_code=status.HTTP_204_NO_CONTENT) + @router.delete( "/{user_group_id}/members/{user_id}", @@ -171,7 +175,7 @@ async def remove_member_from_group( user_group_id: UUID, user_id: UUID, users_repo: UsersRepository = Depends(get_repository(UsersRepository)), -) -> None: +) -> Response: """ Remove member from an user group. """ @@ -184,6 +188,8 @@ async def remove_member_from_group( if not user_group: raise ControllerNotFoundError(f"User group '{user_group_id}' not found") + return Response(status_code=status.HTTP_204_NO_CONTENT) + @router.get("/{user_group_id}/roles", response_model=List[schemas.Role]) async def get_user_group_roles( @@ -206,7 +212,7 @@ async def add_role_to_group( role_id: UUID, users_repo: UsersRepository = Depends(get_repository(UsersRepository)), rbac_repo: RbacRepository = Depends(get_repository(RbacRepository)) -) -> None: +) -> Response: """ Add role to an user group. """ @@ -219,6 +225,8 @@ async def add_role_to_group( if not user_group: raise ControllerNotFoundError(f"User group '{user_group_id}' not found") + return Response(status_code=status.HTTP_204_NO_CONTENT) + @router.delete( "/{user_group_id}/roles/{role_id}", @@ -229,7 +237,7 @@ async def remove_role_from_group( role_id: UUID, users_repo: UsersRepository = Depends(get_repository(UsersRepository)), rbac_repo: RbacRepository = Depends(get_repository(RbacRepository)) -) -> None: +) -> Response: """ Remove role from an user group. """ @@ -241,3 +249,5 @@ async def remove_role_from_group( user_group = await users_repo.remove_role_from_user_group(user_group_id, role) if not user_group: raise ControllerNotFoundError(f"User group '{user_group_id}' not found") + + return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/gns3server/api/routes/controller/links.py b/gns3server/api/routes/controller/links.py index a1db1adf..8f1c6f9c 100644 --- a/gns3server/api/routes/controller/links.py +++ b/gns3server/api/routes/controller/links.py @@ -21,7 +21,7 @@ API routes for links. import multidict import aiohttp -from fastapi import APIRouter, Depends, Request, status +from fastapi import APIRouter, Depends, Request, Response, status from fastapi.responses import StreamingResponse from fastapi.encoders import jsonable_encoder from typing import List @@ -136,13 +136,14 @@ async def update_link(link_data: schemas.LinkUpdate, link: Link = Depends(dep_li @router.delete("/{link_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_link(project_id: UUID, link: Link = Depends(dep_link)) -> None: +async def delete_link(project_id: UUID, link: Link = Depends(dep_link)) -> Response: """ Delete a link. """ project = await Controller.instance().get_loaded_project(str(project_id)) await project.delete_link(link.id) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{link_id}/reset", response_model=schemas.Link) @@ -169,12 +170,13 @@ async def start_capture(capture_data: dict, link: Link = Depends(dep_link)) -> s @router.post("/{link_id}/capture/stop", status_code=status.HTTP_204_NO_CONTENT) -async def stop_capture(link: Link = Depends(dep_link)) -> None: +async def stop_capture(link: Link = Depends(dep_link)) -> Response: """ Stop packet capture on the link. """ await link.stop_capture() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{link_id}/capture/stream") diff --git a/gns3server/api/routes/controller/nodes.py b/gns3server/api/routes/controller/nodes.py index 3016d84f..c175d583 100644 --- a/gns3server/api/routes/controller/nodes.py +++ b/gns3server/api/routes/controller/nodes.py @@ -130,40 +130,44 @@ async def get_nodes(project: Project = Depends(dep_project)) -> List[schemas.Nod @router.post("/start", status_code=status.HTTP_204_NO_CONTENT) -async def start_all_nodes(project: Project = Depends(dep_project)) -> None: +async def start_all_nodes(project: Project = Depends(dep_project)) -> Response: """ Start all nodes belonging to a given project. """ await project.start_all() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/stop", status_code=status.HTTP_204_NO_CONTENT) -async def stop_all_nodes(project: Project = Depends(dep_project)) -> None: +async def stop_all_nodes(project: Project = Depends(dep_project)) -> Response: """ Stop all nodes belonging to a given project. """ await project.stop_all() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/suspend", status_code=status.HTTP_204_NO_CONTENT) -async def suspend_all_nodes(project: Project = Depends(dep_project)) -> None: +async def suspend_all_nodes(project: Project = Depends(dep_project)) -> Response: """ Suspend all nodes belonging to a given project. """ await project.suspend_all() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/reload", status_code=status.HTTP_204_NO_CONTENT) -async def reload_all_nodes(project: Project = Depends(dep_project)) -> None: +async def reload_all_nodes(project: Project = Depends(dep_project)) -> Response: """ Reload all nodes belonging to a given project. """ await project.stop_all() await project.start_all() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}", response_model=schemas.Node) @@ -197,12 +201,13 @@ async def update_node(node_data: schemas.NodeUpdate, node: Node = Depends(dep_no status_code=status.HTTP_204_NO_CONTENT, responses={**responses, 409: {"model": schemas.ErrorMessage, "description": "Cannot delete node"}}, ) -async def delete_node(node_id: UUID, project: Project = Depends(dep_project)) -> None: +async def delete_node(node_id: UUID, project: Project = Depends(dep_project)) -> Response: """ Delete a node from a project. """ await project.delete_node(str(node_id)) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/duplicate", response_model=schemas.Node, status_code=status.HTTP_201_CREATED) @@ -216,39 +221,43 @@ async def duplicate_node(duplicate_data: schemas.NodeDuplicate, node: Node = Dep @router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT) -async def start_node(start_data: dict, node: Node = Depends(dep_node)) -> None: +async def start_node(start_data: dict, node: Node = Depends(dep_node)) -> Response: """ Start a node. """ await node.start(data=start_data) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT) -async def stop_node(node: Node = Depends(dep_node)) -> None: +async def stop_node(node: Node = Depends(dep_node)) -> Response: """ Stop a node. """ await node.stop() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT) -async def suspend_node(node: Node = Depends(dep_node)) -> None: +async def suspend_node(node: Node = Depends(dep_node)) -> Response: """ Suspend a node. """ await node.suspend() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT) -async def reload_node(node: Node = Depends(dep_node)) -> None: +async def reload_node(node: Node = Depends(dep_node)) -> Response: """ Reload a node. """ await node.reload() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/links", response_model=List[schemas.Link], response_model_exclude_unset=True) @@ -282,11 +291,13 @@ async def idlepc_proposals(node: Node = Depends(dep_node)) -> List[str]: @router.post("/{node_id}/resize_disk", status_code=status.HTTP_204_NO_CONTENT) -async def resize_disk(resize_data: dict, node: Node = Depends(dep_node)) -> None: +async def resize_disk(resize_data: dict, node: Node = Depends(dep_node)) -> Response: """ Resize a disk image. """ + await node.post("/resize_disk", **resize_data) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{node_id}/files/{file_path:path}") @@ -377,15 +388,17 @@ async def ws_console(websocket: WebSocket, node: Node = Depends(dep_node)) -> No @router.post("/console/reset", status_code=status.HTTP_204_NO_CONTENT) -async def reset_console_all_nodes(project: Project = Depends(dep_project)) -> None: +async def reset_console_all_nodes(project: Project = Depends(dep_project)) -> Response: """ Reset console for all nodes belonging to the project. """ await project.reset_console_all() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{node_id}/console/reset", status_code=status.HTTP_204_NO_CONTENT) -async def console_reset(node: Node = Depends(dep_node)) -> None: +async def console_reset(node: Node = Depends(dep_node)) -> Response: - await node.post("/console/reset") # , request.json) + await node.post("/console/reset") + return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/gns3server/api/routes/controller/permissions.py b/gns3server/api/routes/controller/permissions.py index 466a2707..fe7bf0f2 100644 --- a/gns3server/api/routes/controller/permissions.py +++ b/gns3server/api/routes/controller/permissions.py @@ -19,7 +19,7 @@ API routes for permissions. """ -from fastapi import APIRouter, Depends, status +from fastapi import APIRouter, Depends, Response, status from uuid import UUID from typing import List @@ -103,7 +103,7 @@ async def update_permission( async def delete_permission( permission_id: UUID, rbac_repo: RbacRepository = Depends(get_repository(RbacRepository)), -) -> None: +) -> Response: """ Delete a permission. """ @@ -115,3 +115,5 @@ async def delete_permission( success = await rbac_repo.delete_permission(permission_id) if not success: raise ControllerNotFoundError(f"Permission '{permission_id}' could not be deleted") + + return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/gns3server/api/routes/controller/projects.py b/gns3server/api/routes/controller/projects.py index 963de68c..757faf6f 100644 --- a/gns3server/api/routes/controller/projects.py +++ b/gns3server/api/routes/controller/projects.py @@ -30,7 +30,7 @@ import logging log = logging.getLogger() -from fastapi import APIRouter, Depends, Request, Body, HTTPException, status, WebSocket, WebSocketDisconnect +from fastapi import APIRouter, Depends, Request, Response, Body, HTTPException, status, WebSocket, WebSocketDisconnect from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse, FileResponse from websockets.exceptions import ConnectionClosed, WebSocketException @@ -141,7 +141,7 @@ async def update_project( async def delete_project( project: Project = Depends(dep_project), rbac_repo: RbacRepository = Depends(get_repository(RbacRepository)) -) -> None: +) -> Response: """ Delete a project. """ @@ -150,6 +150,7 @@ async def delete_project( await project.delete() controller.remove_project(project) await rbac_repo.delete_all_permissions_with_path(f"/projects/{project.id}") + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/{project_id}/stats") @@ -166,12 +167,13 @@ def get_project_stats(project: Project = Depends(dep_project)) -> dict: status_code=status.HTTP_204_NO_CONTENT, responses={**responses, 409: {"model": schemas.ErrorMessage, "description": "Could not close project"}}, ) -async def close_project(project: Project = Depends(dep_project)) -> None: +async def close_project(project: Project = Depends(dep_project)) -> Response: """ Close a project. """ await project.close() + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post( @@ -415,7 +417,7 @@ async def get_file(file_path: str, project: Project = Depends(dep_project)) -> F @router.post("/{project_id}/files/{file_path:path}", status_code=status.HTTP_204_NO_CONTENT) -async def write_file(file_path: str, request: Request, project: Project = Depends(dep_project)) -> None: +async def write_file(file_path: str, request: Request, project: Project = Depends(dep_project)) -> Response: """ Write a file from a project. """ @@ -440,6 +442,8 @@ async def write_file(file_path: str, request: Request, project: Project = Depend except OSError as e: raise ControllerError(str(e)) + return Response(status_code=status.HTTP_204_NO_CONTENT) + @router.post( "/{project_id}/templates/{template_id}", diff --git a/gns3server/api/routes/controller/roles.py b/gns3server/api/routes/controller/roles.py index fb8be351..8da951d6 100644 --- a/gns3server/api/routes/controller/roles.py +++ b/gns3server/api/routes/controller/roles.py @@ -19,7 +19,7 @@ API routes for roles. """ -from fastapi import APIRouter, Depends, status +from fastapi import APIRouter, Depends, Response, status from uuid import UUID from typing import List @@ -105,7 +105,7 @@ async def update_role( async def delete_role( role_id: UUID, rbac_repo: RbacRepository = Depends(get_repository(RbacRepository)), -) -> None: +) -> Response: """ Delete a role. """ @@ -121,6 +121,8 @@ async def delete_role( if not success: raise ControllerNotFoundError(f"Role '{role_id}' could not be deleted") + return Response(status_code=status.HTTP_204_NO_CONTENT) + @router.get("/{role_id}/permissions", response_model=List[schemas.Permission]) async def get_role_permissions( @@ -142,7 +144,7 @@ async def add_permission_to_role( role_id: UUID, permission_id: UUID, rbac_repo: RbacRepository = Depends(get_repository(RbacRepository)) -) -> None: +) -> Response: """ Add a permission to a role. """ @@ -155,6 +157,8 @@ async def add_permission_to_role( if not role: raise ControllerNotFoundError(f"Role '{role_id}' not found") + return Response(status_code=status.HTTP_204_NO_CONTENT) + @router.delete( "/{role_id}/permissions/{permission_id}", @@ -164,7 +168,7 @@ async def remove_permission_from_role( role_id: UUID, permission_id: UUID, rbac_repo: RbacRepository = Depends(get_repository(RbacRepository)), -) -> None: +) -> Response: """ Remove member from an user group. """ @@ -176,3 +180,5 @@ async def remove_permission_from_role( role = await rbac_repo.remove_permission_from_role(role_id, permission) if not role: raise ControllerNotFoundError(f"Role '{role_id}' not found") + + return Response(status_code=status.HTTP_204_NO_CONTENT) \ No newline at end of file diff --git a/gns3server/api/routes/controller/snapshots.py b/gns3server/api/routes/controller/snapshots.py index d410e88a..b1faa8cf 100644 --- a/gns3server/api/routes/controller/snapshots.py +++ b/gns3server/api/routes/controller/snapshots.py @@ -23,7 +23,7 @@ import logging log = logging.getLogger() -from fastapi import APIRouter, Depends, status +from fastapi import APIRouter, Depends, Response, status from typing import List from uuid import UUID @@ -69,12 +69,13 @@ def get_snapshots(project: Project = Depends(dep_project)) -> List[schemas.Snaps @router.delete("/{snapshot_id}", status_code=status.HTTP_204_NO_CONTENT) -async def delete_snapshot(snapshot_id: UUID, project: Project = Depends(dep_project)) -> None: +async def delete_snapshot(snapshot_id: UUID, project: Project = Depends(dep_project)) -> Response: """ Delete a snapshot. """ await project.delete_snapshot(str(snapshot_id)) + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.post("/{snapshot_id}/restore", status_code=status.HTTP_201_CREATED, response_model=schemas.Project) diff --git a/gns3server/api/routes/controller/symbols.py b/gns3server/api/routes/controller/symbols.py index 334ae926..40161672 100644 --- a/gns3server/api/routes/controller/symbols.py +++ b/gns3server/api/routes/controller/symbols.py @@ -21,7 +21,7 @@ API routes for symbols. import os -from fastapi import APIRouter, Request, Depends, status +from fastapi import APIRouter, Request, Depends, Response, status from fastapi.responses import FileResponse from typing import List @@ -95,7 +95,7 @@ def get_default_symbols() -> dict: dependencies=[Depends(get_current_active_user)], status_code=status.HTTP_204_NO_CONTENT ) -async def upload_symbol(symbol_id: str, request: Request) -> None: +async def upload_symbol(symbol_id: str, request: Request) -> Response: """ Upload a symbol file. """ @@ -111,3 +111,5 @@ async def upload_symbol(symbol_id: str, request: Request) -> None: # Reset the symbol list controller.symbols.list() + + return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/gns3server/api/routes/controller/templates.py b/gns3server/api/routes/controller/templates.py index 9f1cf07d..4f1914b5 100644 --- a/gns3server/api/routes/controller/templates.py +++ b/gns3server/api/routes/controller/templates.py @@ -25,7 +25,7 @@ import logging log = logging.getLogger(__name__) -from fastapi import APIRouter, Request, Response, HTTPException, Depends, status +from fastapi import APIRouter, Request, Response, HTTPException, Depends, Response, status from typing import List from uuid import UUID @@ -102,13 +102,14 @@ async def delete_template( template_id: UUID, templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)), rbac_repo: RbacRepository = Depends(get_repository(RbacRepository)) -) -> None: +) -> Response: """ Delete a template. """ await TemplatesService(templates_repo).delete_template(template_id) await rbac_repo.delete_all_permissions_with_path(f"/templates/{template_id}") + return Response(status_code=status.HTTP_204_NO_CONTENT) @router.get("/templates", response_model=List[schemas.Template], response_model_exclude_unset=True) diff --git a/gns3server/api/routes/controller/users.py b/gns3server/api/routes/controller/users.py index 7306c997..1bff6bfe 100644 --- a/gns3server/api/routes/controller/users.py +++ b/gns3server/api/routes/controller/users.py @@ -19,7 +19,7 @@ API routes for users. """ -from fastapi import APIRouter, Depends, HTTPException, status +from fastapi import APIRouter, Depends, HTTPException, Response, status from fastapi.security import OAuth2PasswordRequestForm from uuid import UUID from typing import List @@ -193,7 +193,7 @@ async def update_user( async def delete_user( user_id: UUID, users_repo: UsersRepository = Depends(get_repository(UsersRepository)), -) -> None: +) -> Response: """ Delete an user. """ @@ -209,6 +209,8 @@ async def delete_user( if not success: raise ControllerNotFoundError(f"User '{user_id}' could not be deleted") + return Response(status_code=status.HTTP_204_NO_CONTENT) + @router.get( "/{user_id}/groups", @@ -251,7 +253,7 @@ async def add_permission_to_user( user_id: UUID, permission_id: UUID, rbac_repo: RbacRepository = Depends(get_repository(RbacRepository)) -) -> None: +) -> Response: """ Add a permission to an user. """ @@ -264,6 +266,8 @@ async def add_permission_to_user( if not user: raise ControllerNotFoundError(f"User '{user_id}' not found") + return Response(status_code=status.HTTP_204_NO_CONTENT) + @router.delete( "/{user_id}/permissions/{permission_id}", @@ -274,7 +278,7 @@ async def remove_permission_from_user( user_id: UUID, permission_id: UUID, rbac_repo: RbacRepository = Depends(get_repository(RbacRepository)), -) -> None: +) -> Response: """ Remove permission from an user. """ @@ -286,3 +290,5 @@ async def remove_permission_from_user( user = await rbac_repo.remove_permission_from_user(user_id, permission) if not user: raise ControllerNotFoundError(f"User '{user_id}' not found") + + return Response(status_code=status.HTTP_204_NO_CONTENT)