From 8c7c17b8895fb18466cc062209264dc6c1e49b66 Mon Sep 17 00:00:00 2001 From: grossmj Date: Thu, 31 Oct 2024 17:09:52 +1000 Subject: [PATCH] Upgrade dependencies and fix Pydantic warnings --- .../schemas/compute/ethernet_switch_nodes.py | 2 +- .../controller/templates/cloud_templates.py | 4 ++-- .../controller/templates/docker_templates.py | 6 ++--- .../templates/dynamips_templates.py | 10 ++++---- .../templates/ethernet_hub_templates.py | 2 +- .../templates/ethernet_switch_templates.py | 4 ++-- .../controller/templates/iou_templates.py | 4 ++-- .../controller/templates/qemu_templates.py | 24 +++++++++---------- .../templates/virtualbox_templates.py | 9 ++++--- .../controller/templates/vmware_templates.py | 8 +++---- .../controller/templates/vpcs_templates.py | 4 ++-- requirements.txt | 17 ++++++------- tests/compute/docker/test_docker_vm.py | 1 + tests/compute/qemu/test_qemu_vm.py | 1 + tests/controller/test_import_project.py | 1 + 15 files changed, 50 insertions(+), 47 deletions(-) diff --git a/gns3server/schemas/compute/ethernet_switch_nodes.py b/gns3server/schemas/compute/ethernet_switch_nodes.py index 62c3a66c..ddb4b32c 100644 --- a/gns3server/schemas/compute/ethernet_switch_nodes.py +++ b/gns3server/schemas/compute/ethernet_switch_nodes.py @@ -43,7 +43,7 @@ class EthernetSwitchPort(BaseModel): port_number: int type: EthernetSwitchPortType = Field(..., description="Port type") vlan: int = Field(..., ge=1, le=4094, description="VLAN number") - ethertype: Optional[EthernetSwitchEtherType] = Field("0x8100", description="QinQ Ethertype") + ethertype: Optional[EthernetSwitchEtherType] = Field(EthernetSwitchEtherType.ethertype_8021q, description="QinQ Ethertype") @model_validator(mode="after") def check_ethertype(self) -> "EthernetSwitchPort": diff --git a/gns3server/schemas/controller/templates/cloud_templates.py b/gns3server/schemas/controller/templates/cloud_templates.py index 40695cdd..1754911a 100644 --- a/gns3server/schemas/controller/templates/cloud_templates.py +++ b/gns3server/schemas/controller/templates/cloud_templates.py @@ -29,13 +29,13 @@ from typing import Optional, Union, List class CloudTemplate(TemplateBase): - category: Optional[Category] = "guest" + category: Optional[Category] = Category.guest default_name_format: Optional[str] = "Cloud{0}" symbol: Optional[str] = "cloud" ports_mapping: List[Union[EthernetPort, TAPPort, UDPPort]] = Field(default_factory=list) remote_console_host: Optional[str] = Field("127.0.0.1", description="Remote console host or IP") remote_console_port: Optional[int] = Field(23, gt=0, le=65535, description="Remote console TCP port") - remote_console_type: Optional[CloudConsoleType] = Field("none", description="Remote console type") + remote_console_type: Optional[CloudConsoleType] = Field(CloudConsoleType.none, description="Remote console type") remote_console_http_path: Optional[str] = Field("/", description="Path of the remote web interface") diff --git a/gns3server/schemas/controller/templates/docker_templates.py b/gns3server/schemas/controller/templates/docker_templates.py index cd8010c2..329de37a 100644 --- a/gns3server/schemas/controller/templates/docker_templates.py +++ b/gns3server/schemas/controller/templates/docker_templates.py @@ -24,7 +24,7 @@ from typing import Optional, List class DockerTemplate(TemplateBase): - category: Optional[Category] = "guest" + category: Optional[Category] = Category.guest default_name_format: Optional[str] = "{name}-{0}" symbol: Optional[str] = "docker_guest" image: str = Field(..., description="Docker image name") @@ -32,8 +32,8 @@ class DockerTemplate(TemplateBase): mac_address: Optional[str] = Field("", description="Base MAC address", pattern="^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$|^$") start_command: Optional[str] = Field("", description="Docker CMD entry") environment: Optional[str] = Field("", description="Docker environment variables") - console_type: Optional[ConsoleType] = Field("telnet", description="Console type") - aux_type: Optional[AuxType] = Field("none", description="Auxiliary console type") + console_type: Optional[ConsoleType] = Field(ConsoleType.telnet, description="Console type") + aux_type: Optional[AuxType] = Field(AuxType.none, description="Auxiliary console type") console_auto_start: Optional[bool] = Field( False, description="Automatically start the console when the node has started" ) diff --git a/gns3server/schemas/controller/templates/dynamips_templates.py b/gns3server/schemas/controller/templates/dynamips_templates.py index 5f0d5773..4fb5235a 100644 --- a/gns3server/schemas/controller/templates/dynamips_templates.py +++ b/gns3server/schemas/controller/templates/dynamips_templates.py @@ -32,7 +32,7 @@ from enum import Enum class DynamipsTemplate(TemplateBase): - category: Optional[Category] = "router" + category: Optional[Category] = Category.router default_name_format: Optional[str] = "R{0}" symbol: Optional[str] = "router" platform: DynamipsPlatform = Field(..., description="Cisco router platform") @@ -51,11 +51,11 @@ class DynamipsTemplate(TemplateBase): disk0: Optional[int] = Field(0, description="Disk0 size in MB") disk1: Optional[int] = Field(0, description="Disk1 size in MB") auto_delete_disks: Optional[bool] = Field(False, description="Automatically delete nvram and disk files") - console_type: Optional[DynamipsConsoleType] = Field("telnet", description="Console type") + console_type: Optional[DynamipsConsoleType] = Field(DynamipsConsoleType.telnet, description="Console type") console_auto_start: Optional[bool] = Field( False, description="Automatically start the console when the node has started" ) - aux_type: Optional[DynamipsConsoleType] = Field("none", description="Auxiliary console type") + aux_type: Optional[DynamipsConsoleType] = Field(DynamipsConsoleType.none, description="Auxiliary console type") slot0: Optional[DynamipsAdapters] = Field(None, description="Network module slot 0") slot1: Optional[DynamipsAdapters] = Field(None, description="Network module slot 1") slot2: Optional[DynamipsAdapters] = Field(None, description="Network module slot 2") @@ -72,8 +72,8 @@ class C7200DynamipsTemplate(DynamipsTemplate): ram: Optional[int] = Field(512, description="Amount of RAM in MB") nvram: Optional[int] = Field(512, description="Amount of NVRAM in KB") - npe: Optional[DynamipsNPE] = Field("npe-400", description="NPE model") - midplane: Optional[DynamipsMidplane] = Field("vxr", description="Midplane model") + npe: Optional[DynamipsNPE] = Field(DynamipsNPE.npe_400, description="NPE model") + midplane: Optional[DynamipsMidplane] = Field(DynamipsMidplane.vxr, description="Midplane model") sparsemem: Optional[bool] = Field(True, description="Sparse memory feature") diff --git a/gns3server/schemas/controller/templates/ethernet_hub_templates.py b/gns3server/schemas/controller/templates/ethernet_hub_templates.py index 263a942c..23b04241 100644 --- a/gns3server/schemas/controller/templates/ethernet_hub_templates.py +++ b/gns3server/schemas/controller/templates/ethernet_hub_templates.py @@ -35,7 +35,7 @@ DEFAULT_PORTS = [ class EthernetHubTemplate(TemplateBase): - category: Optional[Category] = "switch" + category: Optional[Category] = Category.switch default_name_format: Optional[str] = "Hub{0}" symbol: Optional[str] = "hub" ports_mapping: Optional[List[EthernetHubPort]] = Field(DEFAULT_PORTS, description="Ports") diff --git a/gns3server/schemas/controller/templates/ethernet_switch_templates.py b/gns3server/schemas/controller/templates/ethernet_switch_templates.py index 4831d2a4..f4e83a0a 100644 --- a/gns3server/schemas/controller/templates/ethernet_switch_templates.py +++ b/gns3server/schemas/controller/templates/ethernet_switch_templates.py @@ -45,11 +45,11 @@ class ConsoleType(str, Enum): class EthernetSwitchTemplate(TemplateBase): - category: Optional[Category] = "switch" + category: Optional[Category] = Category.switch default_name_format: Optional[str] = "Switch{0}" symbol: Optional[str] = "ethernet_switch" ports_mapping: Optional[List[EthernetSwitchPort]] = Field(DEFAULT_PORTS, description="Ports") - console_type: Optional[ConsoleType] = Field("none", description="Console type") + console_type: Optional[ConsoleType] = Field(ConsoleType.none, description="Console type") class EthernetSwitchTemplateUpdate(EthernetSwitchTemplate): diff --git a/gns3server/schemas/controller/templates/iou_templates.py b/gns3server/schemas/controller/templates/iou_templates.py index 4f2d3f38..cf581c8c 100644 --- a/gns3server/schemas/controller/templates/iou_templates.py +++ b/gns3server/schemas/controller/templates/iou_templates.py @@ -24,7 +24,7 @@ from typing import Optional class IOUTemplate(TemplateBase): - category: Optional[Category] = "router" + category: Optional[Category] = Category.router default_name_format: Optional[str] = "IOU{0}" symbol: Optional[str] = "multilayer_switch" path: str = Field(..., description="Path of IOU executable") @@ -36,7 +36,7 @@ class IOUTemplate(TemplateBase): startup_config: Optional[str] = Field("iou_l3_base_startup-config.txt", description="Startup-config of IOU") private_config: Optional[str] = Field("", description="Private-config of IOU") l1_keepalives: Optional[bool] = Field(False, description="Always keep up Ethernet interface (does not always work)") - console_type: Optional[ConsoleType] = Field("telnet", description="Console type") + console_type: Optional[ConsoleType] = Field(ConsoleType.telnet, description="Console type") console_auto_start: Optional[bool] = Field( False, description="Automatically start the console when the node has started" ) diff --git a/gns3server/schemas/controller/templates/qemu_templates.py b/gns3server/schemas/controller/templates/qemu_templates.py index 5b73f50d..f5353d7b 100644 --- a/gns3server/schemas/controller/templates/qemu_templates.py +++ b/gns3server/schemas/controller/templates/qemu_templates.py @@ -33,17 +33,17 @@ from typing import Optional, List class QemuTemplate(TemplateBase): - category: Optional[Category] = "guest" + category: Optional[Category] = Category.guest default_name_format: Optional[str] = "{name}-{0}" symbol: Optional[str] = "qemu_guest" qemu_path: Optional[str] = Field("", description="Qemu executable path") - platform: Optional[QemuPlatform] = Field("x86_64", description="Platform to emulate") + platform: Optional[QemuPlatform] = Field(QemuPlatform.x86_64, description="Platform to emulate") linked_clone: Optional[bool] = Field(True, description="Whether the VM is a linked clone or not") ram: Optional[int] = Field(256, description="Amount of RAM in MB") cpus: Optional[int] = Field(1, ge=1, le=255, description="Number of vCPUs") maxcpus: Optional[int] = Field(1, ge=1, le=255, description="Maximum number of hotpluggable vCPUs") adapters: Optional[int] = Field(1, ge=0, le=275, description="Number of adapters") - adapter_type: Optional[QemuAdapterType] = Field("e1000", description="QEMU adapter type") + adapter_type: Optional[QemuAdapterType] = Field(QemuAdapterType.e1000, description="QEMU adapter type") mac_address: Optional[str] = Field( "", description="QEMU MAC address", pattern="^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$|^$" ) @@ -55,20 +55,20 @@ class QemuTemplate(TemplateBase): 0, description="Optional port segment size. A port segment is a block of port. For example Ethernet0/0 Ethernet0/1 is the module 0 with a port segment size of 2", ) - console_type: Optional[QemuConsoleType] = Field("telnet", description="Console type") + console_type: Optional[QemuConsoleType] = Field(QemuConsoleType.telnet, description="Console type") console_auto_start: Optional[bool] = Field( False, description="Automatically start the console when the node has started" ) - aux_type: Optional[QemuConsoleType] = Field("none", description="Auxiliary console type") - boot_priority: Optional[QemuBootPriority] = Field("c", description="QEMU boot priority") + aux_type: Optional[QemuConsoleType] = Field(QemuConsoleType.none, description="Auxiliary console type") + boot_priority: Optional[QemuBootPriority] = Field(QemuBootPriority.c, description="QEMU boot priority") hda_disk_image: Optional[str] = Field("", description="QEMU hda disk image path") - hda_disk_interface: Optional[QemuDiskInterfaceType] = Field("none", description="QEMU hda interface") + hda_disk_interface: Optional[QemuDiskInterfaceType] = Field(QemuDiskInterfaceType.none, description="QEMU hda interface") hdb_disk_image: Optional[str] = Field("", description="QEMU hdb disk image path") - hdb_disk_interface: Optional[QemuDiskInterfaceType] = Field("none", description="QEMU hdb interface") + hdb_disk_interface: Optional[QemuDiskInterfaceType] = Field(QemuDiskInterfaceType.none, description="QEMU hdb interface") hdc_disk_image: Optional[str] = Field("", description="QEMU hdc disk image path") - hdc_disk_interface: Optional[QemuDiskInterfaceType] = Field("none", description="QEMU hdc interface") + hdc_disk_interface: Optional[QemuDiskInterfaceType] = Field(QemuDiskInterfaceType.none, description="QEMU hdc interface") hdd_disk_image: Optional[str] = Field("", description="QEMU hdd disk image path") - hdd_disk_interface: Optional[QemuDiskInterfaceType] = Field("none", description="QEMU hdd interface") + hdd_disk_interface: Optional[QemuDiskInterfaceType] = Field(QemuDiskInterfaceType.none, description="QEMU hdd interface") cdrom_image: Optional[str] = Field("", description="QEMU cdrom image path") initrd: Optional[str] = Field("", description="QEMU initrd path") kernel_image: Optional[str] = Field("", description="QEMU kernel image path") @@ -82,9 +82,9 @@ class QemuTemplate(TemplateBase): ) tpm: Optional[bool] = Field(False, description="Enable Trusted Platform Module (TPM)") uefi: Optional[bool] = Field(False, description="Enable UEFI boot mode") - on_close: Optional[QemuOnCloseAction] = Field("power_off", description="Action to execute on the VM is closed") + on_close: Optional[QemuOnCloseAction] = Field(QemuOnCloseAction.power_off, description="Action to execute on the VM is closed") cpu_throttling: Optional[int] = Field(0, ge=0, le=800, description="Percentage of CPU allowed for QEMU") - process_priority: Optional[QemuProcessPriority] = Field("normal", description="Process priority for QEMU") + process_priority: Optional[QemuProcessPriority] = Field(QemuProcessPriority.normal, description="Process priority for QEMU") options: Optional[str] = Field("", description="Additional QEMU options") custom_adapters: Optional[List[CustomAdapter]] = Field(default_factory=list, description="Custom adapters") diff --git a/gns3server/schemas/controller/templates/virtualbox_templates.py b/gns3server/schemas/controller/templates/virtualbox_templates.py index 34fb6a1d..922cae6b 100644 --- a/gns3server/schemas/controller/templates/virtualbox_templates.py +++ b/gns3server/schemas/controller/templates/virtualbox_templates.py @@ -28,7 +28,7 @@ from typing import Optional, List class VirtualBoxTemplate(TemplateBase): - category: Optional[Category] = "guest" + category: Optional[Category] = Category.guest default_name_format: Optional[str] = "{name}-{0}" symbol: Optional[str] = "vbox_guest" vmname: str = Field(..., description="VirtualBox VM name (in VirtualBox itself)") @@ -38,8 +38,7 @@ class VirtualBoxTemplate(TemplateBase): 1, ge=0, le=36, description="Number of adapters" ) # 36 is the maximum given by the ICH9 chipset in VirtualBox use_any_adapter: Optional[bool] = Field(False, description="Allow GNS3 to use any VirtualBox adapter") - adapter_type: Optional[VirtualBoxAdapterType] = Field( - "Intel PRO/1000 MT Desktop (82540EM)", description="VirtualBox adapter type" + adapter_type: Optional[VirtualBoxAdapterType] = Field(VirtualBoxAdapterType.intel_pro_1000_mt_desktop, description="VirtualBox adapter type" ) first_port_name: Optional[str] = Field("", description="Optional name of the first networking port example: eth0") port_name_format: Optional[str] = Field( @@ -51,9 +50,9 @@ class VirtualBoxTemplate(TemplateBase): ) headless: Optional[bool] = Field(False, description="Headless mode") on_close: Optional[VirtualBoxOnCloseAction] = Field( - "power_off", description="Action to execute on the VM is closed" + VirtualBoxOnCloseAction.power_off, description="Action to execute on the VM is closed" ) - console_type: Optional[VirtualBoxConsoleType] = Field("none", description="Console type") + console_type: Optional[VirtualBoxConsoleType] = Field(VirtualBoxConsoleType.none, description="Console type") console_auto_start: Optional[bool] = Field( False, description="Automatically start the console when the node has started" ) diff --git a/gns3server/schemas/controller/templates/vmware_templates.py b/gns3server/schemas/controller/templates/vmware_templates.py index 7109e5d0..555e5189 100644 --- a/gns3server/schemas/controller/templates/vmware_templates.py +++ b/gns3server/schemas/controller/templates/vmware_templates.py @@ -29,7 +29,7 @@ from typing import Optional, List class VMwareTemplate(TemplateBase): - category: Optional[Category] = "guest" + category: Optional[Category] = Category.guest default_name_format: Optional[str] = "{name}-{0}" symbol: Optional[str] = "vmware_guest" vmx_path: str = Field(..., description="Path to the vmx file") @@ -45,11 +45,11 @@ class VMwareTemplate(TemplateBase): adapters: Optional[int] = Field( 1, ge=0, le=10, description="Number of adapters" ) # 10 is the maximum adapters support by VMware VMs - adapter_type: Optional[VMwareAdapterType] = Field("e1000", description="VMware adapter type") + adapter_type: Optional[VMwareAdapterType] = Field(VMwareAdapterType.e1000, description="VMware adapter type") use_any_adapter: Optional[bool] = Field(False, description="Allow GNS3 to use any VMware adapter") headless: Optional[bool] = Field(False, description="Headless mode") - on_close: Optional[VMwareOnCloseAction] = Field("power_off", description="Action to execute on the VM is closed") - console_type: Optional[VMwareConsoleType] = Field("none", description="Console type") + on_close: Optional[VMwareOnCloseAction] = Field(VMwareOnCloseAction.power_off, description="Action to execute on the VM is closed") + console_type: Optional[VMwareConsoleType] = Field(VMwareConsoleType.none, description="Console type") console_auto_start: Optional[bool] = Field( False, description="Automatically start the console when the node has started" ) diff --git a/gns3server/schemas/controller/templates/vpcs_templates.py b/gns3server/schemas/controller/templates/vpcs_templates.py index 5ed288c9..79d6f1c3 100644 --- a/gns3server/schemas/controller/templates/vpcs_templates.py +++ b/gns3server/schemas/controller/templates/vpcs_templates.py @@ -24,11 +24,11 @@ from typing import Optional class VPCSTemplate(TemplateBase): - category: Optional[Category] = "guest" + category: Optional[Category] = Category.guest default_name_format: Optional[str] = "PC{0}" symbol: Optional[str] = "vpcs_guest" base_script_file: Optional[str] = Field("vpcs_base_config.txt", description="Script file") - console_type: Optional[ConsoleType] = Field("telnet", description="Console type") + console_type: Optional[ConsoleType] = Field(ConsoleType.telnet, description="Console type") console_auto_start: Optional[bool] = Field( False, description="Automatically start the console when the node has started" ) diff --git a/requirements.txt b/requirements.txt index 0af21ef9..58608bc2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ -uvicorn==0.29.0 -fastapi==0.112.0 -python-multipart==0.0.9 -websockets==12.0 +uvicorn==0.32.0 +pydantic==2.9.2 +fastapi==0.113.0 +python-multipart==0.0.16 +websockets==13.1 aiohttp>=3.10.10,<3.11 async-timeout==4.0.3 aiofiles>=24.1.0,<25.0 @@ -10,14 +11,14 @@ sentry-sdk>=2.17,<2.18 # optional dependency psutil>=6.1.0 distro>=1.9.0 py-cpuinfo==9.0.0 -sqlalchemy==2.0.31 +sqlalchemy==2.0.36 aiosqlite==0.20.0 -alembic==1.12.1 +alembic==1.13.3 bcrypt==4.2.0 python-jose[cryptography]==3.3.0 email-validator==2.2.0 -watchfiles==0.22.0 +watchfiles==0.24.0 zstandard==0.23.0 -platformdirs==4.2.2 +platformdirs==4.3.6 importlib-resources>=1.3; python_version <= '3.9' truststore>=0.10.0; python_version >= '3.10' diff --git a/tests/compute/docker/test_docker_vm.py b/tests/compute/docker/test_docker_vm.py index c48c301d..8eaaef6f 100644 --- a/tests/compute/docker/test_docker_vm.py +++ b/tests/compute/docker/test_docker_vm.py @@ -1449,6 +1449,7 @@ async def test_add_ubridge_connection(vm): vm._ubridge_hypervisor.assert_has_calls(calls, any_order=True) +@pytest.mark.asyncio async def test_add_ubridge_connections_with_base_mac_address(vm): vm._ubridge_hypervisor = MagicMock() diff --git a/tests/compute/qemu/test_qemu_vm.py b/tests/compute/qemu/test_qemu_vm.py index e253aba7..d2348b23 100644 --- a/tests/compute/qemu/test_qemu_vm.py +++ b/tests/compute/qemu/test_qemu_vm.py @@ -793,6 +793,7 @@ async def test_build_command_with_invalid_options(vm): @pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows") +@pytest.mark.asyncio async def test_build_command_with_forbidden_options(vm): vm.options = "-blockdev" diff --git a/tests/controller/test_import_project.py b/tests/controller/test_import_project.py index 3b478fb5..e64e7fb1 100644 --- a/tests/controller/test_import_project.py +++ b/tests/controller/test_import_project.py @@ -122,6 +122,7 @@ async def write_file(path, z): f.write(chunk) +@pytest.mark.asyncio async def test_import_project_containing_symlink(tmpdir, controller): project = Project(controller=controller, name="test")