mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-12 19:38:57 +00:00
Complete type annotations for API endpoints.
This commit is contained in:
parent
cefab8d362
commit
9404c00411
@ -20,7 +20,7 @@ API routes for ATM switch nodes.
|
||||
|
||||
import os
|
||||
|
||||
from fastapi import APIRouter, Depends, Body, status
|
||||
from fastapi import APIRouter, Depends, Body, Path, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
@ -34,7 +34,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
async def dep_node(project_id: UUID, node_id: UUID):
|
||||
async def dep_node(project_id: UUID, node_id: UUID) -> ATMSwitch:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -50,7 +50,7 @@ async def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create ATM switch node"}},
|
||||
)
|
||||
async def create_atm_switch(project_id: UUID, node_data: schemas.ATMSwitchCreate):
|
||||
async def create_atm_switch(project_id: UUID, node_data: schemas.ATMSwitchCreate) -> schemas.ATMSwitch:
|
||||
"""
|
||||
Create a new ATM switch node.
|
||||
"""
|
||||
@ -59,7 +59,7 @@ async def create_atm_switch(project_id: UUID, node_data: schemas.ATMSwitchCreate
|
||||
dynamips_manager = Dynamips.instance()
|
||||
node_data = jsonable_encoder(node_data, exclude_unset=True)
|
||||
node = await dynamips_manager.create_node(
|
||||
node_data.pop("name"),
|
||||
node_data.get("name"),
|
||||
str(project_id),
|
||||
node_data.get("node_id"),
|
||||
node_type="atm_switch",
|
||||
@ -69,7 +69,7 @@ async def create_atm_switch(project_id: UUID, node_data: schemas.ATMSwitchCreate
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.ATMSwitch)
|
||||
def get_atm_switch(node: ATMSwitch = Depends(dep_node)):
|
||||
def get_atm_switch(node: ATMSwitch = Depends(dep_node)) -> schemas.ATMSwitch:
|
||||
"""
|
||||
Return an ATM switch node.
|
||||
"""
|
||||
@ -78,7 +78,10 @@ def get_atm_switch(node: ATMSwitch = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/duplicate", response_model=schemas.ATMSwitch, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_atm_switch(destination_node_id: UUID = Body(..., embed=True), node: ATMSwitch = Depends(dep_node)):
|
||||
async def duplicate_atm_switch(
|
||||
destination_node_id: UUID = Body(..., embed=True),
|
||||
node: ATMSwitch = Depends(dep_node)
|
||||
) -> schemas.ATMSwitch:
|
||||
"""
|
||||
Duplicate an ATM switch node.
|
||||
"""
|
||||
@ -88,7 +91,10 @@ async def duplicate_atm_switch(destination_node_id: UUID = Body(..., embed=True)
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.ATMSwitch)
|
||||
async def update_atm_switch(node_data: schemas.ATMSwitchUpdate, node: ATMSwitch = Depends(dep_node)):
|
||||
async def update_atm_switch(
|
||||
node_data: schemas.ATMSwitchUpdate,
|
||||
node: ATMSwitch = Depends(dep_node)
|
||||
) -> schemas.ATMSwitch:
|
||||
"""
|
||||
Update an ATM switch node.
|
||||
"""
|
||||
@ -103,7 +109,7 @@ async def update_atm_switch(node_data: schemas.ATMSwitchUpdate, node: ATMSwitch
|
||||
|
||||
|
||||
@router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_atm_switch_node(node: ATMSwitch = Depends(dep_node)):
|
||||
async def delete_atm_switch_node(node: ATMSwitch = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete an ATM switch node.
|
||||
"""
|
||||
@ -122,7 +128,7 @@ def start_atm_switch(node: ATMSwitch = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def stop_atm_switch(node: ATMSwitch = Depends(dep_node)):
|
||||
def stop_atm_switch(node: ATMSwitch = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop an ATM switch node.
|
||||
This endpoint results in no action since ATM switch nodes are always on.
|
||||
@ -132,7 +138,7 @@ def stop_atm_switch(node: ATMSwitch = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def suspend_atm_switch(node: ATMSwitch = Depends(dep_node)):
|
||||
def suspend_atm_switch(node: ATMSwitch = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend an ATM switch node.
|
||||
This endpoint results in no action since ATM switch nodes are always on.
|
||||
@ -147,8 +153,12 @@ def suspend_atm_switch(node: ATMSwitch = Depends(dep_node)):
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def create_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: ATMSwitch = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: ATMSwitch = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Add a NIO (Network Input/Output) to the node.
|
||||
The adapter number on the switch is always 0.
|
||||
@ -160,7 +170,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)):
|
||||
async def delete_nio(adapter_number: int, port_number: int, node: ATMSwitch = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Remove a NIO (Network Input/Output) from the node.
|
||||
The adapter number on the switch is always 0.
|
||||
@ -172,8 +182,12 @@ async def delete_nio(adapter_number: int, port_number: int, node: ATMSwitch = De
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_capture(
|
||||
adapter_number: int, port_number: int, node_capture_data: schemas.NodeCapture, node: ATMSwitch = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: ATMSwitch = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
The adapter number on the switch is always 0.
|
||||
@ -188,7 +202,12 @@ async def start_capture(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop_capture",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
)
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: ATMSwitch = Depends(dep_node)):
|
||||
async def stop_capture(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: ATMSwitch = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
The adapter number on the switch is always 0.
|
||||
@ -198,7 +217,12 @@ async def stop_capture(adapter_number: int, port_number: int, node: ATMSwitch =
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: ATMSwitch = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: ATMSwitch = Depends(dep_node)
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
The adapter number on the switch is always 0.
|
||||
|
@ -32,7 +32,7 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/capabilities", response_model=schemas.Capabilities)
|
||||
def get_capabilities():
|
||||
def get_capabilities() -> dict:
|
||||
|
||||
node_types = []
|
||||
for module in MODULES:
|
||||
|
@ -20,7 +20,7 @@ API routes for cloud nodes.
|
||||
|
||||
import os
|
||||
|
||||
from fastapi import APIRouter, Depends, status
|
||||
from fastapi import APIRouter, Depends, Path, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from typing import Union
|
||||
@ -35,7 +35,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_node(project_id: UUID, node_id: UUID):
|
||||
def dep_node(project_id: UUID, node_id: UUID) -> Cloud:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -51,7 +51,7 @@ def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create cloud node"}},
|
||||
)
|
||||
async def create_cloud(project_id: UUID, node_data: schemas.CloudCreate):
|
||||
async def create_cloud(project_id: UUID, node_data: schemas.CloudCreate) -> schemas.Cloud:
|
||||
"""
|
||||
Create a new cloud node.
|
||||
"""
|
||||
@ -76,7 +76,7 @@ async def create_cloud(project_id: UUID, node_data: schemas.CloudCreate):
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.Cloud)
|
||||
def get_cloud(node: Cloud = Depends(dep_node)):
|
||||
def get_cloud(node: Cloud = Depends(dep_node)) -> schemas.Cloud:
|
||||
"""
|
||||
Return a cloud node.
|
||||
"""
|
||||
@ -85,7 +85,7 @@ def get_cloud(node: Cloud = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.Cloud)
|
||||
def update_cloud(node_data: schemas.CloudUpdate, node: Cloud = Depends(dep_node)):
|
||||
def update_cloud(node_data: schemas.CloudUpdate, node: Cloud = Depends(dep_node)) -> schemas.Cloud:
|
||||
"""
|
||||
Update a cloud node.
|
||||
"""
|
||||
@ -99,7 +99,7 @@ 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)):
|
||||
async def delete_cloud(node: Cloud = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete a cloud node.
|
||||
"""
|
||||
@ -108,7 +108,7 @@ async def delete_cloud(node: Cloud = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def start_cloud(node: Cloud = Depends(dep_node)):
|
||||
async def start_cloud(node: Cloud = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start a cloud node.
|
||||
"""
|
||||
@ -117,7 +117,7 @@ async def start_cloud(node: Cloud = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_cloud(node: Cloud = Depends(dep_node)):
|
||||
async def stop_cloud(node: Cloud = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop a cloud node.
|
||||
This endpoint results in no action since cloud nodes cannot be stopped.
|
||||
@ -127,7 +127,7 @@ async def stop_cloud(node: Cloud = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def suspend_cloud(node: Cloud = Depends(dep_node)):
|
||||
async def suspend_cloud(node: Cloud = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend a cloud node.
|
||||
This endpoint results in no action since cloud nodes cannot be suspended.
|
||||
@ -142,11 +142,12 @@ async def suspend_cloud(node: Cloud = Depends(dep_node)):
|
||||
response_model=Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
)
|
||||
async def create_cloud_nio(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
nio_data: Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
node: Cloud = Depends(dep_node),
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
nio_data: Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
node: Cloud = Depends(dep_node),
|
||||
) -> Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO]:
|
||||
"""
|
||||
Add a NIO (Network Input/Output) to the node.
|
||||
The adapter number on the cloud is always 0.
|
||||
@ -163,11 +164,12 @@ async def create_cloud_nio(
|
||||
response_model=Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
)
|
||||
async def update_cloud_nio(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
nio_data: Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
node: Cloud = Depends(dep_node),
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
nio_data: Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
node: Cloud = Depends(dep_node),
|
||||
) -> Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO]:
|
||||
"""
|
||||
Update a NIO (Network Input/Output) to the node.
|
||||
The adapter number on the cloud is always 0.
|
||||
@ -181,7 +183,12 @@ async def update_cloud_nio(
|
||||
|
||||
|
||||
@router.delete("/{node_id}/adapters/{adapter_number}/ports/{port_number}/nio", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_cloud_nio(adapter_number: int, port_number: int, node: Cloud = Depends(dep_node)):
|
||||
async def delete_cloud_nio(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: Cloud = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Remove a NIO (Network Input/Output) from the node.
|
||||
The adapter number on the cloud is always 0.
|
||||
@ -192,8 +199,12 @@ async def delete_cloud_nio(adapter_number: int, port_number: int, node: Cloud =
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_cloud_capture(
|
||||
adapter_number: int, port_number: int, node_capture_data: schemas.NodeCapture, node: Cloud = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: Cloud = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
The adapter number on the cloud is always 0.
|
||||
@ -207,7 +218,12 @@ async def start_cloud_capture(
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop", status_code=status.HTTP_204_NO_CONTENT
|
||||
)
|
||||
async def stop_cloud_capture(adapter_number: int, port_number: int, node: Cloud = Depends(dep_node)):
|
||||
async def stop_cloud_capture(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: Cloud = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
The adapter number on the cloud is always 0.
|
||||
@ -217,7 +233,12 @@ async def stop_cloud_capture(adapter_number: int, port_number: int, node: Cloud
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/pcap")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: Cloud = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: Cloud = Depends(dep_node)
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
The adapter number on the cloud is always 0.
|
||||
|
@ -123,13 +123,15 @@ def compute_statistics() -> dict:
|
||||
|
||||
|
||||
@router.get("/qemu/binaries")
|
||||
async def get_qemu_binaries(archs: Optional[List[str]] = Body(None, embed=True)):
|
||||
async def get_qemu_binaries(
|
||||
archs: Optional[List[str]] = Body(None, embed=True)
|
||||
) -> List[str]:
|
||||
|
||||
return await Qemu.binary_list(archs)
|
||||
|
||||
|
||||
@router.get("/qemu/img-binaries")
|
||||
async def get_image_binaries():
|
||||
async def get_image_binaries() -> List[str]:
|
||||
|
||||
return await Qemu.img_binary_list()
|
||||
|
||||
@ -148,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):
|
||||
async def create_qemu_image(image_data: schemas.QemuImageCreate) -> None:
|
||||
"""
|
||||
Create a Qemu image.
|
||||
"""
|
||||
@ -167,7 +169,7 @@ async def create_qemu_image(image_data: schemas.QemuImageCreate):
|
||||
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):
|
||||
async def update_qemu_image(image_data: schemas.QemuImageUpdate) -> None:
|
||||
"""
|
||||
Update a Qemu image.
|
||||
"""
|
||||
@ -181,13 +183,13 @@ async def update_qemu_image(image_data: schemas.QemuImageUpdate):
|
||||
|
||||
|
||||
@router.get("/virtualbox/vms", response_model=List[dict])
|
||||
async def get_virtualbox_vms():
|
||||
async def get_virtualbox_vms() -> List[dict]:
|
||||
|
||||
vbox_manager = VirtualBox.instance()
|
||||
return await vbox_manager.list_vms()
|
||||
|
||||
|
||||
@router.get("/vmware/vms", response_model=List[dict])
|
||||
async def get_vms():
|
||||
async def get_vms() -> List[dict]:
|
||||
vmware_manager = VMware.instance()
|
||||
return await vmware_manager.list_vms()
|
||||
|
@ -34,7 +34,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_node(project_id: UUID, node_id: UUID):
|
||||
def dep_node(project_id: UUID, node_id: UUID) -> DockerVM:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -50,7 +50,7 @@ def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create Docker node"}},
|
||||
)
|
||||
async def create_docker_node(project_id: UUID, node_data: schemas.DockerCreate):
|
||||
async def create_docker_node(project_id: UUID, node_data: schemas.DockerCreate) -> schemas.Docker:
|
||||
"""
|
||||
Create a new Docker node.
|
||||
"""
|
||||
@ -86,7 +86,7 @@ async def create_docker_node(project_id: UUID, node_data: schemas.DockerCreate):
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.Docker)
|
||||
def get_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
def get_docker_node(node: DockerVM = Depends(dep_node)) -> schemas.Docker:
|
||||
"""
|
||||
Return a Docker node.
|
||||
"""
|
||||
@ -95,7 +95,7 @@ def get_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.Docker)
|
||||
async def update_docker_node(node_data: schemas.DockerUpdate, node: DockerVM = Depends(dep_node)):
|
||||
async def update_docker_node(node_data: schemas.DockerUpdate, node: DockerVM = Depends(dep_node)) -> schemas.Docker:
|
||||
"""
|
||||
Update a Docker node.
|
||||
"""
|
||||
@ -132,7 +132,7 @@ 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)):
|
||||
async def start_docker_node(node: DockerVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start a Docker node.
|
||||
"""
|
||||
@ -141,7 +141,7 @@ async def start_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
async def stop_docker_node(node: DockerVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop a Docker node.
|
||||
"""
|
||||
@ -150,7 +150,7 @@ async def stop_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def suspend_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
async def suspend_docker_node(node: DockerVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend a Docker node.
|
||||
"""
|
||||
@ -159,7 +159,7 @@ async def suspend_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reload_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
async def reload_docker_node(node: DockerVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Reload a Docker node.
|
||||
"""
|
||||
@ -168,7 +168,7 @@ async def reload_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/pause", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def pause_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
async def pause_docker_node(node: DockerVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Pause a Docker node.
|
||||
"""
|
||||
@ -177,7 +177,7 @@ async def pause_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/unpause", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def unpause_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
async def unpause_docker_node(node: DockerVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Unpause a Docker node.
|
||||
"""
|
||||
@ -186,7 +186,7 @@ async def unpause_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
async def delete_docker_node(node: DockerVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete a Docker node.
|
||||
"""
|
||||
@ -195,7 +195,10 @@ async def delete_docker_node(node: DockerVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/duplicate", response_model=schemas.Docker, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_docker_node(destination_node_id: UUID = Body(..., embed=True), node: DockerVM = Depends(dep_node)):
|
||||
async def duplicate_docker_node(
|
||||
destination_node_id: UUID = Body(..., embed=True),
|
||||
node: DockerVM = Depends(dep_node)
|
||||
) -> schemas.Docker:
|
||||
"""
|
||||
Duplicate a Docker node.
|
||||
"""
|
||||
@ -211,7 +214,7 @@ async def duplicate_docker_node(destination_node_id: UUID = Body(..., embed=True
|
||||
)
|
||||
async def create_docker_node_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: DockerVM = Depends(dep_node)
|
||||
):
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Add a NIO (Network Input/Output) to the node.
|
||||
The port number on the Docker node is always 0.
|
||||
@ -229,7 +232,7 @@ async def create_docker_node_nio(
|
||||
)
|
||||
async def update_docker_node_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: DockerVM = Depends(dep_node)
|
||||
):
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Update a NIO (Network Input/Output) on the node.
|
||||
The port number on the Docker node is always 0.
|
||||
@ -243,7 +246,11 @@ async def update_docker_node_nio(
|
||||
|
||||
|
||||
@router.delete("/{node_id}/adapters/{adapter_number}/ports/{port_number}/nio", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_docker_node_nio(adapter_number: int, port_number: int, node: DockerVM = Depends(dep_node)):
|
||||
async def delete_docker_node_nio(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
node: DockerVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Delete a NIO (Network Input/Output) from the node.
|
||||
The port number on the Docker node is always 0.
|
||||
@ -254,8 +261,11 @@ async def delete_docker_node_nio(adapter_number: int, port_number: int, node: Do
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_docker_node_capture(
|
||||
adapter_number: int, port_number: int, node_capture_data: schemas.NodeCapture, node: DockerVM = Depends(dep_node)
|
||||
):
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: DockerVM = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
The port number on the Docker node is always 0.
|
||||
@ -267,9 +277,14 @@ async def start_docker_node_capture(
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop", status_code=status.HTTP_204_NO_CONTENT
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT
|
||||
)
|
||||
async def stop_docker_node_capture(adapter_number: int, port_number: int, node: DockerVM = Depends(dep_node)):
|
||||
async def stop_docker_node_capture(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
node: DockerVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
The port number on the Docker node is always 0.
|
||||
@ -279,7 +294,11 @@ async def stop_docker_node_capture(adapter_number: int, port_number: int, node:
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: DockerVM = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
node: DockerVM = Depends(dep_node)
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
The port number on the Docker node is always 0.
|
||||
@ -291,7 +310,7 @@ async def stream_pcap_file(adapter_number: int, port_number: int, node: DockerVM
|
||||
|
||||
|
||||
@router.websocket("/{node_id}/console/ws")
|
||||
async def console_ws(websocket: WebSocket, node: DockerVM = Depends(dep_node)):
|
||||
async def console_ws(websocket: WebSocket, node: DockerVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Console WebSocket.
|
||||
"""
|
||||
@ -300,6 +319,6 @@ 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)):
|
||||
async def reset_console(node: DockerVM = Depends(dep_node)) -> None:
|
||||
|
||||
await node.reset_console()
|
||||
|
@ -40,7 +40,7 @@ router = APIRouter(responses=responses)
|
||||
DEFAULT_CHASSIS = {"c1700": "1720", "c2600": "2610", "c3600": "3640"}
|
||||
|
||||
|
||||
def dep_node(project_id: UUID, node_id: UUID):
|
||||
def dep_node(project_id: UUID, node_id: UUID) -> Router:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -56,7 +56,7 @@ def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create Dynamips node"}},
|
||||
)
|
||||
async def create_router(project_id: UUID, node_data: schemas.DynamipsCreate):
|
||||
async def create_router(project_id: UUID, node_data: schemas.DynamipsCreate) -> schemas.Dynamips:
|
||||
"""
|
||||
Create a new Dynamips router.
|
||||
"""
|
||||
@ -85,7 +85,7 @@ async def create_router(project_id: UUID, node_data: schemas.DynamipsCreate):
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.Dynamips)
|
||||
def get_router(node: Router = Depends(dep_node)):
|
||||
def get_router(node: Router = Depends(dep_node)) -> schemas.Dynamips:
|
||||
"""
|
||||
Return Dynamips router.
|
||||
"""
|
||||
@ -94,7 +94,7 @@ def get_router(node: Router = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.Dynamips)
|
||||
async def update_router(node_data: schemas.DynamipsUpdate, node: Router = Depends(dep_node)):
|
||||
async def update_router(node_data: schemas.DynamipsUpdate, node: Router = Depends(dep_node)) -> schemas.Dynamips:
|
||||
"""
|
||||
Update a Dynamips router.
|
||||
"""
|
||||
@ -105,7 +105,7 @@ 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)):
|
||||
async def delete_router(node: Router = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete a Dynamips router.
|
||||
"""
|
||||
@ -114,7 +114,7 @@ async def delete_router(node: Router = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def start_router(node: Router = Depends(dep_node)):
|
||||
async def start_router(node: Router = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start a Dynamips router.
|
||||
"""
|
||||
@ -127,7 +127,7 @@ async def start_router(node: Router = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_router(node: Router = Depends(dep_node)):
|
||||
async def stop_router(node: Router = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop a Dynamips router.
|
||||
"""
|
||||
@ -136,13 +136,13 @@ async def stop_router(node: Router = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def suspend_router(node: Router = Depends(dep_node)):
|
||||
async def suspend_router(node: Router = Depends(dep_node)) -> None:
|
||||
|
||||
await node.suspend()
|
||||
|
||||
|
||||
@router.post("/{node_id}/resume", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def resume_router(node: Router = Depends(dep_node)):
|
||||
async def resume_router(node: Router = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Resume a suspended Dynamips router.
|
||||
"""
|
||||
@ -151,7 +151,7 @@ async def resume_router(node: Router = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reload_router(node: Router = Depends(dep_node)):
|
||||
async def reload_router(node: Router = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Reload a suspended Dynamips router.
|
||||
"""
|
||||
@ -164,7 +164,12 @@ async def reload_router(node: Router = Depends(dep_node)):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def create_nio(adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: Router = Depends(dep_node)):
|
||||
async def create_nio(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: Router = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Add a NIO (Network Input/Output) to the node.
|
||||
"""
|
||||
@ -179,7 +184,12 @@ async def create_nio(adapter_number: int, port_number: int, nio_data: schemas.UD
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def update_nio(adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: Router = Depends(dep_node)):
|
||||
async def update_nio(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: Router = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Update a NIO (Network Input/Output) on the node.
|
||||
"""
|
||||
@ -192,7 +202,7 @@ async def update_nio(adapter_number: int, port_number: int, nio_data: schemas.UD
|
||||
|
||||
|
||||
@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)):
|
||||
async def delete_nio(adapter_number: int, port_number: int, node: Router = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete a NIO (Network Input/Output) from the node.
|
||||
"""
|
||||
@ -203,8 +213,11 @@ async def delete_nio(adapter_number: int, port_number: int, node: Router = Depen
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_capture(
|
||||
adapter_number: int, port_number: int, node_capture_data: schemas.NodeCapture, node: Router = Depends(dep_node)
|
||||
):
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: Router = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
"""
|
||||
@ -227,7 +240,7 @@ 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)):
|
||||
async def stop_capture(adapter_number: int, port_number: int, node: Router = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
"""
|
||||
@ -236,7 +249,11 @@ async def stop_capture(adapter_number: int, port_number: int, node: Router = Dep
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: Router = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
node: Router = Depends(dep_node)
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
"""
|
||||
@ -266,8 +283,8 @@ async def get_auto_idlepc(node: Router = Depends(dep_node)) -> dict:
|
||||
return {"idlepc": idlepc}
|
||||
|
||||
|
||||
@router.post("/{node_id}/duplicate", status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_router(destination_node_id: UUID, node: Router = Depends(dep_node)):
|
||||
@router.post("/{node_id}/duplicate", response_model=schemas.Dynamips, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_router(destination_node_id: UUID, node: Router = Depends(dep_node)) -> schemas.Dynamips:
|
||||
"""
|
||||
Duplicate a router.
|
||||
"""
|
||||
@ -277,7 +294,7 @@ async def duplicate_router(destination_node_id: UUID, node: Router = Depends(dep
|
||||
|
||||
|
||||
@router.websocket("/{node_id}/console/ws")
|
||||
async def console_ws(websocket: WebSocket, node: Router = Depends(dep_node)):
|
||||
async def console_ws(websocket: WebSocket, node: Router = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Console WebSocket.
|
||||
"""
|
||||
@ -286,6 +303,6 @@ 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)):
|
||||
async def reset_console(node: Router = Depends(dep_node)) -> None:
|
||||
|
||||
await node.reset_console()
|
||||
|
@ -20,7 +20,7 @@ API routes for Ethernet hub nodes.
|
||||
|
||||
import os
|
||||
|
||||
from fastapi import APIRouter, Depends, Body, status
|
||||
from fastapi import APIRouter, Depends, Body, Path, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
@ -34,7 +34,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_node(project_id: UUID, node_id: UUID):
|
||||
def dep_node(project_id: UUID, node_id: UUID) -> EthernetHub:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -50,7 +50,7 @@ def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create Ethernet hub node"}},
|
||||
)
|
||||
async def create_ethernet_hub(project_id: UUID, node_data: schemas.EthernetHubCreate):
|
||||
async def create_ethernet_hub(project_id: UUID, node_data: schemas.EthernetHubCreate) -> schemas.EthernetHub:
|
||||
"""
|
||||
Create a new Ethernet hub.
|
||||
"""
|
||||
@ -69,7 +69,7 @@ async def create_ethernet_hub(project_id: UUID, node_data: schemas.EthernetHubCr
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.EthernetHub)
|
||||
def get_ethernet_hub(node: EthernetHub = Depends(dep_node)):
|
||||
def get_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> schemas.EthernetHub:
|
||||
"""
|
||||
Return an Ethernet hub.
|
||||
"""
|
||||
@ -80,7 +80,7 @@ def get_ethernet_hub(node: EthernetHub = Depends(dep_node)):
|
||||
@router.post("/{node_id}/duplicate", response_model=schemas.EthernetHub, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_ethernet_hub(
|
||||
destination_node_id: UUID = Body(..., embed=True), node: EthernetHub = Depends(dep_node)
|
||||
):
|
||||
) -> schemas.EthernetHub:
|
||||
"""
|
||||
Duplicate an Ethernet hub.
|
||||
"""
|
||||
@ -90,7 +90,10 @@ async def duplicate_ethernet_hub(
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.EthernetHub)
|
||||
async def update_ethernet_hub(node_data: schemas.EthernetHubUpdate, node: EthernetHub = Depends(dep_node)):
|
||||
async def update_ethernet_hub(
|
||||
node_data: schemas.EthernetHubUpdate,
|
||||
node: EthernetHub = Depends(dep_node)
|
||||
) -> schemas.EthernetHub:
|
||||
"""
|
||||
Update an Ethernet hub.
|
||||
"""
|
||||
@ -105,7 +108,7 @@ async def update_ethernet_hub(node_data: schemas.EthernetHubUpdate, node: Ethern
|
||||
|
||||
|
||||
@router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_ethernet_hub(node: EthernetHub = Depends(dep_node)):
|
||||
async def delete_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete an Ethernet hub.
|
||||
"""
|
||||
@ -114,7 +117,7 @@ async def delete_ethernet_hub(node: EthernetHub = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def start_ethernet_hub(node: EthernetHub = Depends(dep_node)):
|
||||
def start_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start an Ethernet hub.
|
||||
This endpoint results in no action since Ethernet hub nodes are always on.
|
||||
@ -124,7 +127,7 @@ def start_ethernet_hub(node: EthernetHub = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def stop_ethernet_hub(node: EthernetHub = Depends(dep_node)):
|
||||
def stop_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop an Ethernet hub.
|
||||
This endpoint results in no action since Ethernet hub nodes are always on.
|
||||
@ -134,7 +137,7 @@ def stop_ethernet_hub(node: EthernetHub = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def suspend_ethernet_hub(node: EthernetHub = Depends(dep_node)):
|
||||
def suspend_ethernet_hub(node: EthernetHub = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend an Ethernet hub.
|
||||
This endpoint results in no action since Ethernet hub nodes are always on.
|
||||
@ -149,8 +152,12 @@ def suspend_ethernet_hub(node: EthernetHub = Depends(dep_node)):
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def create_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: EthernetHub = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: EthernetHub = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Add a NIO (Network Input/Output) to the node.
|
||||
The adapter number on the hub is always 0.
|
||||
@ -162,7 +169,12 @@ 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: EthernetHub = Depends(dep_node)):
|
||||
async def delete_nio(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: EthernetHub = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Delete a NIO (Network Input/Output) from the node.
|
||||
The adapter number on the hub is always 0.
|
||||
@ -174,8 +186,12 @@ async def delete_nio(adapter_number: int, port_number: int, node: EthernetHub =
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_capture(
|
||||
adapter_number: int, port_number: int, node_capture_data: schemas.NodeCapture, node: EthernetHub = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: EthernetHub = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
The adapter number on the hub is always 0.
|
||||
@ -189,7 +205,12 @@ 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: EthernetHub = Depends(dep_node)):
|
||||
async def stop_capture(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: EthernetHub = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
The adapter number on the hub is always 0.
|
||||
@ -199,7 +220,12 @@ async def stop_capture(adapter_number: int, port_number: int, node: EthernetHub
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: EthernetHub = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: EthernetHub = Depends(dep_node)
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
The adapter number on the hub is always 0.
|
||||
|
@ -20,7 +20,7 @@ API routes for Ethernet switch nodes.
|
||||
|
||||
import os
|
||||
|
||||
from fastapi import APIRouter, Depends, Body, status
|
||||
from fastapi import APIRouter, Depends, Body, Path, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
@ -34,7 +34,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_node(project_id: UUID, node_id: UUID):
|
||||
def dep_node(project_id: UUID, node_id: UUID) -> EthernetSwitch:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -50,7 +50,7 @@ def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create Ethernet switch node"}},
|
||||
)
|
||||
async def create_ethernet_switch(project_id: UUID, node_data: schemas.EthernetSwitchCreate):
|
||||
async def create_ethernet_switch(project_id: UUID, node_data: schemas.EthernetSwitchCreate) -> schemas.EthernetSwitch:
|
||||
"""
|
||||
Create a new Ethernet switch.
|
||||
"""
|
||||
@ -72,15 +72,16 @@ async def create_ethernet_switch(project_id: UUID, node_data: schemas.EthernetSw
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.EthernetSwitch)
|
||||
def get_ethernet_switch(node: EthernetSwitch = Depends(dep_node)):
|
||||
def get_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> schemas.EthernetSwitch:
|
||||
|
||||
return node.asdict()
|
||||
|
||||
|
||||
@router.post("/{node_id}/duplicate", response_model=schemas.EthernetSwitch, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_ethernet_switch(
|
||||
destination_node_id: UUID = Body(..., embed=True), node: EthernetSwitch = Depends(dep_node)
|
||||
):
|
||||
destination_node_id: UUID = Body(..., embed=True),
|
||||
node: EthernetSwitch = Depends(dep_node)
|
||||
) -> schemas.EthernetSwitch:
|
||||
"""
|
||||
Duplicate an Ethernet switch.
|
||||
"""
|
||||
@ -90,7 +91,10 @@ async def duplicate_ethernet_switch(
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.EthernetSwitch)
|
||||
async def update_ethernet_switch(node_data: schemas.EthernetSwitchUpdate, node: EthernetSwitch = Depends(dep_node)):
|
||||
async def update_ethernet_switch(
|
||||
node_data: schemas.EthernetSwitchUpdate,
|
||||
node: EthernetSwitch = Depends(dep_node)
|
||||
) -> schemas.EthernetSwitch:
|
||||
"""
|
||||
Update an Ethernet switch.
|
||||
"""
|
||||
@ -108,7 +112,7 @@ async def update_ethernet_switch(node_data: schemas.EthernetSwitchUpdate, node:
|
||||
|
||||
|
||||
@router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_ethernet_switch(node: EthernetSwitch = Depends(dep_node)):
|
||||
async def delete_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete an Ethernet switch.
|
||||
"""
|
||||
@ -117,7 +121,7 @@ async def delete_ethernet_switch(node: EthernetSwitch = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def start_ethernet_switch(node: EthernetSwitch = Depends(dep_node)):
|
||||
def start_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start an Ethernet switch.
|
||||
This endpoint results in no action since Ethernet switch nodes are always on.
|
||||
@ -127,7 +131,7 @@ def start_ethernet_switch(node: EthernetSwitch = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def stop_ethernet_switch(node: EthernetSwitch = Depends(dep_node)):
|
||||
def stop_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop an Ethernet switch.
|
||||
This endpoint results in no action since Ethernet switch nodes are always on.
|
||||
@ -137,7 +141,7 @@ def stop_ethernet_switch(node: EthernetSwitch = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def suspend_ethernet_switch(node: EthernetSwitch = Depends(dep_node)):
|
||||
def suspend_ethernet_switch(node: EthernetSwitch = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend an Ethernet switch.
|
||||
This endpoint results in no action since Ethernet switch nodes are always on.
|
||||
@ -152,8 +156,12 @@ def suspend_ethernet_switch(node: EthernetSwitch = Depends(dep_node)):
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def create_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: EthernetSwitch = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: EthernetSwitch = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
|
||||
nio = await Dynamips.instance().create_nio(node, jsonable_encoder(nio_data, exclude_unset=True))
|
||||
await node.add_nio(nio, port_number)
|
||||
@ -161,7 +169,12 @@ 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: EthernetSwitch = Depends(dep_node)):
|
||||
async def delete_nio(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: EthernetSwitch = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Delete a NIO (Network Input/Output) from the node.
|
||||
The adapter number on the switch is always 0.
|
||||
@ -173,11 +186,12 @@ async def delete_nio(adapter_number: int, port_number: int, node: EthernetSwitch
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_capture(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: EthernetSwitch = Depends(dep_node),
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: EthernetSwitch = Depends(dep_node),
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
The adapter number on the switch is always 0.
|
||||
@ -191,7 +205,12 @@ 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: EthernetSwitch = Depends(dep_node)):
|
||||
async def stop_capture(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: EthernetSwitch = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
The adapter number on the switch is always 0.
|
||||
@ -201,7 +220,12 @@ async def stop_capture(adapter_number: int, port_number: int, node: EthernetSwit
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: EthernetSwitch = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: EthernetSwitch = Depends(dep_node)
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
The adapter number on the switch is always 0.
|
||||
|
@ -20,7 +20,7 @@ API routes for Frame Relay switch nodes.
|
||||
|
||||
import os
|
||||
|
||||
from fastapi import APIRouter, Depends, Body, status
|
||||
from fastapi import APIRouter, Depends, Body, Path, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
@ -34,7 +34,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_node(project_id: UUID, node_id: UUID):
|
||||
def dep_node(project_id: UUID, node_id: UUID) -> FrameRelaySwitch:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -50,7 +50,10 @@ def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create Frame Relay switch node"}},
|
||||
)
|
||||
async def create_frame_relay_switch(project_id: UUID, node_data: schemas.FrameRelaySwitchCreate):
|
||||
async def create_frame_relay_switch(
|
||||
project_id: UUID,
|
||||
node_data: schemas.FrameRelaySwitchCreate
|
||||
) -> schemas.FrameRelaySwitch:
|
||||
"""
|
||||
Create a new Frame Relay switch node.
|
||||
"""
|
||||
@ -69,7 +72,7 @@ async def create_frame_relay_switch(project_id: UUID, node_data: schemas.FrameRe
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.FrameRelaySwitch)
|
||||
def get_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)):
|
||||
def get_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> schemas.FrameRelaySwitch:
|
||||
"""
|
||||
Return a Frame Relay switch node.
|
||||
"""
|
||||
@ -79,8 +82,9 @@ def get_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)):
|
||||
|
||||
@router.post("/{node_id}/duplicate", response_model=schemas.FrameRelaySwitch, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_frame_relay_switch(
|
||||
destination_node_id: UUID = Body(..., embed=True), node: FrameRelaySwitch = Depends(dep_node)
|
||||
):
|
||||
destination_node_id: UUID = Body(..., embed=True),
|
||||
node: FrameRelaySwitch = Depends(dep_node)
|
||||
) -> schemas.FrameRelaySwitch:
|
||||
"""
|
||||
Duplicate a Frame Relay switch node.
|
||||
"""
|
||||
@ -91,8 +95,9 @@ async def duplicate_frame_relay_switch(
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.FrameRelaySwitch)
|
||||
async def update_frame_relay_switch(
|
||||
node_data: schemas.FrameRelaySwitchUpdate, node: FrameRelaySwitch = Depends(dep_node)
|
||||
):
|
||||
node_data: schemas.FrameRelaySwitchUpdate,
|
||||
node: FrameRelaySwitch = Depends(dep_node)
|
||||
) -> schemas.FrameRelaySwitch:
|
||||
"""
|
||||
Update an Frame Relay switch node.
|
||||
"""
|
||||
@ -107,7 +112,7 @@ 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)):
|
||||
async def delete_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete a Frame Relay switch node.
|
||||
"""
|
||||
@ -116,7 +121,7 @@ async def delete_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def start_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)):
|
||||
def start_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start a Frame Relay switch node.
|
||||
This endpoint results in no action since Frame Relay switch nodes are always on.
|
||||
@ -126,7 +131,7 @@ def start_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def stop_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)):
|
||||
def stop_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop a Frame Relay switch node.
|
||||
This endpoint results in no action since Frame Relay switch nodes are always on.
|
||||
@ -136,7 +141,7 @@ def stop_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def suspend_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)):
|
||||
def suspend_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend a Frame Relay switch node.
|
||||
This endpoint results in no action since Frame Relay switch nodes are always on.
|
||||
@ -151,8 +156,12 @@ def suspend_frame_relay_switch(node: FrameRelaySwitch = Depends(dep_node)):
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def create_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: FrameRelaySwitch = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: FrameRelaySwitch = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Add a NIO (Network Input/Output) to the node.
|
||||
The adapter number on the switch is always 0.
|
||||
@ -164,7 +173,12 @@ 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: FrameRelaySwitch = Depends(dep_node)):
|
||||
async def delete_nio(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: FrameRelaySwitch = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Remove a NIO (Network Input/Output) from the node.
|
||||
The adapter number on the switch is always 0.
|
||||
@ -176,11 +190,12 @@ async def delete_nio(adapter_number: int, port_number: int, node: FrameRelaySwit
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_capture(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: FrameRelaySwitch = Depends(dep_node),
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: FrameRelaySwitch = Depends(dep_node),
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
The adapter number on the switch is always 0.
|
||||
@ -194,7 +209,12 @@ 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: FrameRelaySwitch = Depends(dep_node)):
|
||||
async def stop_capture(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: FrameRelaySwitch = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
The adapter number on the switch is always 0.
|
||||
@ -204,7 +224,12 @@ async def stop_capture(adapter_number: int, port_number: int, node: FrameRelaySw
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: FrameRelaySwitch = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: FrameRelaySwitch = Depends(dep_node)
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
The adapter number on the hub is always 0.
|
||||
|
@ -54,7 +54,7 @@ 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):
|
||||
async def upload_dynamips_image(filename: str, request: Request) -> None:
|
||||
"""
|
||||
Upload a Dynamips IOS image.
|
||||
"""
|
||||
@ -64,7 +64,7 @@ async def upload_dynamips_image(filename: str, request: Request):
|
||||
|
||||
|
||||
@router.get("/dynamips/images/{filename:path}")
|
||||
async def download_dynamips_image(filename: str):
|
||||
async def download_dynamips_image(filename: str) -> FileResponse:
|
||||
"""
|
||||
Download a Dynamips IOS image.
|
||||
"""
|
||||
@ -93,7 +93,7 @@ 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):
|
||||
async def upload_iou_image(filename: str, request: Request) -> None:
|
||||
"""
|
||||
Upload an IOU image.
|
||||
"""
|
||||
@ -103,7 +103,7 @@ async def upload_iou_image(filename: str, request: Request):
|
||||
|
||||
|
||||
@router.get("/iou/images/{filename:path}")
|
||||
async def download_iou_image(filename: str):
|
||||
async def download_iou_image(filename: str) -> FileResponse:
|
||||
"""
|
||||
Download an IOU image.
|
||||
"""
|
||||
@ -129,14 +129,14 @@ 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):
|
||||
async def upload_qemu_image(filename: str, request: Request) -> None:
|
||||
|
||||
qemu_manager = Qemu.instance()
|
||||
await qemu_manager.write_image(urllib.parse.unquote(filename), request.stream())
|
||||
|
||||
|
||||
@router.get("/qemu/images/{filename:path}")
|
||||
async def download_qemu_image(filename: str):
|
||||
async def download_qemu_image(filename: str) -> FileResponse:
|
||||
|
||||
qemu_manager = Qemu.instance()
|
||||
filename = urllib.parse.unquote(filename)
|
||||
|
@ -35,7 +35,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_node(project_id: UUID, node_id: UUID):
|
||||
def dep_node(project_id: UUID, node_id: UUID) -> IOUVM:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -51,7 +51,7 @@ def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create IOU node"}},
|
||||
)
|
||||
async def create_iou_node(project_id: UUID, node_data: schemas.IOUCreate):
|
||||
async def create_iou_node(project_id: UUID, node_data: schemas.IOUCreate) -> schemas.IOU:
|
||||
"""
|
||||
Create a new IOU node.
|
||||
"""
|
||||
@ -83,7 +83,7 @@ async def create_iou_node(project_id: UUID, node_data: schemas.IOUCreate):
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.IOU)
|
||||
def get_iou_node(node: IOUVM = Depends(dep_node)):
|
||||
def get_iou_node(node: IOUVM = Depends(dep_node)) -> schemas.IOU:
|
||||
"""
|
||||
Return an IOU node.
|
||||
"""
|
||||
@ -92,7 +92,7 @@ def get_iou_node(node: IOUVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.IOU)
|
||||
async def update_iou_node(node_data: schemas.IOUUpdate, node: IOUVM = Depends(dep_node)):
|
||||
async def update_iou_node(node_data: schemas.IOUUpdate, node: IOUVM = Depends(dep_node)) -> schemas.IOU:
|
||||
"""
|
||||
Update an IOU node.
|
||||
"""
|
||||
@ -113,7 +113,7 @@ 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)):
|
||||
async def delete_iou_node(node: IOUVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete an IOU node.
|
||||
"""
|
||||
@ -122,7 +122,10 @@ async def delete_iou_node(node: IOUVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/duplicate", response_model=schemas.IOU, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_iou_node(destination_node_id: UUID = Body(..., embed=True), node: IOUVM = Depends(dep_node)):
|
||||
async def duplicate_iou_node(
|
||||
destination_node_id: UUID = Body(..., embed=True),
|
||||
node: IOUVM = Depends(dep_node)
|
||||
) -> schemas.IOU:
|
||||
"""
|
||||
Duplicate an IOU node.
|
||||
"""
|
||||
@ -132,7 +135,7 @@ async def duplicate_iou_node(destination_node_id: UUID = Body(..., embed=True),
|
||||
|
||||
|
||||
@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)):
|
||||
async def start_iou_node(start_data: schemas.IOUStart, node: IOUVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start an IOU node.
|
||||
"""
|
||||
@ -147,7 +150,7 @@ async def start_iou_node(start_data: schemas.IOUStart, node: IOUVM = Depends(dep
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_iou_node(node: IOUVM = Depends(dep_node)):
|
||||
async def stop_iou_node(node: IOUVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop an IOU node.
|
||||
"""
|
||||
@ -156,7 +159,7 @@ async def stop_iou_node(node: IOUVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def suspend_iou_node(node: IOUVM = Depends(dep_node)):
|
||||
def suspend_iou_node(node: IOUVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend an IOU node.
|
||||
Does nothing since IOU doesn't support being suspended.
|
||||
@ -166,7 +169,7 @@ def suspend_iou_node(node: IOUVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reload_iou_node(node: IOUVM = Depends(dep_node)):
|
||||
async def reload_iou_node(node: IOUVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Reload an IOU node.
|
||||
"""
|
||||
@ -184,7 +187,7 @@ async def create_iou_node_nio(
|
||||
port_number: int,
|
||||
nio_data: Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
node: IOUVM = Depends(dep_node),
|
||||
):
|
||||
) -> Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO]:
|
||||
"""
|
||||
Add a NIO (Network Input/Output) to the node.
|
||||
"""
|
||||
@ -204,7 +207,7 @@ async def update_iou_node_nio(
|
||||
port_number: int,
|
||||
nio_data: Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
node: IOUVM = Depends(dep_node),
|
||||
):
|
||||
) -> Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO]:
|
||||
"""
|
||||
Update a NIO (Network Input/Output) on the node.
|
||||
"""
|
||||
@ -217,7 +220,7 @@ 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)):
|
||||
async def delete_iou_node_nio(adapter_number: int, port_number: int, node: IOUVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete a NIO (Network Input/Output) from the node.
|
||||
"""
|
||||
@ -227,8 +230,11 @@ async def delete_iou_node_nio(adapter_number: int, port_number: int, node: IOUVM
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_iou_node_capture(
|
||||
adapter_number: int, port_number: int, node_capture_data: schemas.NodeCapture, node: IOUVM = Depends(dep_node)
|
||||
):
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: IOUVM = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
"""
|
||||
@ -241,7 +247,7 @@ 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)):
|
||||
async def stop_iou_node_capture(adapter_number: int, port_number: int, node: IOUVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
"""
|
||||
@ -250,7 +256,11 @@ async def stop_iou_node_capture(adapter_number: int, port_number: int, node: IOU
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: IOUVM = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
node: IOUVM = Depends(dep_node)
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
"""
|
||||
@ -261,7 +271,7 @@ async def stream_pcap_file(adapter_number: int, port_number: int, node: IOUVM =
|
||||
|
||||
|
||||
@router.websocket("/{node_id}/console/ws")
|
||||
async def console_ws(websocket: WebSocket, node: IOUVM = Depends(dep_node)):
|
||||
async def console_ws(websocket: WebSocket, node: IOUVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Console WebSocket.
|
||||
"""
|
||||
@ -270,6 +280,6 @@ async def console_ws(websocket: WebSocket, node: IOUVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/console/reset", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reset_console(node: IOUVM = Depends(dep_node)):
|
||||
async def reset_console(node: IOUVM = Depends(dep_node)) -> None:
|
||||
|
||||
await node.reset_console()
|
||||
|
@ -20,7 +20,7 @@ API routes for NAT nodes.
|
||||
|
||||
import os
|
||||
|
||||
from fastapi import APIRouter, Depends, status
|
||||
from fastapi import APIRouter, Depends, Path, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from typing import Union
|
||||
@ -35,7 +35,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_node(project_id: UUID, node_id: UUID):
|
||||
def dep_node(project_id: UUID, node_id: UUID) -> Nat:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -51,7 +51,7 @@ def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create NAT node"}},
|
||||
)
|
||||
async def create_nat_node(project_id: UUID, node_data: schemas.NATCreate):
|
||||
async def create_nat_node(project_id: UUID, node_data: schemas.NATCreate) -> schemas.NAT:
|
||||
"""
|
||||
Create a new NAT node.
|
||||
"""
|
||||
@ -71,7 +71,7 @@ async def create_nat_node(project_id: UUID, node_data: schemas.NATCreate):
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.NAT)
|
||||
def get_nat_node(node: Nat = Depends(dep_node)):
|
||||
def get_nat_node(node: Nat = Depends(dep_node)) -> schemas.NAT:
|
||||
"""
|
||||
Return a NAT node.
|
||||
"""
|
||||
@ -80,7 +80,7 @@ def get_nat_node(node: Nat = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.NAT)
|
||||
def update_nat_node(node_data: schemas.NATUpdate, node: Nat = Depends(dep_node)):
|
||||
def update_nat_node(node_data: schemas.NATUpdate, node: Nat = Depends(dep_node)) -> schemas.NAT:
|
||||
"""
|
||||
Update a NAT node.
|
||||
"""
|
||||
@ -94,7 +94,7 @@ 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)):
|
||||
async def delete_nat_node(node: Nat = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete a cloud node.
|
||||
"""
|
||||
@ -103,7 +103,7 @@ async def delete_nat_node(node: Nat = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def start_nat_node(node: Nat = Depends(dep_node)):
|
||||
async def start_nat_node(node: Nat = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start a NAT node.
|
||||
"""
|
||||
@ -112,7 +112,7 @@ async def start_nat_node(node: Nat = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_nat_node(node: Nat = Depends(dep_node)):
|
||||
async def stop_nat_node(node: Nat = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop a NAT node.
|
||||
This endpoint results in no action since cloud nodes cannot be stopped.
|
||||
@ -122,7 +122,7 @@ async def stop_nat_node(node: Nat = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def suspend_nat_node(node: Nat = Depends(dep_node)):
|
||||
async def suspend_nat_node(node: Nat = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend a NAT node.
|
||||
This endpoint results in no action since NAT nodes cannot be suspended.
|
||||
@ -137,11 +137,12 @@ async def suspend_nat_node(node: Nat = Depends(dep_node)):
|
||||
response_model=Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
)
|
||||
async def create_nat_node_nio(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
nio_data: Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
node: Nat = Depends(dep_node),
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
nio_data: Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
node: Nat = Depends(dep_node),
|
||||
) -> Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO]:
|
||||
"""
|
||||
Add a NIO (Network Input/Output) to the node.
|
||||
The adapter number on the cloud is always 0.
|
||||
@ -158,11 +159,12 @@ async def create_nat_node_nio(
|
||||
response_model=Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
)
|
||||
async def update_nat_node_nio(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
nio_data: Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
node: Nat = Depends(dep_node),
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
nio_data: Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO],
|
||||
node: Nat = Depends(dep_node),
|
||||
) -> Union[schemas.EthernetNIO, schemas.TAPNIO, schemas.UDPNIO]:
|
||||
"""
|
||||
Update a NIO (Network Input/Output) to the node.
|
||||
The adapter number on the cloud is always 0.
|
||||
@ -176,7 +178,12 @@ async def update_nat_node_nio(
|
||||
|
||||
|
||||
@router.delete("/{node_id}/adapters/{adapter_number}/ports/{port_number}/nio", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_nat_node_nio(adapter_number: int, port_number: int, node: Nat = Depends(dep_node)):
|
||||
async def delete_nat_node_nio(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: Nat = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Remove a NIO (Network Input/Output) from the node.
|
||||
The adapter number on the cloud is always 0.
|
||||
@ -187,8 +194,12 @@ async def delete_nat_node_nio(adapter_number: int, port_number: int, node: Nat =
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_nat_node_capture(
|
||||
adapter_number: int, port_number: int, node_capture_data: schemas.NodeCapture, node: Nat = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: Nat = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
The adapter number on the cloud is always 0.
|
||||
@ -202,7 +213,12 @@ async def start_nat_node_capture(
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop", status_code=status.HTTP_204_NO_CONTENT
|
||||
)
|
||||
async def stop_nat_node_capture(adapter_number: int, port_number: int, node: Nat = Depends(dep_node)):
|
||||
async def stop_nat_node_capture(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: Nat = Depends(dep_node)
|
||||
):
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
The adapter number on the cloud is always 0.
|
||||
@ -212,7 +228,12 @@ async def stop_nat_node_capture(adapter_number: int, port_number: int, node: Nat
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: Nat = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: Nat = Depends(dep_node)
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
The adapter number on the cloud is always 0.
|
||||
|
@ -31,7 +31,7 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.websocket("/notifications/ws")
|
||||
async def notification_ws(websocket: WebSocket):
|
||||
async def notification_ws(websocket: WebSocket) -> None:
|
||||
"""
|
||||
Receive project notifications about the project from WebSocket.
|
||||
"""
|
||||
|
@ -41,7 +41,7 @@ router = APIRouter()
|
||||
_notifications_listening = {}
|
||||
|
||||
|
||||
def dep_project(project_id: UUID):
|
||||
def dep_project(project_id: UUID) -> Project:
|
||||
"""
|
||||
Dependency to retrieve a project.
|
||||
"""
|
||||
@ -52,7 +52,7 @@ def dep_project(project_id: UUID):
|
||||
|
||||
|
||||
@router.get("/projects", response_model=List[schemas.Project])
|
||||
def get_compute_projects():
|
||||
def get_compute_projects() -> List[schemas.Project]:
|
||||
"""
|
||||
Get all projects opened on the compute.
|
||||
"""
|
||||
@ -62,7 +62,7 @@ def get_compute_projects():
|
||||
|
||||
|
||||
@router.post("/projects", status_code=status.HTTP_201_CREATED, response_model=schemas.Project)
|
||||
def create_compute_project(project_data: schemas.ProjectCreate):
|
||||
def create_compute_project(project_data: schemas.ProjectCreate) -> schemas.Project:
|
||||
"""
|
||||
Create a new project on the compute.
|
||||
"""
|
||||
@ -79,7 +79,10 @@ def create_compute_project(project_data: schemas.ProjectCreate):
|
||||
|
||||
|
||||
@router.put("/projects/{project_id}", response_model=schemas.Project)
|
||||
async def update_compute_project(project_data: schemas.ProjectUpdate, project: Project = Depends(dep_project)):
|
||||
async def update_compute_project(
|
||||
project_data: schemas.ProjectUpdate,
|
||||
project: Project = Depends(dep_project)
|
||||
) -> schemas.Project:
|
||||
"""
|
||||
Update project on the compute.
|
||||
"""
|
||||
@ -89,7 +92,7 @@ async def update_compute_project(project_data: schemas.ProjectUpdate, project: P
|
||||
|
||||
|
||||
@router.get("/projects/{project_id}", response_model=schemas.Project)
|
||||
def get_compute_project(project: Project = Depends(dep_project)):
|
||||
def get_compute_project(project: Project = Depends(dep_project)) -> schemas.Project:
|
||||
"""
|
||||
Return a project from the compute.
|
||||
"""
|
||||
@ -98,7 +101,7 @@ def get_compute_project(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.post("/projects/{project_id}/close", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def close_compute_project(project: Project = Depends(dep_project)):
|
||||
async def close_compute_project(project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Close a project on the compute.
|
||||
"""
|
||||
@ -116,7 +119,7 @@ async def close_compute_project(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.delete("/projects/{project_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_compute_project(project: Project = Depends(dep_project)):
|
||||
async def delete_compute_project(project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Delete project from the compute.
|
||||
"""
|
||||
@ -180,7 +183,7 @@ async def delete_compute_project(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.get("/projects/{project_id}/files", response_model=List[schemas.ProjectFile])
|
||||
async def get_compute_project_files(project: Project = Depends(dep_project)):
|
||||
async def get_compute_project_files(project: Project = Depends(dep_project)) -> List[schemas.ProjectFile]:
|
||||
"""
|
||||
Return files belonging to a project.
|
||||
"""
|
||||
@ -189,7 +192,7 @@ async def get_compute_project_files(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.get("/projects/{project_id}/files/{file_path:path}")
|
||||
async def get_compute_project_file(file_path: str, project: Project = Depends(dep_project)):
|
||||
async def get_compute_project_file(file_path: str, project: Project = Depends(dep_project)) -> FileResponse:
|
||||
"""
|
||||
Get a file from a project.
|
||||
"""
|
||||
@ -208,7 +211,7 @@ 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)):
|
||||
async def write_compute_project_file(file_path: str, request: Request, project: Project = Depends(dep_project)) -> None:
|
||||
|
||||
path = os.path.normpath(file_path)
|
||||
|
||||
|
@ -19,9 +19,8 @@ API routes for Qemu nodes.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from fastapi import APIRouter, WebSocket, Depends, Body, status
|
||||
from fastapi import APIRouter, WebSocket, Depends, Body, Path, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
@ -36,7 +35,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_node(project_id: UUID, node_id: UUID):
|
||||
def dep_node(project_id: UUID, node_id: UUID) -> QemuVM:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -52,7 +51,7 @@ def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create Qemu node"}},
|
||||
)
|
||||
async def create_qemu_node(project_id: UUID, node_data: schemas.QemuCreate):
|
||||
async def create_qemu_node(project_id: UUID, node_data: schemas.QemuCreate) -> schemas.Qemu:
|
||||
"""
|
||||
Create a new Qemu node.
|
||||
"""
|
||||
@ -80,7 +79,7 @@ async def create_qemu_node(project_id: UUID, node_data: schemas.QemuCreate):
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.Qemu)
|
||||
def get_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
def get_qemu_node(node: QemuVM = Depends(dep_node)) -> schemas.Qemu:
|
||||
"""
|
||||
Return a Qemu node.
|
||||
"""
|
||||
@ -89,7 +88,7 @@ def get_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.Qemu)
|
||||
async def update_qemu_node(node_data: schemas.QemuUpdate, node: QemuVM = Depends(dep_node)):
|
||||
async def update_qemu_node(node_data: schemas.QemuUpdate, node: QemuVM = Depends(dep_node)) -> schemas.Qemu:
|
||||
"""
|
||||
Update a Qemu node.
|
||||
"""
|
||||
@ -105,7 +104,7 @@ 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)):
|
||||
async def delete_qemu_node(node: QemuVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete a Qemu node.
|
||||
"""
|
||||
@ -114,7 +113,10 @@ async def delete_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/duplicate", response_model=schemas.Qemu, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_qemu_node(destination_node_id: UUID = Body(..., embed=True), node: QemuVM = Depends(dep_node)):
|
||||
async def duplicate_qemu_node(
|
||||
destination_node_id: UUID = Body(..., embed=True),
|
||||
node: QemuVM = Depends(dep_node)
|
||||
) -> schemas.Qemu:
|
||||
"""
|
||||
Duplicate a Qemu node.
|
||||
"""
|
||||
@ -124,13 +126,13 @@ async def duplicate_qemu_node(destination_node_id: UUID = Body(..., embed=True),
|
||||
|
||||
|
||||
@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)):
|
||||
async def resize_qemu_node_disk(node_data: schemas.QemuDiskResize, node: QemuVM = Depends(dep_node)) -> None:
|
||||
|
||||
await node.resize_disk(node_data.drive_name, node_data.extend)
|
||||
|
||||
|
||||
@router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def start_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
async def start_qemu_node(node: QemuVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start a Qemu node.
|
||||
"""
|
||||
@ -146,7 +148,7 @@ async def start_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
async def stop_qemu_node(node: QemuVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop a Qemu node.
|
||||
"""
|
||||
@ -155,7 +157,7 @@ async def stop_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reload_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
async def reload_qemu_node(node: QemuVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Reload a Qemu node.
|
||||
"""
|
||||
@ -164,7 +166,7 @@ async def reload_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def suspend_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
async def suspend_qemu_node(node: QemuVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend a Qemu node.
|
||||
"""
|
||||
@ -173,7 +175,7 @@ async def suspend_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/resume", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def resume_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
async def resume_qemu_node(node: QemuVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Resume a Qemu node.
|
||||
"""
|
||||
@ -187,8 +189,12 @@ async def resume_qemu_node(node: QemuVM = Depends(dep_node)):
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def create_qemu_node_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: QemuVM = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: QemuVM = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Add a NIO (Network Input/Output) to the node.
|
||||
The port number on the Qemu node is always 0.
|
||||
@ -205,8 +211,12 @@ async def create_qemu_node_nio(
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def update_qemu_node_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: QemuVM = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: QemuVM = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Update a NIO (Network Input/Output) on the node.
|
||||
The port number on the Qemu node is always 0.
|
||||
@ -222,7 +232,11 @@ async def update_qemu_node_nio(
|
||||
|
||||
|
||||
@router.delete("/{node_id}/adapters/{adapter_number}/ports/{port_number}/nio", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_qemu_node_nio(adapter_number: int, port_number: int, node: QemuVM = Depends(dep_node)):
|
||||
async def delete_qemu_node_nio(
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node: QemuVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Delete a NIO (Network Input/Output) from the node.
|
||||
The port number on the Qemu node is always 0.
|
||||
@ -233,8 +247,12 @@ async def delete_qemu_node_nio(adapter_number: int, port_number: int, node: Qemu
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_qemu_node_capture(
|
||||
adapter_number: int, port_number: int, node_capture_data: schemas.NodeCapture, node: QemuVM = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: QemuVM = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
The port number on the Qemu node is always 0.
|
||||
@ -248,7 +266,11 @@ async def start_qemu_node_capture(
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop", status_code=status.HTTP_204_NO_CONTENT
|
||||
)
|
||||
async def stop_qemu_node_capture(adapter_number: int, port_number: int, node: QemuVM = Depends(dep_node)):
|
||||
async def stop_qemu_node_capture(
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node: QemuVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
The port number on the Qemu node is always 0.
|
||||
@ -258,7 +280,10 @@ async def stop_qemu_node_capture(adapter_number: int, port_number: int, node: Qe
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: QemuVM = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node: QemuVM = Depends(dep_node)) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
The port number on the Qemu node is always 0.
|
||||
@ -270,7 +295,7 @@ async def stream_pcap_file(adapter_number: int, port_number: int, node: QemuVM =
|
||||
|
||||
|
||||
@router.websocket("/{node_id}/console/ws")
|
||||
async def console_ws(websocket: WebSocket, node: QemuVM = Depends(dep_node)):
|
||||
async def console_ws(websocket: WebSocket, node: QemuVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Console WebSocket.
|
||||
"""
|
||||
@ -279,6 +304,6 @@ 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)):
|
||||
async def reset_console(node: QemuVM = Depends(dep_node)) -> None:
|
||||
|
||||
await node.reset_console()
|
||||
|
@ -20,7 +20,7 @@ API routes for VirtualBox nodes.
|
||||
|
||||
import os
|
||||
|
||||
from fastapi import APIRouter, WebSocket, Depends, status
|
||||
from fastapi import APIRouter, WebSocket, Depends, Path, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
@ -28,7 +28,6 @@ from uuid import UUID
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.virtualbox import VirtualBox
|
||||
from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError
|
||||
from gns3server.compute.project_manager import ProjectManager
|
||||
from gns3server.compute.virtualbox.virtualbox_vm import VirtualBoxVM
|
||||
|
||||
responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find project or VirtualBox node"}}
|
||||
@ -36,7 +35,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_node(project_id: UUID, node_id: UUID):
|
||||
def dep_node(project_id: UUID, node_id: UUID) -> VirtualBoxVM:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -52,7 +51,7 @@ def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create VirtualBox node"}},
|
||||
)
|
||||
async def create_virtualbox_node(project_id: UUID, node_data: schemas.VirtualBoxCreate):
|
||||
async def create_virtualbox_node(project_id: UUID, node_data: schemas.VirtualBoxCreate) -> schemas.VirtualBox:
|
||||
"""
|
||||
Create a new VirtualBox node.
|
||||
"""
|
||||
@ -84,7 +83,7 @@ async def create_virtualbox_node(project_id: UUID, node_data: schemas.VirtualBox
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.VirtualBox)
|
||||
def get_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
def get_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> schemas.VirtualBox:
|
||||
"""
|
||||
Return a VirtualBox node.
|
||||
"""
|
||||
@ -93,7 +92,10 @@ def get_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.VirtualBox)
|
||||
async def update_virtualbox_node(node_data: schemas.VirtualBoxUpdate, node: VirtualBoxVM = Depends(dep_node)):
|
||||
async def update_virtualbox_node(
|
||||
node_data: schemas.VirtualBoxUpdate,
|
||||
node: VirtualBoxVM = Depends(dep_node)
|
||||
) -> schemas.VirtualBox:
|
||||
"""
|
||||
Update a VirtualBox node.
|
||||
"""
|
||||
@ -135,7 +137,7 @@ async def update_virtualbox_node(node_data: schemas.VirtualBoxUpdate, node: Virt
|
||||
|
||||
|
||||
@router.delete("/{node_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
async def delete_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete a VirtualBox node.
|
||||
"""
|
||||
@ -144,7 +146,7 @@ async def delete_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def start_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
async def start_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start a VirtualBox node.
|
||||
"""
|
||||
@ -153,7 +155,7 @@ async def start_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
async def stop_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop a VirtualBox node.
|
||||
"""
|
||||
@ -162,7 +164,7 @@ async def stop_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def suspend_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
async def suspend_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend a VirtualBox node.
|
||||
"""
|
||||
@ -171,7 +173,7 @@ async def suspend_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/resume", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def resume_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
async def resume_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Resume a VirtualBox node.
|
||||
"""
|
||||
@ -180,7 +182,7 @@ async def resume_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reload_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
async def reload_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Reload a VirtualBox node.
|
||||
"""
|
||||
@ -194,8 +196,12 @@ async def reload_virtualbox_node(node: VirtualBoxVM = Depends(dep_node)):
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def create_virtualbox_node_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: VirtualBoxVM = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: VirtualBoxVM = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Add a NIO (Network Input/Output) to the node.
|
||||
The port number on the VirtualBox node is always 0.
|
||||
@ -212,8 +218,12 @@ async def create_virtualbox_node_nio(
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def update_virtualbox_node_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: VirtualBoxVM = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: VirtualBoxVM = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Update a NIO (Network Input/Output) on the node.
|
||||
The port number on the VirtualBox node is always 0.
|
||||
@ -229,7 +239,11 @@ async def update_virtualbox_node_nio(
|
||||
|
||||
|
||||
@router.delete("/{node_id}/adapters/{adapter_number}/ports/{port_number}/nio", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_virtualbox_node_nio(adapter_number: int, port_number: int, node: VirtualBoxVM = Depends(dep_node)):
|
||||
async def delete_virtualbox_node_nio(
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node: VirtualBoxVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Delete a NIO (Network Input/Output) from the node.
|
||||
The port number on the VirtualBox node is always 0.
|
||||
@ -240,11 +254,12 @@ async def delete_virtualbox_node_nio(adapter_number: int, port_number: int, node
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_virtualbox_node_capture(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: VirtualBoxVM = Depends(dep_node),
|
||||
):
|
||||
*,
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: VirtualBoxVM = Depends(dep_node),
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
The port number on the VirtualBox node is always 0.
|
||||
@ -258,7 +273,11 @@ async def start_virtualbox_node_capture(
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop", status_code=status.HTTP_204_NO_CONTENT
|
||||
)
|
||||
async def stop_virtualbox_node_capture(adapter_number: int, port_number: int, node: VirtualBoxVM = Depends(dep_node)):
|
||||
async def stop_virtualbox_node_capture(
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node: VirtualBoxVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
The port number on the VirtualBox node is always 0.
|
||||
@ -268,7 +287,11 @@ async def stop_virtualbox_node_capture(adapter_number: int, port_number: int, no
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: VirtualBoxVM = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node: VirtualBoxVM = Depends(dep_node)
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
The port number on the VirtualBox node is always 0.
|
||||
@ -280,7 +303,7 @@ async def stream_pcap_file(adapter_number: int, port_number: int, node: VirtualB
|
||||
|
||||
|
||||
@router.websocket("/{node_id}/console/ws")
|
||||
async def console_ws(websocket: WebSocket, node: VirtualBoxVM = Depends(dep_node)):
|
||||
async def console_ws(websocket: WebSocket, node: VirtualBoxVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Console WebSocket.
|
||||
"""
|
||||
@ -289,6 +312,6 @@ 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)):
|
||||
async def reset_console(node: VirtualBoxVM = Depends(dep_node)) -> None:
|
||||
|
||||
await node.reset_console()
|
||||
|
@ -20,7 +20,7 @@ API routes for VMware nodes.
|
||||
|
||||
import os
|
||||
|
||||
from fastapi import APIRouter, WebSocket, Depends, status
|
||||
from fastapi import APIRouter, WebSocket, Depends, Path, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
@ -35,7 +35,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_node(project_id: UUID, node_id: UUID):
|
||||
def dep_node(project_id: UUID, node_id: UUID) -> VMwareVM:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -51,7 +51,7 @@ def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create VMware node"}},
|
||||
)
|
||||
async def create_vmware_node(project_id: UUID, node_data: schemas.VMwareCreate):
|
||||
async def create_vmware_node(project_id: UUID, node_data: schemas.VMwareCreate) -> schemas.VMware:
|
||||
"""
|
||||
Create a new VMware node.
|
||||
"""
|
||||
@ -77,7 +77,7 @@ async def create_vmware_node(project_id: UUID, node_data: schemas.VMwareCreate):
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.VMware)
|
||||
def get_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
def get_vmware_node(node: VMwareVM = Depends(dep_node)) -> schemas.VMware:
|
||||
"""
|
||||
Return a VMware node.
|
||||
"""
|
||||
@ -86,7 +86,7 @@ def get_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.VMware)
|
||||
def update_vmware_node(node_data: schemas.VMwareUpdate, node: VMwareVM = Depends(dep_node)):
|
||||
def update_vmware_node(node_data: schemas.VMwareUpdate, node: VMwareVM = Depends(dep_node)) -> schemas.VMware:
|
||||
"""
|
||||
Update a VMware node.
|
||||
"""
|
||||
@ -103,7 +103,7 @@ 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)):
|
||||
async def delete_vmware_node(node: VMwareVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete a VMware node.
|
||||
"""
|
||||
@ -112,7 +112,7 @@ async def delete_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def start_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
async def start_vmware_node(node: VMwareVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start a VMware node.
|
||||
"""
|
||||
@ -121,7 +121,7 @@ async def start_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
async def stop_vmware_node(node: VMwareVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop a VMware node.
|
||||
"""
|
||||
@ -130,7 +130,7 @@ async def stop_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def suspend_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
async def suspend_vmware_node(node: VMwareVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend a VMware node.
|
||||
"""
|
||||
@ -139,7 +139,7 @@ async def suspend_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/resume", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def resume_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
async def resume_vmware_node(node: VMwareVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Resume a VMware node.
|
||||
"""
|
||||
@ -148,7 +148,7 @@ async def resume_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reload_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
async def reload_vmware_node(node: VMwareVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Reload a VMware node.
|
||||
"""
|
||||
@ -162,8 +162,12 @@ async def reload_vmware_node(node: VMwareVM = Depends(dep_node)):
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def create_vmware_node_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: VMwareVM = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: VMwareVM = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Add a NIO (Network Input/Output) to the node.
|
||||
The port number on the VMware node is always 0.
|
||||
@ -180,8 +184,12 @@ async def create_vmware_node_nio(
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def update_vmware_node_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: VMwareVM = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: VMwareVM = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Update a NIO (Network Input/Output) on the node.
|
||||
The port number on the VMware node is always 0.
|
||||
@ -195,7 +203,11 @@ async def update_vmware_node_nio(
|
||||
|
||||
|
||||
@router.delete("/{node_id}/adapters/{adapter_number}/ports/{port_number}/nio", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_vmware_node_nio(adapter_number: int, port_number: int, node: VMwareVM = Depends(dep_node)):
|
||||
async def delete_vmware_node_nio(
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node: VMwareVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Delete a NIO (Network Input/Output) from the node.
|
||||
The port number on the VMware node is always 0.
|
||||
@ -206,8 +218,12 @@ async def delete_vmware_node_nio(adapter_number: int, port_number: int, node: VM
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_vmware_node_capture(
|
||||
adapter_number: int, port_number: int, node_capture_data: schemas.NodeCapture, node: VMwareVM = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: VMwareVM = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
The port number on the VMware node is always 0.
|
||||
@ -221,7 +237,11 @@ async def start_vmware_node_capture(
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop", status_code=status.HTTP_204_NO_CONTENT
|
||||
)
|
||||
async def stop_vmware_node_capture(adapter_number: int, port_number: int, node: VMwareVM = Depends(dep_node)):
|
||||
async def stop_vmware_node_capture(
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node: VMwareVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
The port number on the VMware node is always 0.
|
||||
@ -231,7 +251,11 @@ async def stop_vmware_node_capture(adapter_number: int, port_number: int, node:
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: VMwareVM = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
adapter_number: int,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node: VMwareVM = Depends(dep_node)
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
The port number on the VMware node is always 0.
|
||||
@ -256,7 +280,7 @@ def allocate_vmnet(node: VMwareVM = Depends(dep_node)) -> dict:
|
||||
|
||||
|
||||
@router.websocket("/{node_id}/console/ws")
|
||||
async def console_ws(websocket: WebSocket, node: VMwareVM = Depends(dep_node)):
|
||||
async def console_ws(websocket: WebSocket, node: VMwareVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Console WebSocket.
|
||||
"""
|
||||
@ -265,6 +289,6 @@ 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)):
|
||||
async def reset_console(node: VMwareVM = Depends(dep_node)) -> None:
|
||||
|
||||
await node.reset_console()
|
||||
|
@ -20,7 +20,7 @@ API routes for VPCS nodes.
|
||||
|
||||
import os
|
||||
|
||||
from fastapi import APIRouter, WebSocket, Depends, Body, status
|
||||
from fastapi import APIRouter, WebSocket, Depends, Body, Path, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import StreamingResponse
|
||||
from uuid import UUID
|
||||
@ -34,7 +34,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_node(project_id: UUID, node_id: UUID):
|
||||
def dep_node(project_id: UUID, node_id: UUID) -> VPCSVM:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -50,7 +50,7 @@ def dep_node(project_id: UUID, node_id: UUID):
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create VMware node"}},
|
||||
)
|
||||
async def create_vpcs_node(project_id: UUID, node_data: schemas.VPCSCreate):
|
||||
async def create_vpcs_node(project_id: UUID, node_data: schemas.VPCSCreate) -> schemas.VPCS:
|
||||
"""
|
||||
Create a new VPCS node.
|
||||
"""
|
||||
@ -70,7 +70,7 @@ async def create_vpcs_node(project_id: UUID, node_data: schemas.VPCSCreate):
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.VPCS)
|
||||
def get_vpcs_node(node: VPCSVM = Depends(dep_node)):
|
||||
def get_vpcs_node(node: VPCSVM = Depends(dep_node)) -> schemas.VPCS:
|
||||
"""
|
||||
Return a VPCS node.
|
||||
"""
|
||||
@ -79,7 +79,7 @@ def get_vpcs_node(node: VPCSVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.VPCS)
|
||||
def update_vpcs_node(node_data: schemas.VPCSUpdate, node: VPCSVM = Depends(dep_node)):
|
||||
def update_vpcs_node(node_data: schemas.VPCSUpdate, node: VPCSVM = Depends(dep_node)) -> schemas.VPCS:
|
||||
"""
|
||||
Update a VPCS node.
|
||||
"""
|
||||
@ -93,7 +93,7 @@ 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)):
|
||||
async def delete_vpcs_node(node: VPCSVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Delete a VPCS node.
|
||||
"""
|
||||
@ -102,7 +102,9 @@ async def delete_vpcs_node(node: VPCSVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/duplicate", response_model=schemas.VPCS, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_vpcs_node(destination_node_id: UUID = Body(..., embed=True), node: VPCSVM = Depends(dep_node)):
|
||||
async def duplicate_vpcs_node(
|
||||
destination_node_id: UUID = Body(..., embed=True),
|
||||
node: VPCSVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Duplicate a VPCS node.
|
||||
"""
|
||||
@ -112,7 +114,7 @@ async def duplicate_vpcs_node(destination_node_id: UUID = Body(..., embed=True),
|
||||
|
||||
|
||||
@router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def start_vpcs_node(node: VPCSVM = Depends(dep_node)):
|
||||
async def start_vpcs_node(node: VPCSVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start a VPCS node.
|
||||
"""
|
||||
@ -121,7 +123,7 @@ async def start_vpcs_node(node: VPCSVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_vpcs_node(node: VPCSVM = Depends(dep_node)):
|
||||
async def stop_vpcs_node(node: VPCSVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop a VPCS node.
|
||||
"""
|
||||
@ -130,7 +132,7 @@ async def stop_vpcs_node(node: VPCSVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def suspend_vpcs_node(node: VPCSVM = Depends(dep_node)):
|
||||
async def suspend_vpcs_node(node: VPCSVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend a VPCS node.
|
||||
Does nothing, suspend is not supported by VPCS.
|
||||
@ -140,7 +142,7 @@ async def suspend_vpcs_node(node: VPCSVM = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reload_vpcs_node(node: VPCSVM = Depends(dep_node)):
|
||||
async def reload_vpcs_node(node: VPCSVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Reload a VPCS node.
|
||||
"""
|
||||
@ -154,8 +156,12 @@ async def reload_vpcs_node(node: VPCSVM = Depends(dep_node)):
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def create_vpcs_node_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: VPCSVM = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: VPCSVM = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Add a NIO (Network Input/Output) to the node.
|
||||
The adapter number on the VPCS node is always 0.
|
||||
@ -172,8 +178,12 @@ async def create_vpcs_node_nio(
|
||||
response_model=schemas.UDPNIO,
|
||||
)
|
||||
async def update_vpcs_node_nio(
|
||||
adapter_number: int, port_number: int, nio_data: schemas.UDPNIO, node: VPCSVM = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
nio_data: schemas.UDPNIO,
|
||||
node: VPCSVM = Depends(dep_node)
|
||||
) -> schemas.UDPNIO:
|
||||
"""
|
||||
Update a NIO (Network Input/Output) on the node.
|
||||
The adapter number on the VPCS node is always 0.
|
||||
@ -187,7 +197,12 @@ async def update_vpcs_node_nio(
|
||||
|
||||
|
||||
@router.delete("/{node_id}/adapters/{adapter_number}/ports/{port_number}/nio", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_vpcs_node_nio(adapter_number: int, port_number: int, node: VPCSVM = Depends(dep_node)):
|
||||
async def delete_vpcs_node_nio(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: VPCSVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Delete a NIO (Network Input/Output) from the node.
|
||||
The adapter number on the VPCS node is always 0.
|
||||
@ -198,8 +213,12 @@ async def delete_vpcs_node_nio(adapter_number: int, port_number: int, node: VPCS
|
||||
|
||||
@router.post("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/start")
|
||||
async def start_vpcs_node_capture(
|
||||
adapter_number: int, port_number: int, node_capture_data: schemas.NodeCapture, node: VPCSVM = Depends(dep_node)
|
||||
):
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node_capture_data: schemas.NodeCapture,
|
||||
node: VPCSVM = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Start a packet capture on the node.
|
||||
The adapter number on the VPCS node is always 0.
|
||||
@ -213,7 +232,12 @@ async def start_vpcs_node_capture(
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stop", status_code=status.HTTP_204_NO_CONTENT
|
||||
)
|
||||
async def stop_vpcs_node_capture(adapter_number: int, port_number: int, node: VPCSVM = Depends(dep_node)):
|
||||
async def stop_vpcs_node_capture(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: VPCSVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Stop a packet capture on the node.
|
||||
The adapter number on the VPCS node is always 0.
|
||||
@ -223,13 +247,18 @@ async def stop_vpcs_node_capture(adapter_number: int, port_number: int, node: VP
|
||||
|
||||
|
||||
@router.post("/{node_id}/console/reset", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reset_console(node: VPCSVM = Depends(dep_node)):
|
||||
async def reset_console(node: VPCSVM = Depends(dep_node)) -> None:
|
||||
|
||||
await node.reset_console()
|
||||
|
||||
|
||||
@router.get("/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream")
|
||||
async def stream_pcap_file(adapter_number: int, port_number: int, node: VPCSVM = Depends(dep_node)):
|
||||
async def stream_pcap_file(
|
||||
*,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
port_number: int,
|
||||
node: VPCSVM = Depends(dep_node)
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Stream the pcap capture file.
|
||||
The adapter number on the VPCS node is always 0.
|
||||
@ -241,7 +270,7 @@ async def stream_pcap_file(adapter_number: int, port_number: int, node: VPCSVM =
|
||||
|
||||
|
||||
@router.websocket("/{node_id}/console/ws")
|
||||
async def console_ws(websocket: WebSocket, node: VPCSVM = Depends(dep_node)):
|
||||
async def console_ws(websocket: WebSocket, node: VPCSVM = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Console WebSocket.
|
||||
"""
|
||||
|
@ -19,13 +19,13 @@ API routes for appliances.
|
||||
"""
|
||||
|
||||
from fastapi import APIRouter
|
||||
from typing import Optional
|
||||
from typing import Optional, List
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def get_appliances(update: Optional[bool] = None, symbol_theme: Optional[str] = "Classic"):
|
||||
async def get_appliances(update: Optional[bool] = None, symbol_theme: Optional[str] = "Classic") -> List[dict]:
|
||||
"""
|
||||
Return all appliances known by the controller.
|
||||
"""
|
||||
|
@ -93,7 +93,7 @@ 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:
|
||||
"""
|
||||
Delete a compute from the controller.
|
||||
"""
|
||||
@ -102,7 +102,7 @@ async def delete_compute(
|
||||
|
||||
|
||||
@router.get("/{compute_id}/{emulator}/images")
|
||||
async def get_images(compute_id: Union[str, UUID], emulator: str):
|
||||
async def get_images(compute_id: Union[str, UUID], emulator: str) -> List[str]:
|
||||
"""
|
||||
Return the list of images available on a compute for a given emulator type.
|
||||
"""
|
||||
@ -113,7 +113,7 @@ async def get_images(compute_id: Union[str, UUID], emulator: str):
|
||||
|
||||
|
||||
@router.get("/{compute_id}/{emulator}/{endpoint_path:path}")
|
||||
async def forward_get(compute_id: Union[str, UUID], emulator: str, endpoint_path: str):
|
||||
async def forward_get(compute_id: Union[str, UUID], emulator: str, endpoint_path: str) -> dict:
|
||||
"""
|
||||
Forward a GET request to a compute.
|
||||
Read the full compute API documentation for available routes.
|
||||
@ -125,7 +125,7 @@ async def forward_get(compute_id: Union[str, UUID], emulator: str, endpoint_path
|
||||
|
||||
|
||||
@router.post("/{compute_id}/{emulator}/{endpoint_path:path}")
|
||||
async def forward_post(compute_id: Union[str, UUID], emulator: str, endpoint_path: str, compute_data: dict):
|
||||
async def forward_post(compute_id: Union[str, UUID], emulator: str, endpoint_path: str, compute_data: dict) -> dict:
|
||||
"""
|
||||
Forward a POST request to a compute.
|
||||
Read the full compute API documentation for available routes.
|
||||
@ -136,7 +136,7 @@ async def forward_post(compute_id: Union[str, UUID], emulator: str, endpoint_pat
|
||||
|
||||
|
||||
@router.put("/{compute_id}/{emulator}/{endpoint_path:path}")
|
||||
async def forward_put(compute_id: Union[str, UUID], emulator: str, endpoint_path: str, compute_data: dict):
|
||||
async def forward_put(compute_id: Union[str, UUID], emulator: str, endpoint_path: str, compute_data: dict) -> dict:
|
||||
"""
|
||||
Forward a PUT request to a compute.
|
||||
Read the full compute API documentation for available routes.
|
||||
@ -147,7 +147,7 @@ async def forward_put(compute_id: Union[str, UUID], emulator: str, endpoint_path
|
||||
|
||||
|
||||
@router.post("/{compute_id}/auto_idlepc")
|
||||
async def autoidlepc(compute_id: Union[str, UUID], auto_idle_pc: schemas.AutoIdlePC):
|
||||
async def autoidlepc(compute_id: Union[str, UUID], auto_idle_pc: schemas.AutoIdlePC) -> str:
|
||||
"""
|
||||
Find a suitable Idle-PC value for a given IOS image. This may take a few minutes.
|
||||
"""
|
||||
|
@ -20,6 +20,7 @@ import os
|
||||
|
||||
from fastapi import APIRouter, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from typing import List
|
||||
|
||||
from gns3server.config import Config
|
||||
from gns3server.controller import Controller
|
||||
@ -40,7 +41,7 @@ router = APIRouter()
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses={403: {"model": schemas.ErrorMessage, "description": "Server shutdown not allowed"}},
|
||||
)
|
||||
async def shutdown():
|
||||
async def shutdown() -> None:
|
||||
"""
|
||||
Shutdown the local server
|
||||
"""
|
||||
@ -71,7 +72,7 @@ async def shutdown():
|
||||
|
||||
|
||||
@router.get("/version", response_model=schemas.Version)
|
||||
def get_version():
|
||||
def get_version() -> dict:
|
||||
"""
|
||||
Return the server version number.
|
||||
"""
|
||||
@ -86,7 +87,7 @@ def get_version():
|
||||
response_model_exclude_defaults=True,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Invalid version"}},
|
||||
)
|
||||
def check_version(version: schemas.Version):
|
||||
def check_version(version: schemas.Version) -> dict:
|
||||
"""
|
||||
Check if version is the same as the server.
|
||||
|
||||
@ -102,7 +103,7 @@ def check_version(version: schemas.Version):
|
||||
|
||||
|
||||
@router.get("/iou_license", response_model=schemas.IOULicense)
|
||||
def get_iou_license():
|
||||
def get_iou_license() -> schemas.IOULicense:
|
||||
"""
|
||||
Return the IOU license settings
|
||||
"""
|
||||
@ -111,7 +112,7 @@ def get_iou_license():
|
||||
|
||||
|
||||
@router.put("/iou_license", status_code=status.HTTP_201_CREATED, response_model=schemas.IOULicense)
|
||||
async def update_iou_license(iou_license: schemas.IOULicense):
|
||||
async def update_iou_license(iou_license: schemas.IOULicense) -> schemas.IOULicense:
|
||||
"""
|
||||
Update the IOU license settings.
|
||||
"""
|
||||
@ -124,7 +125,7 @@ async def update_iou_license(iou_license: schemas.IOULicense):
|
||||
|
||||
|
||||
@router.get("/statistics")
|
||||
async def statistics():
|
||||
async def statistics() -> List[dict]:
|
||||
"""
|
||||
Return server statistics.
|
||||
"""
|
||||
|
@ -32,7 +32,7 @@ router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
@router.get("", response_model=List[schemas.Drawing], response_model_exclude_unset=True)
|
||||
async def get_drawings(project_id: UUID):
|
||||
async def get_drawings(project_id: UUID) -> List[schemas.Drawing]:
|
||||
"""
|
||||
Return the list of all drawings for a given project.
|
||||
"""
|
||||
@ -42,7 +42,7 @@ async def get_drawings(project_id: UUID):
|
||||
|
||||
|
||||
@router.post("", status_code=status.HTTP_201_CREATED, response_model=schemas.Drawing)
|
||||
async def create_drawing(project_id: UUID, drawing_data: schemas.Drawing):
|
||||
async def create_drawing(project_id: UUID, drawing_data: schemas.Drawing) -> schemas.Drawing:
|
||||
"""
|
||||
Create a new drawing.
|
||||
"""
|
||||
@ -53,7 +53,7 @@ async def create_drawing(project_id: UUID, drawing_data: schemas.Drawing):
|
||||
|
||||
|
||||
@router.get("/{drawing_id}", response_model=schemas.Drawing, response_model_exclude_unset=True)
|
||||
async def get_drawing(project_id: UUID, drawing_id: UUID):
|
||||
async def get_drawing(project_id: UUID, drawing_id: UUID) -> schemas.Drawing:
|
||||
"""
|
||||
Return a drawing.
|
||||
"""
|
||||
@ -64,7 +64,7 @@ async def get_drawing(project_id: UUID, drawing_id: UUID):
|
||||
|
||||
|
||||
@router.put("/{drawing_id}", response_model=schemas.Drawing, response_model_exclude_unset=True)
|
||||
async def update_drawing(project_id: UUID, drawing_id: UUID, drawing_data: schemas.Drawing):
|
||||
async def update_drawing(project_id: UUID, drawing_id: UUID, drawing_data: schemas.Drawing) -> schemas.Drawing:
|
||||
"""
|
||||
Update a drawing.
|
||||
"""
|
||||
@ -76,7 +76,7 @@ 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):
|
||||
async def delete_drawing(project_id: UUID, drawing_id: UUID) -> None:
|
||||
"""
|
||||
Delete a drawing.
|
||||
"""
|
||||
|
@ -21,6 +21,7 @@ API routes for managing the GNS3 VM.
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from typing import List
|
||||
|
||||
from gns3server.controller import Controller
|
||||
from gns3server import schemas
|
||||
@ -29,7 +30,7 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/engines")
|
||||
async def get_engines():
|
||||
async def get_engines() -> List[dict]:
|
||||
"""
|
||||
Return the list of supported engines for the GNS3VM.
|
||||
"""
|
||||
@ -39,7 +40,7 @@ async def get_engines():
|
||||
|
||||
|
||||
@router.get("/engines/{engine}/vms")
|
||||
async def get_vms(engine: str):
|
||||
async def get_vms(engine: str) -> List[dict]:
|
||||
"""
|
||||
Return all the available VMs for a specific virtualization engine.
|
||||
"""
|
||||
@ -49,7 +50,7 @@ async def get_vms(engine: str):
|
||||
|
||||
|
||||
@router.get("", response_model=schemas.GNS3VM)
|
||||
async def get_gns3vm_settings():
|
||||
async def get_gns3vm_settings() -> schemas.GNS3VM:
|
||||
"""
|
||||
Return the GNS3 VM settings.
|
||||
"""
|
||||
@ -58,7 +59,7 @@ async def get_gns3vm_settings():
|
||||
|
||||
|
||||
@router.put("", response_model=schemas.GNS3VM, response_model_exclude_unset=True)
|
||||
async def update_gns3vm_settings(gns3vm_data: schemas.GNS3VM):
|
||||
async def update_gns3vm_settings(gns3vm_data: schemas.GNS3VM) -> schemas.GNS3VM:
|
||||
"""
|
||||
Update the GNS3 VM settings.
|
||||
"""
|
||||
|
@ -42,7 +42,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
async def dep_link(project_id: UUID, link_id: UUID):
|
||||
async def dep_link(project_id: UUID, link_id: UUID) -> Link:
|
||||
"""
|
||||
Dependency to retrieve a link.
|
||||
"""
|
||||
@ -53,7 +53,7 @@ async def dep_link(project_id: UUID, link_id: UUID):
|
||||
|
||||
|
||||
@router.get("", response_model=List[schemas.Link], response_model_exclude_unset=True)
|
||||
async def get_links(project_id: UUID):
|
||||
async def get_links(project_id: UUID) -> List[schemas.Link]:
|
||||
"""
|
||||
Return all links for a given project.
|
||||
"""
|
||||
@ -71,7 +71,7 @@ async def get_links(project_id: UUID):
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not create link"},
|
||||
},
|
||||
)
|
||||
async def create_link(project_id: UUID, link_data: schemas.LinkCreate):
|
||||
async def create_link(project_id: UUID, link_data: schemas.LinkCreate) -> schemas.Link:
|
||||
"""
|
||||
Create a new link.
|
||||
"""
|
||||
@ -98,7 +98,7 @@ async def create_link(project_id: UUID, link_data: schemas.LinkCreate):
|
||||
|
||||
|
||||
@router.get("/{link_id}/available_filters")
|
||||
async def get_filters(link: Link = Depends(dep_link)):
|
||||
async def get_filters(link: Link = Depends(dep_link)) -> List[dict]:
|
||||
"""
|
||||
Return all filters available for a given link.
|
||||
"""
|
||||
@ -107,7 +107,7 @@ async def get_filters(link: Link = Depends(dep_link)):
|
||||
|
||||
|
||||
@router.get("/{link_id}", response_model=schemas.Link, response_model_exclude_unset=True)
|
||||
async def get_link(link: Link = Depends(dep_link)):
|
||||
async def get_link(link: Link = Depends(dep_link)) -> schemas.Link:
|
||||
"""
|
||||
Return a link.
|
||||
"""
|
||||
@ -116,7 +116,7 @@ async def get_link(link: Link = Depends(dep_link)):
|
||||
|
||||
|
||||
@router.put("/{link_id}", response_model=schemas.Link, response_model_exclude_unset=True)
|
||||
async def update_link(link_data: schemas.LinkUpdate, link: Link = Depends(dep_link)):
|
||||
async def update_link(link_data: schemas.LinkUpdate, link: Link = Depends(dep_link)) -> schemas.Link:
|
||||
"""
|
||||
Update a link.
|
||||
"""
|
||||
@ -132,7 +132,7 @@ 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)):
|
||||
async def delete_link(project_id: UUID, link: Link = Depends(dep_link)) -> None:
|
||||
"""
|
||||
Delete a link.
|
||||
"""
|
||||
@ -142,7 +142,7 @@ async def delete_link(project_id: UUID, link: Link = Depends(dep_link)):
|
||||
|
||||
|
||||
@router.post("/{link_id}/reset", response_model=schemas.Link)
|
||||
async def reset_link(link: Link = Depends(dep_link)):
|
||||
async def reset_link(link: Link = Depends(dep_link)) -> schemas.Link:
|
||||
"""
|
||||
Reset a link.
|
||||
"""
|
||||
@ -152,7 +152,7 @@ async def reset_link(link: Link = Depends(dep_link)):
|
||||
|
||||
|
||||
@router.post("/{link_id}/capture/start", status_code=status.HTTP_201_CREATED, response_model=schemas.Link)
|
||||
async def start_capture(capture_data: dict, link: Link = Depends(dep_link)):
|
||||
async def start_capture(capture_data: dict, link: Link = Depends(dep_link)) -> schemas.Link:
|
||||
"""
|
||||
Start packet capture on the link.
|
||||
"""
|
||||
@ -165,7 +165,7 @@ async def start_capture(capture_data: dict, link: Link = Depends(dep_link)):
|
||||
|
||||
|
||||
@router.post("/{link_id}/capture/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_capture(link: Link = Depends(dep_link)):
|
||||
async def stop_capture(link: Link = Depends(dep_link)) -> None:
|
||||
"""
|
||||
Stop packet capture on the link.
|
||||
"""
|
||||
@ -174,7 +174,7 @@ async def stop_capture(link: Link = Depends(dep_link)):
|
||||
|
||||
|
||||
@router.get("/{link_id}/capture/stream")
|
||||
async def stream_pcap(request: Request, link: Link = Depends(dep_link)):
|
||||
async def stream_pcap(request: Request, link: Link = Depends(dep_link)) -> StreamingResponse:
|
||||
"""
|
||||
Stream the PCAP capture file from compute.
|
||||
"""
|
||||
|
@ -81,7 +81,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(route_class=NodeConcurrency, responses=responses)
|
||||
|
||||
|
||||
async def dep_project(project_id: UUID):
|
||||
async def dep_project(project_id: UUID) -> Project:
|
||||
"""
|
||||
Dependency to retrieve a project.
|
||||
"""
|
||||
@ -90,7 +90,7 @@ async def dep_project(project_id: UUID):
|
||||
return project
|
||||
|
||||
|
||||
async def dep_node(node_id: UUID, project: Project = Depends(dep_project)):
|
||||
async def dep_node(node_id: UUID, project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Dependency to retrieve a node.
|
||||
"""
|
||||
@ -108,7 +108,7 @@ async def dep_node(node_id: UUID, project: Project = Depends(dep_project)):
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not create node"},
|
||||
},
|
||||
)
|
||||
async def create_node(node_data: schemas.NodeCreate, project: Project = Depends(dep_project)):
|
||||
async def create_node(node_data: schemas.NodeCreate, project: Project = Depends(dep_project)) -> schemas.Node:
|
||||
"""
|
||||
Create a new node.
|
||||
"""
|
||||
@ -121,7 +121,7 @@ async def create_node(node_data: schemas.NodeCreate, project: Project = Depends(
|
||||
|
||||
|
||||
@router.get("", response_model=List[schemas.Node], response_model_exclude_unset=True)
|
||||
async def get_nodes(project: Project = Depends(dep_project)):
|
||||
async def get_nodes(project: Project = Depends(dep_project)) -> List[schemas.Node]:
|
||||
"""
|
||||
Return all nodes belonging to a given project.
|
||||
"""
|
||||
@ -130,7 +130,7 @@ async def get_nodes(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.post("/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def start_all_nodes(project: Project = Depends(dep_project)):
|
||||
async def start_all_nodes(project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Start all nodes belonging to a given project.
|
||||
"""
|
||||
@ -139,7 +139,7 @@ async def start_all_nodes(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.post("/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_all_nodes(project: Project = Depends(dep_project)):
|
||||
async def stop_all_nodes(project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Stop all nodes belonging to a given project.
|
||||
"""
|
||||
@ -148,7 +148,7 @@ async def stop_all_nodes(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.post("/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def suspend_all_nodes(project: Project = Depends(dep_project)):
|
||||
async def suspend_all_nodes(project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Suspend all nodes belonging to a given project.
|
||||
"""
|
||||
@ -157,7 +157,7 @@ async def suspend_all_nodes(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.post("/reload", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reload_all_nodes(project: Project = Depends(dep_project)):
|
||||
async def reload_all_nodes(project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Reload all nodes belonging to a given project.
|
||||
"""
|
||||
@ -167,7 +167,7 @@ async def reload_all_nodes(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.get("/{node_id}", response_model=schemas.Node)
|
||||
def get_node(node: Node = Depends(dep_node)):
|
||||
def get_node(node: Node = Depends(dep_node)) -> schemas.Node:
|
||||
"""
|
||||
Return a node from a given project.
|
||||
"""
|
||||
@ -176,7 +176,7 @@ def get_node(node: Node = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.put("/{node_id}", response_model=schemas.Node, response_model_exclude_unset=True)
|
||||
async def update_node(node_data: schemas.NodeUpdate, node: Node = Depends(dep_node)):
|
||||
async def update_node(node_data: schemas.NodeUpdate, node: Node = Depends(dep_node)) -> schemas.Node:
|
||||
"""
|
||||
Update a node.
|
||||
"""
|
||||
@ -197,7 +197,7 @@ 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)):
|
||||
async def delete_node(node_id: UUID, project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Delete a node from a project.
|
||||
"""
|
||||
@ -206,7 +206,7 @@ async def delete_node(node_id: UUID, project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/duplicate", response_model=schemas.Node, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_node(duplicate_data: schemas.NodeDuplicate, node: Node = Depends(dep_node)):
|
||||
async def duplicate_node(duplicate_data: schemas.NodeDuplicate, node: Node = Depends(dep_node)) -> schemas.Node:
|
||||
"""
|
||||
Duplicate a node.
|
||||
"""
|
||||
@ -216,7 +216,7 @@ 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)):
|
||||
async def start_node(start_data: dict, node: Node = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Start a node.
|
||||
"""
|
||||
@ -225,7 +225,7 @@ async def start_node(start_data: dict, node: Node = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_node(node: Node = Depends(dep_node)):
|
||||
async def stop_node(node: Node = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Stop a node.
|
||||
"""
|
||||
@ -234,7 +234,7 @@ async def stop_node(node: Node = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def suspend_node(node: Node = Depends(dep_node)):
|
||||
async def suspend_node(node: Node = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Suspend a node.
|
||||
"""
|
||||
@ -243,7 +243,7 @@ async def suspend_node(node: Node = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reload_node(node: Node = Depends(dep_node)):
|
||||
async def reload_node(node: Node = Depends(dep_node)) -> None:
|
||||
"""
|
||||
Reload a node.
|
||||
"""
|
||||
@ -252,7 +252,7 @@ async def reload_node(node: Node = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.get("/{node_id}/links", response_model=List[schemas.Link], response_model_exclude_unset=True)
|
||||
async def get_node_links(node: Node = Depends(dep_node)):
|
||||
async def get_node_links(node: Node = Depends(dep_node)) -> List[schemas.Link]:
|
||||
"""
|
||||
Return all the links connected to a node.
|
||||
"""
|
||||
@ -264,7 +264,7 @@ async def get_node_links(node: Node = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.get("/{node_id}/dynamips/auto_idlepc")
|
||||
async def auto_idlepc(node: Node = Depends(dep_node)):
|
||||
async def auto_idlepc(node: Node = Depends(dep_node)) -> str:
|
||||
"""
|
||||
Compute an Idle-PC value for a Dynamips node
|
||||
"""
|
||||
@ -273,7 +273,7 @@ async def auto_idlepc(node: Node = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.get("/{node_id}/dynamips/idlepc_proposals")
|
||||
async def idlepc_proposals(node: Node = Depends(dep_node)):
|
||||
async def idlepc_proposals(node: Node = Depends(dep_node)) -> List[str]:
|
||||
"""
|
||||
Compute a list of potential idle-pc values for a Dynamips node
|
||||
"""
|
||||
@ -281,8 +281,8 @@ async def idlepc_proposals(node: Node = Depends(dep_node)):
|
||||
return await node.dynamips_idlepc_proposals()
|
||||
|
||||
|
||||
@router.post("/{node_id}/resize_disk", status_code=status.HTTP_201_CREATED)
|
||||
async def resize_disk(resize_data: dict, node: Node = Depends(dep_node)):
|
||||
@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:
|
||||
"""
|
||||
Resize a disk image.
|
||||
"""
|
||||
@ -290,7 +290,7 @@ async def resize_disk(resize_data: dict, node: Node = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.get("/{node_id}/files/{file_path:path}")
|
||||
async def get_file(file_path: str, node: Node = Depends(dep_node)):
|
||||
async def get_file(file_path: str, node: Node = Depends(dep_node)) -> Response:
|
||||
"""
|
||||
Return a file in the node directory
|
||||
"""
|
||||
@ -309,7 +309,7 @@ async def get_file(file_path: str, node: Node = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/files/{file_path:path}", status_code=status.HTTP_201_CREATED)
|
||||
async def post_file(file_path: str, request: Request, node: Node = Depends(dep_node)):
|
||||
async def post_file(file_path: str, request: Request, node: Node = Depends(dep_node)) -> dict:
|
||||
"""
|
||||
Write a file in the node directory.
|
||||
"""
|
||||
@ -329,7 +329,7 @@ async def post_file(file_path: str, request: Request, node: Node = Depends(dep_n
|
||||
|
||||
|
||||
@router.websocket("/{node_id}/console/ws")
|
||||
async def ws_console(websocket: WebSocket, node: Node = Depends(dep_node)):
|
||||
async def ws_console(websocket: WebSocket, node: Node = Depends(dep_node)) -> None:
|
||||
"""
|
||||
WebSocket console.
|
||||
"""
|
||||
@ -377,7 +377,7 @@ async def ws_console(websocket: WebSocket, node: Node = Depends(dep_node)):
|
||||
|
||||
|
||||
@router.post("/console/reset", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reset_console_all_nodes(project: Project = Depends(dep_project)):
|
||||
async def reset_console_all_nodes(project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Reset console for all nodes belonging to the project.
|
||||
"""
|
||||
@ -386,6 +386,6 @@ async def reset_console_all_nodes(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.post("/{node_id}/console/reset", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def console_reset(node: Node = Depends(dep_node)):
|
||||
async def console_reset(node: Node = Depends(dep_node)) -> None:
|
||||
|
||||
await node.post("/console/reset") # , request.json)
|
||||
|
@ -32,7 +32,7 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def http_notification():
|
||||
async def http_notification() -> StreamingResponse:
|
||||
"""
|
||||
Receive controller notifications about the controller from HTTP stream.
|
||||
"""
|
||||
@ -47,7 +47,7 @@ async def http_notification():
|
||||
|
||||
|
||||
@router.websocket("/ws")
|
||||
async def notification_ws(websocket: WebSocket):
|
||||
async def notification_ws(websocket: WebSocket) -> None:
|
||||
"""
|
||||
Receive project notifications about the controller from WebSocket.
|
||||
"""
|
||||
|
@ -51,7 +51,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_project(project_id: UUID):
|
||||
def dep_project(project_id: UUID) -> Project:
|
||||
"""
|
||||
Dependency to retrieve a project.
|
||||
"""
|
||||
@ -64,7 +64,7 @@ CHUNK_SIZE = 1024 * 8 # 8KB
|
||||
|
||||
|
||||
@router.get("", response_model=List[schemas.Project], response_model_exclude_unset=True)
|
||||
def get_projects():
|
||||
def get_projects() -> List[schemas.Project]:
|
||||
"""
|
||||
Return all projects.
|
||||
"""
|
||||
@ -80,7 +80,7 @@ def get_projects():
|
||||
response_model_exclude_unset=True,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create project"}},
|
||||
)
|
||||
async def create_project(project_data: schemas.ProjectCreate):
|
||||
async def create_project(project_data: schemas.ProjectCreate) -> schemas.Project:
|
||||
"""
|
||||
Create a new project.
|
||||
"""
|
||||
@ -91,7 +91,7 @@ async def create_project(project_data: schemas.ProjectCreate):
|
||||
|
||||
|
||||
@router.get("/{project_id}", response_model=schemas.Project)
|
||||
def get_project(project: Project = Depends(dep_project)):
|
||||
def get_project(project: Project = Depends(dep_project)) -> schemas.Project:
|
||||
"""
|
||||
Return a project.
|
||||
"""
|
||||
@ -100,7 +100,10 @@ def get_project(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.put("/{project_id}", response_model=schemas.Project, response_model_exclude_unset=True)
|
||||
async def update_project(project_data: schemas.ProjectUpdate, project: Project = Depends(dep_project)):
|
||||
async def update_project(
|
||||
project_data: schemas.ProjectUpdate,
|
||||
project: Project = Depends(dep_project)
|
||||
) -> schemas.Project:
|
||||
"""
|
||||
Update a project.
|
||||
"""
|
||||
@ -110,7 +113,7 @@ async def update_project(project_data: schemas.ProjectUpdate, project: Project =
|
||||
|
||||
|
||||
@router.delete("/{project_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_project(project: Project = Depends(dep_project)):
|
||||
async def delete_project(project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Delete a project.
|
||||
"""
|
||||
@ -121,7 +124,7 @@ async def delete_project(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.get("/{project_id}/stats")
|
||||
def get_project_stats(project: Project = Depends(dep_project)):
|
||||
def get_project_stats(project: Project = Depends(dep_project)) -> dict:
|
||||
"""
|
||||
Return a project statistics.
|
||||
"""
|
||||
@ -134,7 +137,7 @@ def get_project_stats(project: Project = Depends(dep_project)):
|
||||
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)):
|
||||
async def close_project(project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Close a project.
|
||||
"""
|
||||
@ -148,7 +151,7 @@ async def close_project(project: Project = Depends(dep_project)):
|
||||
response_model=schemas.Project,
|
||||
responses={**responses, 409: {"model": schemas.ErrorMessage, "description": "Could not open project"}},
|
||||
)
|
||||
async def open_project(project: Project = Depends(dep_project)):
|
||||
async def open_project(project: Project = Depends(dep_project)) -> schemas.Project:
|
||||
"""
|
||||
Open a project.
|
||||
"""
|
||||
@ -163,7 +166,7 @@ async def open_project(project: Project = Depends(dep_project)):
|
||||
response_model=schemas.Project,
|
||||
responses={**responses, 409: {"model": schemas.ErrorMessage, "description": "Could not load project"}},
|
||||
)
|
||||
async def load_project(path: str = Body(..., embed=True)):
|
||||
async def load_project(path: str = Body(..., embed=True)) -> schemas.Project:
|
||||
"""
|
||||
Load a project (local server only).
|
||||
"""
|
||||
@ -180,7 +183,7 @@ async def load_project(path: str = Body(..., embed=True)):
|
||||
|
||||
|
||||
@router.get("/{project_id}/notifications")
|
||||
async def notification(project_id: UUID):
|
||||
async def notification(project_id: UUID) -> StreamingResponse:
|
||||
"""
|
||||
Receive project notifications about the controller from HTTP stream.
|
||||
"""
|
||||
@ -211,7 +214,7 @@ async def notification(project_id: UUID):
|
||||
|
||||
|
||||
@router.websocket("/{project_id}/notifications/ws")
|
||||
async def notification_ws(project_id: UUID, websocket: WebSocket):
|
||||
async def notification_ws(project_id: UUID, websocket: WebSocket) -> None:
|
||||
"""
|
||||
Receive project notifications about the controller from WebSocket.
|
||||
"""
|
||||
@ -248,7 +251,7 @@ async def export_project(
|
||||
include_images: bool = False,
|
||||
reset_mac_addresses: bool = False,
|
||||
compression: str = "zip",
|
||||
):
|
||||
) -> StreamingResponse:
|
||||
"""
|
||||
Export a project as a portable archive.
|
||||
"""
|
||||
@ -294,7 +297,12 @@ async def export_project(
|
||||
|
||||
|
||||
@router.post("/{project_id}/import", status_code=status.HTTP_201_CREATED, response_model=schemas.Project)
|
||||
async def import_project(project_id: UUID, request: Request, path: Optional[Path] = None, name: Optional[str] = None):
|
||||
async def import_project(
|
||||
project_id: UUID,
|
||||
request: Request,
|
||||
path: Optional[Path] = None,
|
||||
name: Optional[str] = None
|
||||
) -> schemas.Project:
|
||||
"""
|
||||
Import a project from a portable archive.
|
||||
"""
|
||||
@ -332,7 +340,10 @@ async def import_project(project_id: UUID, request: Request, path: Optional[Path
|
||||
response_model=schemas.Project,
|
||||
responses={**responses, 409: {"model": schemas.ErrorMessage, "description": "Could not duplicate project"}},
|
||||
)
|
||||
async def duplicate_project(project_data: schemas.ProjectDuplicate, project: Project = Depends(dep_project)):
|
||||
async def duplicate_project(
|
||||
project_data: schemas.ProjectDuplicate,
|
||||
project: Project = Depends(dep_project)
|
||||
) -> schemas.Project:
|
||||
"""
|
||||
Duplicate a project.
|
||||
"""
|
||||
@ -352,7 +363,7 @@ async def duplicate_project(project_data: schemas.ProjectDuplicate, project: Pro
|
||||
|
||||
|
||||
@router.get("/{project_id}/files/{file_path:path}")
|
||||
async def get_file(file_path: str, project: Project = Depends(dep_project)):
|
||||
async def get_file(file_path: str, project: Project = Depends(dep_project)) -> FileResponse:
|
||||
"""
|
||||
Return a file from a project.
|
||||
"""
|
||||
@ -371,7 +382,7 @@ async def get_file(file_path: str, project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@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)):
|
||||
async def write_file(file_path: str, request: Request, project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Write a file from a project.
|
||||
"""
|
||||
|
@ -36,7 +36,7 @@ responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
def dep_project(project_id: UUID):
|
||||
def dep_project(project_id: UUID) -> Project:
|
||||
"""
|
||||
Dependency to retrieve a project.
|
||||
"""
|
||||
@ -46,7 +46,10 @@ def dep_project(project_id: UUID):
|
||||
|
||||
|
||||
@router.post("", status_code=status.HTTP_201_CREATED, response_model=schemas.Snapshot)
|
||||
async def create_snapshot(snapshot_data: schemas.SnapshotCreate, project: Project = Depends(dep_project)):
|
||||
async def create_snapshot(
|
||||
snapshot_data: schemas.SnapshotCreate,
|
||||
project: Project = Depends(dep_project)
|
||||
) -> schemas.Snapshot:
|
||||
"""
|
||||
Create a new snapshot of a project.
|
||||
"""
|
||||
@ -56,7 +59,7 @@ async def create_snapshot(snapshot_data: schemas.SnapshotCreate, project: Projec
|
||||
|
||||
|
||||
@router.get("", response_model=List[schemas.Snapshot], response_model_exclude_unset=True)
|
||||
def get_snapshots(project: Project = Depends(dep_project)):
|
||||
def get_snapshots(project: Project = Depends(dep_project)) -> List[schemas.Snapshot]:
|
||||
"""
|
||||
Return all snapshots belonging to a given project.
|
||||
"""
|
||||
@ -66,7 +69,7 @@ def get_snapshots(project: Project = Depends(dep_project)):
|
||||
|
||||
|
||||
@router.delete("/{snapshot_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_snapshot(snapshot_id: UUID, project: Project = Depends(dep_project)):
|
||||
async def delete_snapshot(snapshot_id: UUID, project: Project = Depends(dep_project)) -> None:
|
||||
"""
|
||||
Delete a snapshot.
|
||||
"""
|
||||
@ -75,7 +78,7 @@ async def delete_snapshot(snapshot_id: UUID, project: Project = Depends(dep_proj
|
||||
|
||||
|
||||
@router.post("/{snapshot_id}/restore", status_code=status.HTTP_201_CREATED, response_model=schemas.Project)
|
||||
async def restore_snapshot(snapshot_id: UUID, project: Project = Depends(dep_project)):
|
||||
async def restore_snapshot(snapshot_id: UUID, project: Project = Depends(dep_project)) -> schemas.Project:
|
||||
"""
|
||||
Restore a snapshot.
|
||||
"""
|
||||
|
@ -23,6 +23,7 @@ import os
|
||||
|
||||
from fastapi import APIRouter, Request, status
|
||||
from fastapi.responses import FileResponse
|
||||
from typing import List
|
||||
|
||||
from gns3server.controller import Controller
|
||||
from gns3server import schemas
|
||||
@ -37,7 +38,7 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.get("")
|
||||
def get_symbols():
|
||||
def get_symbols() -> List[str]:
|
||||
|
||||
controller = Controller.instance()
|
||||
return controller.symbols.list()
|
||||
@ -46,7 +47,7 @@ def get_symbols():
|
||||
@router.get(
|
||||
"/{symbol_id:path}/raw", responses={404: {"model": schemas.ErrorMessage, "description": "Could not find symbol"}}
|
||||
)
|
||||
async def get_symbol(symbol_id: str):
|
||||
async def get_symbol(symbol_id: str) -> FileResponse:
|
||||
"""
|
||||
Download a symbol file.
|
||||
"""
|
||||
@ -63,7 +64,7 @@ async def get_symbol(symbol_id: str):
|
||||
"/{symbol_id:path}/dimensions",
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find symbol"}},
|
||||
)
|
||||
async def get_symbol_dimensions(symbol_id: str):
|
||||
async def get_symbol_dimensions(symbol_id: str) -> dict:
|
||||
"""
|
||||
Get a symbol dimensions.
|
||||
"""
|
||||
@ -78,7 +79,7 @@ async def get_symbol_dimensions(symbol_id: str):
|
||||
|
||||
|
||||
@router.post("/{symbol_id:path}/raw", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def upload_symbol(symbol_id: str, request: Request):
|
||||
async def upload_symbol(symbol_id: str, request: Request) -> None:
|
||||
"""
|
||||
Upload a symbol file.
|
||||
"""
|
||||
@ -97,7 +98,7 @@ async def upload_symbol(symbol_id: str, request: Request):
|
||||
|
||||
|
||||
@router.get("/default_symbols")
|
||||
def get_default_symbols():
|
||||
def get_default_symbols() -> dict:
|
||||
"""
|
||||
Return all default symbols.
|
||||
"""
|
||||
|
@ -44,7 +44,7 @@ router = APIRouter(responses=responses)
|
||||
async def create_template(
|
||||
template_create: schemas.TemplateCreate,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)),
|
||||
) -> dict:
|
||||
) -> schemas.Template:
|
||||
"""
|
||||
Create a new template.
|
||||
"""
|
||||
@ -58,7 +58,7 @@ async def get_template(
|
||||
request: Request,
|
||||
response: Response,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)),
|
||||
) -> dict:
|
||||
) -> schemas.Template:
|
||||
"""
|
||||
Return a template.
|
||||
"""
|
||||
@ -79,7 +79,7 @@ async def update_template(
|
||||
template_id: UUID,
|
||||
template_update: schemas.TemplateUpdate,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)),
|
||||
) -> dict:
|
||||
) -> schemas.Template:
|
||||
"""
|
||||
Update a template.
|
||||
"""
|
||||
@ -104,7 +104,7 @@ async def delete_template(
|
||||
@router.get("/templates", response_model=List[schemas.Template], response_model_exclude_unset=True)
|
||||
async def get_templates(
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)),
|
||||
) -> List[dict]:
|
||||
) -> List[schemas.Template]:
|
||||
"""
|
||||
Return all templates.
|
||||
"""
|
||||
@ -115,7 +115,7 @@ async def get_templates(
|
||||
@router.post("/templates/{template_id}/duplicate", response_model=schemas.Template, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_template(
|
||||
template_id: UUID, templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository))
|
||||
) -> dict:
|
||||
) -> schemas.Template:
|
||||
"""
|
||||
Duplicate a template.
|
||||
"""
|
||||
|
@ -20,25 +20,25 @@ import struct
|
||||
import stat
|
||||
import asyncio
|
||||
import aiofiles
|
||||
|
||||
import socket
|
||||
import shutil
|
||||
import re
|
||||
|
||||
import logging
|
||||
|
||||
from gns3server.utils.asyncio import cancellable_wait_run_in_executor
|
||||
from gns3server.compute.compute_error import ComputeError, ComputeForbiddenError, ComputeNotFoundError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
from uuid import UUID, uuid4
|
||||
from gns3server.utils.asyncio import cancellable_wait_run_in_executor
|
||||
from gns3server.compute.compute_error import ComputeError, ComputeForbiddenError, ComputeNotFoundError
|
||||
from gns3server.utils.interfaces import is_interface_up
|
||||
|
||||
from uuid import UUID, uuid4
|
||||
from typing import Type
|
||||
from ..config import Config
|
||||
from ..utils.asyncio import wait_run_in_executor
|
||||
from ..utils import force_unix_path
|
||||
from .project_manager import ProjectManager
|
||||
from .port_manager import PortManager
|
||||
from .base_node import BaseNode
|
||||
|
||||
from .nios.nio_udp import NIOUDP
|
||||
from .nios.nio_tap import NIOTAP
|
||||
@ -150,7 +150,7 @@ class BaseManager:
|
||||
BaseManager._instance = None
|
||||
log.debug(f"Module {self.module_name} unloaded")
|
||||
|
||||
def get_node(self, node_id, project_id=None):
|
||||
def get_node(self, node_id, project_id=None) -> Type[BaseNode]:
|
||||
"""
|
||||
Returns a Node instance.
|
||||
|
||||
|
@ -59,7 +59,7 @@ class UsersRepository(BaseRepository):
|
||||
|
||||
async def create_user(self, user: schemas.UserCreate) -> models.User:
|
||||
|
||||
hashed_password = self._auth_service.hash_password(user.password)
|
||||
hashed_password = self._auth_service.hash_password(user.password.get_secret_value())
|
||||
db_user = models.User(
|
||||
username=user.username, email=user.email, full_name=user.full_name, hashed_password=hashed_password
|
||||
)
|
||||
@ -73,7 +73,7 @@ class UsersRepository(BaseRepository):
|
||||
update_values = user_update.dict(exclude_unset=True)
|
||||
password = update_values.pop("password", None)
|
||||
if password:
|
||||
update_values["hashed_password"] = self._auth_service.hash_password(password=password)
|
||||
update_values["hashed_password"] = self._auth_service.hash_password(password=password.get_secret_value())
|
||||
|
||||
query = update(models.User).where(models.User.user_id == user_id).values(update_values)
|
||||
|
||||
|
@ -54,7 +54,13 @@ class ComputeCreate(ComputeBase):
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": {"name": "My compute", "host": "127.0.0.1", "port": 3080, "user": "user", "password": "password"}
|
||||
"example": {
|
||||
"name": "My compute",
|
||||
"host": "127.0.0.1",
|
||||
"port": 3080,
|
||||
"user": "user",
|
||||
"password": "password"
|
||||
}
|
||||
}
|
||||
|
||||
@validator("name", always=True)
|
||||
|
@ -30,7 +30,7 @@ class LinkNode(BaseModel):
|
||||
node_id: UUID
|
||||
adapter_number: int
|
||||
port_number: int
|
||||
label: Optional[Label]
|
||||
label: Optional[Label] = None
|
||||
|
||||
|
||||
class LinkType(str, Enum):
|
||||
|
@ -15,7 +15,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Optional
|
||||
from pydantic import EmailStr, BaseModel, Field
|
||||
from pydantic import EmailStr, BaseModel, Field, SecretStr
|
||||
from uuid import UUID
|
||||
|
||||
from .base import DateTimeModelMixin
|
||||
@ -37,7 +37,7 @@ class UserCreate(UserBase):
|
||||
"""
|
||||
|
||||
username: str = Field(..., min_length=3, regex="[a-zA-Z0-9_-]+$")
|
||||
password: str = Field(..., min_length=7, max_length=100)
|
||||
password: SecretStr = Field(..., min_length=7, max_length=100)
|
||||
|
||||
|
||||
class UserUpdate(UserBase):
|
||||
@ -45,7 +45,7 @@ class UserUpdate(UserBase):
|
||||
Properties to update an user.
|
||||
"""
|
||||
|
||||
password: Optional[str] = Field(None, min_length=7, max_length=100)
|
||||
password: Optional[SecretStr] = Field(None, min_length=7, max_length=100)
|
||||
|
||||
|
||||
class User(DateTimeModelMixin, UserBase):
|
||||
|
Loading…
Reference in New Issue
Block a user