diff --git a/gns3server/agent/__init__.py b/gns3server/agent/__init__.py index bf6ecac3e..f27893a61 100644 --- a/gns3server/agent/__init__.py +++ b/gns3server/agent/__init__.py @@ -34,8 +34,7 @@ AI_COPILOT_AVAILABLE = False # Try to import AI Copilot components try: - from .gns3_copilot.project_agent_manager import get_project_agent_manager - from .gns3_copilot.project_agent_manager import ProjectAgentManager + from .gns3_copilot.project_agent_manager import ProjectAgentManager, get_project_agent_manager AI_COPILOT_AVAILABLE = True diff --git a/gns3server/agent/gns3_copilot/agent/context_manager.py b/gns3server/agent/gns3_copilot/agent/context_manager.py index a17338c83..48258729b 100644 --- a/gns3server/agent/gns3_copilot/agent/context_manager.py +++ b/gns3server/agent/gns3_copilot/agent/context_manager.py @@ -46,8 +46,7 @@ import logging import os import warnings from pathlib import Path -from typing import Any -from typing import Callable +from typing import Any, Callable # Configure tiktoken cache directory (must be set before importing tiktoken) _cache_dir = Path(__file__).parent.parent / "cache" / "tiktoken" @@ -55,9 +54,7 @@ _cache_dir.mkdir(parents=True, exist_ok=True) os.environ["TIKTOKEN_CACHE_DIR"] = str(_cache_dir) import tiktoken -from langchain_core.messages import BaseMessage -from langchain_core.messages import SystemMessage -from langchain_core.messages import trim_messages +from langchain_core.messages import BaseMessage, SystemMessage, trim_messages logger = logging.getLogger(__name__) diff --git a/gns3server/agent/gns3_copilot/agent/gns3_copilot.py b/gns3server/agent/gns3_copilot/agent/gns3_copilot.py index ac784cab0..148ccac63 100644 --- a/gns3server/agent/gns3_copilot/agent/gns3_copilot.py +++ b/gns3server/agent/gns3_copilot/agent/gns3_copilot.py @@ -50,17 +50,12 @@ import json import logging import operator from datetime import datetime -from typing import Annotated -from typing import Literal +from typing import Annotated, Literal # Third-party imports -from langchain.messages import AnyMessage -from langchain.messages import SystemMessage -from langchain.messages import ToolMessage +from langchain.messages import AnyMessage, SystemMessage, ToolMessage from langchain_core.runnables import RunnableConfig -from langgraph.graph import END -from langgraph.graph import START -from langgraph.graph import StateGraph +from langgraph.graph import END, START, StateGraph from langgraph.managed.is_last_step import RemainingSteps from typing_extensions import TypedDict @@ -70,8 +65,6 @@ from gns3server.agent.gns3_copilot.agent.context_manager import ( ) from gns3server.agent.gns3_copilot.agent.model_factory import ( create_base_model_with_tools, -) -from gns3server.agent.gns3_copilot.agent.model_factory import ( create_title_model, ) from gns3server.agent.gns3_copilot.gns3_client import GNS3TopologyTool @@ -79,27 +72,23 @@ from gns3server.agent.gns3_copilot.gns3_client.context_helpers import ( get_current_llm_config, ) from gns3server.agent.gns3_copilot.prompts import load_system_prompt +from gns3server.agent.gns3_copilot.skills import DeviceSkillsTool, InjectionSkillsTool, PacketAnalysisSkillsTool from gns3server.agent.gns3_copilot.skills.registry import get_prompt from gns3server.agent.gns3_copilot.tools_v2 import ( ExecuteMultipleDeviceCommands, -) -from gns3server.agent.gns3_copilot.tools_v2 import ( ExecuteMultipleDeviceConfigCommands, + GNS3CreateNodeTool, + GNS3LinkTool, + GNS3PacketFilterTool, + GNS3StartNodeTool, + GNS3StopNodeTool, + GNS3SuspendNodeTool, + GNS3TemplateTool, + GNS3UpdateNodeNameTool, + GNS3WaitTool, + PacketAnalysisTool, ) -from gns3server.agent.gns3_copilot.tools_v2 import GNS3CreateNodeTool -from gns3server.agent.gns3_copilot.tools_v2 import GNS3LinkTool -from gns3server.agent.gns3_copilot.tools_v2 import GNS3PacketFilterTool -from gns3server.agent.gns3_copilot.tools_v2 import GNS3StartNodeTool -from gns3server.agent.gns3_copilot.tools_v2 import GNS3StopNodeTool -from gns3server.agent.gns3_copilot.tools_v2 import GNS3SuspendNodeTool -from gns3server.agent.gns3_copilot.tools_v2 import GNS3TemplateTool -from gns3server.agent.gns3_copilot.tools_v2 import GNS3UpdateNodeNameTool -from gns3server.agent.gns3_copilot.tools_v2 import GNS3WaitTool from gns3server.agent.gns3_copilot.tools_v2.vpcs_tools_netmiko import VPCSCommands -from gns3server.agent.gns3_copilot.tools_v2 import PacketAnalysisTool -from gns3server.agent.gns3_copilot.skills import DeviceSkillsTool -from gns3server.agent.gns3_copilot.skills import InjectionSkillsTool -from gns3server.agent.gns3_copilot.skills import PacketAnalysisSkillsTool # Set up logger for GNS3-Copilot logger = logging.getLogger(__name__) diff --git a/gns3server/agent/gns3_copilot/agent/model_factory.py b/gns3server/agent/gns3_copilot/agent/model_factory.py index f790646bd..5700b38bc 100644 --- a/gns3server/agent/gns3_copilot/agent/model_factory.py +++ b/gns3server/agent/gns3_copilot/agent/model_factory.py @@ -32,8 +32,7 @@ Configuration is passed directly from the database. """ import logging -from typing import Any -from typing import Optional +from typing import Any, Optional from langchain.chat_models import init_chat_model diff --git a/gns3server/agent/gns3_copilot/agent_service.py b/gns3server/agent/gns3_copilot/agent_service.py index 32c71c981..be6ed201d 100644 --- a/gns3server/agent/gns3_copilot/agent_service.py +++ b/gns3server/agent/gns3_copilot/agent_service.py @@ -36,11 +36,7 @@ import json import logging import os from datetime import datetime -from typing import Any -from typing import AsyncGenerator -from typing import Dict -from typing import List -from typing import Optional +from typing import Any, AsyncGenerator, Dict, List, Optional from uuid import uuid4 import aiosqlite @@ -53,8 +49,6 @@ from gns3server.agent.gns3_copilot.chat_sessions_repository import ( ) from gns3server.agent.gns3_copilot.gns3_client.context_helpers import ( set_current_jwt_token, -) -from gns3server.agent.gns3_copilot.gns3_client.context_helpers import ( set_current_llm_config, ) from gns3server.agent.gns3_copilot.utils.error_handler import format_error_message diff --git a/gns3server/agent/gns3_copilot/chat_sessions_repository.py b/gns3server/agent/gns3_copilot/chat_sessions_repository.py index 41006f299..d263f35cf 100644 --- a/gns3server/agent/gns3_copilot/chat_sessions_repository.py +++ b/gns3server/agent/gns3_copilot/chat_sessions_repository.py @@ -33,10 +33,7 @@ checkpoint database. import json import logging from datetime import datetime -from typing import Any -from typing import Dict -from typing import List -from typing import Optional +from typing import Any, Dict, List, Optional import aiosqlite diff --git a/gns3server/agent/gns3_copilot/gns3_client/__init__.py b/gns3server/agent/gns3_copilot/gns3_client/__init__.py index 16fb366c5..326c0f886 100644 --- a/gns3server/agent/gns3_copilot/gns3_client/__init__.py +++ b/gns3server/agent/gns3_copilot/gns3_client/__init__.py @@ -47,14 +47,18 @@ The connector is adapted from the upstream gns3fy project from .api_handlers import build_gns3_ctx from .connector import Gns3Connector -from .connector_factory import get_gns3_connector -from .connector_factory import get_gns3_connector_with_llm_config -from .connector_factory import get_gns3_server_host -from .connector_factory import get_llm_config -from .context_helpers import get_current_jwt_token -from .context_helpers import get_current_llm_config -from .context_helpers import set_current_jwt_token -from .context_helpers import set_current_llm_config +from .connector_factory import ( + get_gns3_connector, + get_gns3_connector_with_llm_config, + get_gns3_server_host, + get_llm_config, +) +from .context_helpers import ( + get_current_jwt_token, + get_current_llm_config, + set_current_jwt_token, + set_current_llm_config, +) from .gns3_project_info import GNS3ProjectInfoTool from .gns3_topology_reader import GNS3TopologyTool diff --git a/gns3server/agent/gns3_copilot/gns3_client/api_handlers.py b/gns3server/agent/gns3_copilot/gns3_client/api_handlers.py index 7f6ca8c95..bce5ba091 100644 --- a/gns3server/agent/gns3_copilot/gns3_client/api_handlers.py +++ b/gns3server/agent/gns3_copilot/gns3_client/api_handlers.py @@ -47,16 +47,14 @@ Copilot-side callers build the context with :func:`build_gns3_ctx`, which pulls the request-scoped user JWT from the context variables. """ -from typing import Any -from concurrent.futures import ThreadPoolExecutor - import hashlib import logging - -from gns3server.services import access_ticket_service -from gns3server.services.access_tickets import DEFAULT_TICKET_TTL +from concurrent.futures import ThreadPoolExecutor +from typing import Any from gns3server.agent.gns3_copilot.gns3_client.connector import Gns3Connector +from gns3server.services import access_ticket_service +from gns3server.services.access_tickets import DEFAULT_TICKET_TTL log = logging.getLogger(__name__) diff --git a/gns3server/agent/gns3_copilot/gns3_client/connector_factory.py b/gns3server/agent/gns3_copilot/gns3_client/connector_factory.py index 32a4e2e45..0bf95f845 100644 --- a/gns3server/agent/gns3_copilot/gns3_client/connector_factory.py +++ b/gns3server/agent/gns3_copilot/gns3_client/connector_factory.py @@ -49,14 +49,13 @@ import logging from typing import Optional from uuid import UUID -from gns3server.agent.gns3_copilot.gns3_client.context_helpers import ( - get_current_jwt_token, -) - # Local imports from gns3server.agent.gns3_copilot.gns3_client.connector import ( Gns3Connector, ) +from gns3server.agent.gns3_copilot.gns3_client.context_helpers import ( + get_current_jwt_token, +) logger = logging.getLogger(__name__) diff --git a/gns3server/agent/gns3_copilot/project_agent_manager.py b/gns3server/agent/gns3_copilot/project_agent_manager.py index b9ade018a..7448a55b9 100644 --- a/gns3server/agent/gns3_copilot/project_agent_manager.py +++ b/gns3server/agent/gns3_copilot/project_agent_manager.py @@ -33,8 +33,7 @@ database. import asyncio import logging -from typing import Dict -from typing import Optional +from typing import Dict, Optional from gns3server.agent.gns3_copilot.agent_service import AgentService diff --git a/gns3server/agent/gns3_copilot/skills/__init__.py b/gns3server/agent/gns3_copilot/skills/__init__.py index 6dd522dca..891389d12 100644 --- a/gns3server/agent/gns3_copilot/skills/__init__.py +++ b/gns3server/agent/gns3_copilot/skills/__init__.py @@ -36,23 +36,23 @@ Directory Structure: - loader.py # SkillsLoader - YAML/Markdown file loading """ +from .loader import SkillsLoader +from .manager import SkillsManager from .registry import ( - SKILLS_REGISTRY, INJECTION_SKILLS_REGISTRY, - get_skill, - get_injection_skill, + SKILLS_REGISTRY, DeviceSkillsTool, InjectionSkillsTool, PacketAnalysisSkillsTool, - set_skills_manager, + get_injection_skill, + get_skill, get_skills_manager, - reload_injection_skills, - reload_forbidden_commands, - reload_skills_repository, get_skills_repository_info, + reload_forbidden_commands, + reload_injection_skills, + reload_skills_repository, + set_skills_manager, ) -from .manager import SkillsManager -from .loader import SkillsLoader __all__ = [ "INJECTION_SKILLS_REGISTRY", diff --git a/gns3server/agent/gns3_copilot/skills/manager.py b/gns3server/agent/gns3_copilot/skills/manager.py index 3195b4611..ef62562ce 100644 --- a/gns3server/agent/gns3_copilot/skills/manager.py +++ b/gns3server/agent/gns3_copilot/skills/manager.py @@ -33,7 +33,7 @@ including Git operations and hot reload of skills. import logging import os from pathlib import Path -from typing import Optional, Dict, Any +from typing import Any, Dict, Optional try: import git @@ -43,6 +43,7 @@ except ImportError: GIT_AVAILABLE = False from gns3server.config import Config + from .loader import SkillsLoader logger = logging.getLogger(__name__) diff --git a/gns3server/agent/gns3_copilot/skills/registry.py b/gns3server/agent/gns3_copilot/skills/registry.py index aa67cd51b..782215dd0 100644 --- a/gns3server/agent/gns3_copilot/skills/registry.py +++ b/gns3server/agent/gns3_copilot/skills/registry.py @@ -183,8 +183,8 @@ def reload_skills_repository() -> dict[str, Any]: protocols_ok = manager.reload_packet_analysis_protocols() # Reload forbidden commands (local import to avoid circular dependency) - from gns3server.agent.gns3_copilot.utils.command_filter import reload_forbidden_commands as _reload_fc from gns3server.agent.gns3_copilot.utils.command_filter import get_forbidden_commands + from gns3server.agent.gns3_copilot.utils.command_filter import reload_forbidden_commands as _reload_fc _reload_fc() forbidden_commands = get_forbidden_commands() @@ -300,8 +300,8 @@ def reload_forbidden_commands() -> dict[str, Any]: } """ try: - from gns3server.agent.gns3_copilot.utils.command_filter import reload_forbidden_commands as _reload from gns3server.agent.gns3_copilot.utils.command_filter import get_forbidden_commands + from gns3server.agent.gns3_copilot.utils.command_filter import reload_forbidden_commands as _reload _reload() commands = get_forbidden_commands() diff --git a/gns3server/agent/gns3_copilot/tools_v2/__init__.py b/gns3server/agent/gns3_copilot/tools_v2/__init__.py index aacf4423f..0818bd81c 100644 --- a/gns3server/agent/gns3_copilot/tools_v2/__init__.py +++ b/gns3server/agent/gns3_copilot/tools_v2/__init__.py @@ -58,8 +58,7 @@ from .gns3_create_link import GNS3LinkTool from .gns3_create_node import GNS3CreateNodeTool from .gns3_get_node_temp import GNS3TemplateTool from .gns3_packet_filter import GNS3PacketFilterTool -from .gns3_start_node import GNS3StartNodeQuickTool -from .gns3_start_node import GNS3StartNodeTool +from .gns3_start_node import GNS3StartNodeQuickTool, GNS3StartNodeTool from .gns3_stop_node import GNS3StopNodeTool from .gns3_suspend_node import GNS3SuspendNodeTool from .gns3_update_node_name import GNS3UpdateNodeNameTool diff --git a/gns3server/agent/gns3_copilot/tools_v2/config_tools_nornir.py b/gns3server/agent/gns3_copilot/tools_v2/config_tools_nornir.py index 250fb559d..79cd175f5 100644 --- a/gns3server/agent/gns3_copilot/tools_v2/config_tools_nornir.py +++ b/gns3server/agent/gns3_copilot/tools_v2/config_tools_nornir.py @@ -43,21 +43,18 @@ from langchain_core.callbacks import CallbackManagerForToolRun from netmiko.exceptions import ReadTimeout from nornir import InitNornir from nornir.core import Nornir -from nornir.core.task import AggregatedResult -from nornir.core.task import Result -from nornir.core.task import Task +from nornir.core.task import AggregatedResult, Result, Task from nornir_netmiko.tasks import netmiko_send_config from gns3server.agent.gns3_copilot.gns3_client import get_gns3_server_host -from gns3server.agent.gns3_copilot.utils import get_device_ports_from_topology -from gns3server.agent.gns3_copilot.utils.command_filter import ( - filter_forbidden_commands, -) # Import custom Netmiko device types for GNS3 emulation # This registers gns3_huawei_telnet_ce and other custom device types # NOTE: Must be imported BEFORE any Nornir operations to ensure device types are registered -from gns3server.agent.gns3_copilot.utils import custom_netmiko +from gns3server.agent.gns3_copilot.utils import custom_netmiko, get_device_ports_from_topology +from gns3server.agent.gns3_copilot.utils.command_filter import ( + filter_forbidden_commands, +) # Explicitly register custom device types to ensure they are available # This is a safety measure in case the auto-registration on import doesn't work diff --git a/gns3server/agent/gns3_copilot/tools_v2/display_tools_nornir.py b/gns3server/agent/gns3_copilot/tools_v2/display_tools_nornir.py index ab31e9978..428170794 100644 --- a/gns3server/agent/gns3_copilot/tools_v2/display_tools_nornir.py +++ b/gns3server/agent/gns3_copilot/tools_v2/display_tools_nornir.py @@ -43,21 +43,18 @@ from langchain_core.callbacks import CallbackManagerForToolRun from netmiko.exceptions import ReadTimeout from nornir import InitNornir from nornir.core import Nornir -from nornir.core.task import AggregatedResult -from nornir.core.task import Result -from nornir.core.task import Task +from nornir.core.task import AggregatedResult, Result, Task from nornir_netmiko.tasks import netmiko_multiline from gns3server.agent.gns3_copilot.gns3_client import get_gns3_server_host -from gns3server.agent.gns3_copilot.utils import get_device_ports_from_topology -from gns3server.agent.gns3_copilot.utils.command_filter import ( - filter_forbidden_commands, -) # Import custom Netmiko device types for GNS3 emulation # This registers gns3_huawei_telnet_ce and other custom device types # NOTE: Must be imported BEFORE any Nornir operations to ensure device types are registered -from gns3server.agent.gns3_copilot.utils import custom_netmiko +from gns3server.agent.gns3_copilot.utils import custom_netmiko, get_device_ports_from_topology +from gns3server.agent.gns3_copilot.utils.command_filter import ( + filter_forbidden_commands, +) # Explicitly register custom device types to ensure they are available # This is a safety measure in case the auto-registration on import doesn't work diff --git a/gns3server/agent/gns3_copilot/tools_v2/vpcs_tools_netmiko.py b/gns3server/agent/gns3_copilot/tools_v2/vpcs_tools_netmiko.py index 26a512dc5..e1ce51fa6 100644 --- a/gns3server/agent/gns3_copilot/tools_v2/vpcs_tools_netmiko.py +++ b/gns3server/agent/gns3_copilot/tools_v2/vpcs_tools_netmiko.py @@ -43,18 +43,15 @@ from langchain_core.callbacks import CallbackManagerForToolRun from netmiko.exceptions import ReadTimeout from nornir import InitNornir from nornir.core import Nornir -from nornir.core.task import AggregatedResult -from nornir.core.task import Result -from nornir.core.task import Task +from nornir.core.task import AggregatedResult, Result, Task from nornir_netmiko.tasks import netmiko_multiline from gns3server.agent.gns3_copilot.gns3_client import get_gns3_server_host -from gns3server.agent.gns3_copilot.utils import get_device_ports_from_topology # Import custom Netmiko device types for GNS3 emulation # This registers gns3_vpcs_telnet and other custom device types # NOTE: Must be imported BEFORE any Nornir operations to ensure device types are registered -from gns3server.agent.gns3_copilot.utils import custom_netmiko +from gns3server.agent.gns3_copilot.utils import custom_netmiko, get_device_ports_from_topology # Explicitly register VPCS device type to ensure it is available try: diff --git a/gns3server/agent/gns3_copilot/utils/__init__.py b/gns3server/agent/gns3_copilot/utils/__init__.py index 7beb1d745..59cfca0a7 100644 --- a/gns3server/agent/gns3_copilot/utils/__init__.py +++ b/gns3server/agent/gns3_copilot/utils/__init__.py @@ -39,9 +39,7 @@ Author: Yue Guobin (岳国宾) # Import main utility functions from .error_handler import format_error_message from .get_gns3_device_port import get_device_ports_from_topology -from .parse_tool_content import format_tool_response -from .parse_tool_content import normalize_tool_response -from .parse_tool_content import parse_tool_content +from .parse_tool_content import format_tool_response, normalize_tool_response, parse_tool_content # Dynamic version management try: diff --git a/gns3server/agent/gns3_copilot/utils/custom_netmiko/scripts/list_netmiko_telnet_devices.py b/gns3server/agent/gns3_copilot/utils/custom_netmiko/scripts/list_netmiko_telnet_devices.py index 3097dd954..de517249f 100644 --- a/gns3server/agent/gns3_copilot/utils/custom_netmiko/scripts/list_netmiko_telnet_devices.py +++ b/gns3server/agent/gns3_copilot/utils/custom_netmiko/scripts/list_netmiko_telnet_devices.py @@ -31,8 +31,8 @@ Features: import os import sys -from typing import Dict, List, Tuple from datetime import datetime +from typing import Dict, List, Tuple def get_netmiko_version() -> str: diff --git a/gns3server/agent/gns3_copilot/utils/custom_netmiko/tests/test_huawei_ce.py b/gns3server/agent/gns3_copilot/utils/custom_netmiko/tests/test_huawei_ce.py index 62343c3ef..4e231ae62 100644 --- a/gns3server/agent/gns3_copilot/utils/custom_netmiko/tests/test_huawei_ce.py +++ b/gns3server/agent/gns3_copilot/utils/custom_netmiko/tests/test_huawei_ce.py @@ -18,10 +18,10 @@ This script tests: Run with: python test_huawei_ce.py """ +import os import sys import unittest from unittest.mock import Mock, patch -import os # Add project root to path using relative path test_dir = os.path.dirname(os.path.abspath(__file__)) diff --git a/gns3server/agent/gns3_copilot/utils/custom_netmiko/tests/test_ruijie_telnet.py b/gns3server/agent/gns3_copilot/utils/custom_netmiko/tests/test_ruijie_telnet.py index adfbafea2..3ff869bf6 100644 --- a/gns3server/agent/gns3_copilot/utils/custom_netmiko/tests/test_ruijie_telnet.py +++ b/gns3server/agent/gns3_copilot/utils/custom_netmiko/tests/test_ruijie_telnet.py @@ -18,10 +18,10 @@ This script tests: Run with: python test_ruijie_telnet.py """ +import os import sys import unittest from unittest.mock import Mock, patch -import os # Add project root to path using relative path test_dir = os.path.dirname(os.path.abspath(__file__)) diff --git a/gns3server/agent/gns3_copilot/utils/custom_netmiko/tests/test_vpcs_telnet.py b/gns3server/agent/gns3_copilot/utils/custom_netmiko/tests/test_vpcs_telnet.py index f24565d85..36b173db7 100644 --- a/gns3server/agent/gns3_copilot/utils/custom_netmiko/tests/test_vpcs_telnet.py +++ b/gns3server/agent/gns3_copilot/utils/custom_netmiko/tests/test_vpcs_telnet.py @@ -20,10 +20,10 @@ This script tests: Run with: python test_vpcs_telnet.py """ +import os import sys import unittest -from unittest.mock import Mock, patch, MagicMock -import os +from unittest.mock import MagicMock, Mock, patch # Add project root to path using relative path test_dir = os.path.dirname(os.path.abspath(__file__)) diff --git a/gns3server/agent/gns3_copilot/utils/custom_netmiko/vpcs_telnet.py b/gns3server/agent/gns3_copilot/utils/custom_netmiko/vpcs_telnet.py index 0711f9c5d..863f52cdb 100644 --- a/gns3server/agent/gns3_copilot/utils/custom_netmiko/vpcs_telnet.py +++ b/gns3server/agent/gns3_copilot/utils/custom_netmiko/vpcs_telnet.py @@ -47,7 +47,6 @@ import time from netmiko.base_connection import BaseConnection - logger = logging.getLogger(__name__) # ANSI escape code pattern for stripping terminal formatting codes diff --git a/gns3server/agent/gns3_copilot/utils/gns3_drawing_utils.py b/gns3server/agent/gns3_copilot/utils/gns3_drawing_utils.py index 4fa48ee7d..50456cbf5 100644 --- a/gns3server/agent/gns3_copilot/utils/gns3_drawing_utils.py +++ b/gns3server/agent/gns3_copilot/utils/gns3_drawing_utils.py @@ -31,8 +31,7 @@ Supports ellipse and rectangle shapes for two-node annotations. """ import math -from typing import Any -from typing import Literal +from typing import Any, Literal # Default parameters DEFAULT_DEVICE_WIDTH = 50 diff --git a/gns3server/agent/gns3_copilot/utils/llm_config_helper.py b/gns3server/agent/gns3_copilot/utils/llm_config_helper.py index f0118c9d2..57e6658ae 100644 --- a/gns3server/agent/gns3_copilot/utils/llm_config_helper.py +++ b/gns3server/agent/gns3_copilot/utils/llm_config_helper.py @@ -43,9 +43,7 @@ Usage: """ import logging -from typing import Any -from typing import Dict -from typing import Optional +from typing import Any, Dict, Optional from uuid import UUID from fastapi import FastAPI diff --git a/gns3server/agent/gns3_copilot/utils/message_converters.py b/gns3server/agent/gns3_copilot/utils/message_converters.py index 367b2d956..eb0d9a825 100644 --- a/gns3server/agent/gns3_copilot/utils/message_converters.py +++ b/gns3server/agent/gns3_copilot/utils/message_converters.py @@ -31,14 +31,9 @@ Converts between LangChain messages and OpenAI-compatible format. import json import uuid -from typing import Any -from typing import Dict +from typing import Any, Dict -from langchain_core.messages import AIMessage -from langchain_core.messages import HumanMessage -from langchain_core.messages import SystemMessage -from langchain_core.messages import ToolCall -from langchain_core.messages import ToolMessage +from langchain_core.messages import AIMessage, HumanMessage, SystemMessage, ToolCall, ToolMessage def _ensure_string(content: Any) -> str: diff --git a/gns3server/agent/mcp/__init__.py b/gns3server/agent/mcp/__init__.py index e89babc77..f55cdfc6e 100644 --- a/gns3server/agent/mcp/__init__.py +++ b/gns3server/agent/mcp/__init__.py @@ -26,54 +26,65 @@ Implements the standard MCP protocol over SSE transport using FastMCP: Tools are registered via @mcp.tool() decorators. """ +import asyncio import contextvars import json -import asyncio import logging import socket -from uuid import UUID -import bcrypt -from typing import Any, Annotated +from typing import Annotated, Any from urllib.parse import parse_qs +from uuid import UUID +import bcrypt from fastapi import APIRouter from fastapi.responses import Response - -from pydantic import Field - from mcp.server.fastmcp import FastMCP from mcp.server.transport_security import TransportSecuritySettings - +from pydantic import Field from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession -from gns3server.config import Config -from gns3server.services.authentication import AuthService import gns3server.db.models as models -from gns3server.services import auth_service -from gns3server.utils.request_utils import extract_client_info +from gns3server.agent.gns3_copilot.gns3_client.api_handlers import ( + available_filters_handler, + create_link_handler, + create_node_handler, + delete_link_handler, + delete_node_file_handler, + delete_node_handler, + download_capture_file_handler, + duplicate_node_handler, + get_link_handler, + get_links_handler, + get_node_console_info_handler, + get_node_file_handler, + get_node_handler, + get_node_links_handler, + get_nodes_handler, + isolate_node_handler, + link_marker_handler, + list_node_files_handler, + marker_definition_handler, + reset_link_handler, + start_all_nodes_handler, + start_capture_handler, + start_node_handler, + stop_all_nodes_handler, + stop_capture_handler, + stop_node_handler, + suspend_all_nodes_handler, + suspend_node_handler, + unisolate_node_handler, + update_link_handler, + update_node_handler, + write_node_file_handler, +) +from gns3server.config import Config from gns3server.db.repositories.api_keys import ApiKeysRepository from gns3server.db.repositories.users import UsersRepository -from .projects import ( - list_projects_handler, - get_project_handler, - create_project_handler, - delete_project_handler, - open_project_handler, - close_project_handler, - get_project_stats_handler, - update_project_handler, - duplicate_project_handler, - get_project_readme_handler, - update_project_readme_handler, - lock_project_handler, - unlock_project_handler, - get_locked_project_handler, -) -from .server import ( - get_version_handler, - get_statistics_handler, -) +from gns3server.services import auth_service +from gns3server.services.authentication import AuthService +from gns3server.utils.request_utils import extract_client_info # Symbol tools are disabled for now: they require a vision-capable model to # be genuinely useful (the tools shuttle SVG content, which a text-only LLM @@ -84,80 +95,66 @@ from .server import ( # upload_symbol_handler, delete_symbol_handler, # ) from .appliances import ( - get_appliances_handler, get_appliance_handler, + get_appliances_handler, install_appliance_handler, ) -from .images import ( - get_images_handler, - get_image_handler, - delete_image_handler, - prune_images_handler, - install_images_handler, +from .computes import ( + get_compute_handler, + get_compute_images_handler, + list_computes_handler, ) from .device_config import ( device_config_send_handler, device_show_run_handler, vpcs_config_set_handler, ) -from gns3server.agent.gns3_copilot.gns3_client.api_handlers import ( - get_nodes_handler, - get_node_handler, - start_node_handler, - stop_node_handler, - suspend_node_handler, - create_node_handler, - delete_node_handler, - update_node_handler, - get_node_console_info_handler, - list_node_files_handler, - get_node_file_handler, - write_node_file_handler, - delete_node_file_handler, - start_all_nodes_handler, - stop_all_nodes_handler, - suspend_all_nodes_handler, - duplicate_node_handler, - isolate_node_handler, - unisolate_node_handler, - get_node_links_handler, - get_links_handler, - get_link_handler, - available_filters_handler, - create_link_handler, - delete_link_handler, - update_link_handler, - reset_link_handler, - start_capture_handler, - stop_capture_handler, - download_capture_file_handler, - link_marker_handler, - marker_definition_handler, +from .drawings import ( + create_drawing_handler, + delete_drawing_handler, + get_drawing_handler, + get_drawings_handler, + update_drawing_handler, ) -from .templates import ( - list_templates_handler, - get_template_handler, - create_template_handler, - update_template_handler, - delete_template_handler, +from .images import ( + delete_image_handler, + get_image_handler, + get_images_handler, + install_images_handler, + prune_images_handler, ) -from .computes import ( - list_computes_handler, - get_compute_handler, - get_compute_images_handler, +from .projects import ( + close_project_handler, + create_project_handler, + delete_project_handler, + duplicate_project_handler, + get_locked_project_handler, + get_project_handler, + get_project_readme_handler, + get_project_stats_handler, + list_projects_handler, + lock_project_handler, + open_project_handler, + unlock_project_handler, + update_project_handler, + update_project_readme_handler, +) +from .server import ( + get_statistics_handler, + get_version_handler, ) from .snapshots import ( - get_snapshots_handler, create_snapshot_handler, delete_snapshot_handler, + get_snapshots_handler, restore_snapshot_handler, ) -from .drawings import ( - get_drawings_handler, - create_drawing_handler, - get_drawing_handler, - update_drawing_handler, - delete_drawing_handler, +from .templates import ( + create_template_handler, + delete_template_handler, + get_template_handler, + list_templates_handler, + update_template_handler, ) log = logging.getLogger(__name__) diff --git a/gns3server/agent/mcp/appliances.py b/gns3server/agent/mcp/appliances.py index 6e3a3ecf5..35084ea6a 100644 --- a/gns3server/agent/mcp/appliances.py +++ b/gns3server/agent/mcp/appliances.py @@ -19,9 +19,8 @@ MCP tool handlers for GNS3 appliance management. """ -from typing import Any - import logging +from typing import Any log = logging.getLogger(__name__) diff --git a/gns3server/agent/mcp/computes.py b/gns3server/agent/mcp/computes.py index 1f744066c..722ed15ce 100644 --- a/gns3server/agent/mcp/computes.py +++ b/gns3server/agent/mcp/computes.py @@ -19,8 +19,8 @@ MCP tool handlers for GNS3 compute management. """ -from typing import Any import logging +from typing import Any log = logging.getLogger(__name__) diff --git a/gns3server/agent/mcp/device_config.py b/gns3server/agent/mcp/device_config.py index 278295071..be7f04356 100644 --- a/gns3server/agent/mcp/device_config.py +++ b/gns3server/agent/mcp/device_config.py @@ -33,7 +33,8 @@ import json import logging from typing import Any -from jinja2 import Template as JinjaTemplate, TemplateError as JinjaError +from jinja2 import Template as JinjaTemplate +from jinja2 import TemplateError as JinjaError log = logging.getLogger(__name__) diff --git a/gns3server/agent/mcp/drawings.py b/gns3server/agent/mcp/drawings.py index a3ca146f6..7ca6daeda 100644 --- a/gns3server/agent/mcp/drawings.py +++ b/gns3server/agent/mcp/drawings.py @@ -19,9 +19,8 @@ MCP tool handlers for GNS3 drawing management. """ -from typing import Any - import logging +from typing import Any log = logging.getLogger(__name__) diff --git a/gns3server/agent/mcp/images.py b/gns3server/agent/mcp/images.py index d2b7ed958..7d20bc2fa 100644 --- a/gns3server/agent/mcp/images.py +++ b/gns3server/agent/mcp/images.py @@ -19,9 +19,8 @@ MCP tool handlers for GNS3 image management. """ -from typing import Any - import logging +from typing import Any log = logging.getLogger(__name__) diff --git a/gns3server/agent/mcp/projects.py b/gns3server/agent/mcp/projects.py index ff6b5125c..57b9c01d3 100644 --- a/gns3server/agent/mcp/projects.py +++ b/gns3server/agent/mcp/projects.py @@ -22,9 +22,8 @@ Tool handlers receive (params, gns3_ctx) and call GNS3's REST API via Gns3Connector (from gns3_copilot.gns3_client.connector). """ -from typing import Any - import logging +from typing import Any log = logging.getLogger(__name__) diff --git a/gns3server/agent/mcp/server.py b/gns3server/agent/mcp/server.py index fe5c21dc3..0585a8566 100644 --- a/gns3server/agent/mcp/server.py +++ b/gns3server/agent/mcp/server.py @@ -19,9 +19,8 @@ MCP tool handlers for GNS3 server information. """ -from typing import Any - import logging +from typing import Any log = logging.getLogger(__name__) diff --git a/gns3server/agent/mcp/snapshots.py b/gns3server/agent/mcp/snapshots.py index 336c7a3e0..9f741a91e 100644 --- a/gns3server/agent/mcp/snapshots.py +++ b/gns3server/agent/mcp/snapshots.py @@ -19,9 +19,8 @@ MCP tool handlers for GNS3 snapshot management. """ -from typing import Any - import logging +from typing import Any log = logging.getLogger(__name__) diff --git a/gns3server/agent/mcp/symbols.py b/gns3server/agent/mcp/symbols.py index d363e042c..30f8f7d71 100644 --- a/gns3server/agent/mcp/symbols.py +++ b/gns3server/agent/mcp/symbols.py @@ -19,9 +19,8 @@ MCP tool handlers for GNS3 symbol management. """ -from typing import Any - import logging +from typing import Any from gns3server.services import access_ticket_service diff --git a/gns3server/agent/mcp/templates.py b/gns3server/agent/mcp/templates.py index 56e02680a..2a6130c78 100644 --- a/gns3server/agent/mcp/templates.py +++ b/gns3server/agent/mcp/templates.py @@ -22,9 +22,8 @@ Handlers receive (params, gns3_ctx) and call GNS3's REST API via Gns3Connector (from gns3_copilot.gns3_client.connector). """ -from typing import Any - import logging +from typing import Any log = logging.getLogger(__name__) diff --git a/gns3server/agent/web_wireshark/manage_wireshark.py b/gns3server/agent/web_wireshark/manage_wireshark.py index 5203a98d9..02445f477 100755 --- a/gns3server/agent/web_wireshark/manage_wireshark.py +++ b/gns3server/agent/web_wireshark/manage_wireshark.py @@ -67,12 +67,12 @@ For more information on each command, use: python manage_wireshark.py --help """ -import sys -import json import argparse -import logging import asyncio +import json +import logging import os +import sys from typing import Optional from gns3server.utils.uuid_validator import validate_uuid diff --git a/gns3server/agent/web_wireshark/manager.py b/gns3server/agent/web_wireshark/manager.py index 16f057d75..0791c0668 100644 --- a/gns3server/agent/web_wireshark/manager.py +++ b/gns3server/agent/web_wireshark/manager.py @@ -30,6 +30,7 @@ from urllib.parse import urlparse from gns3server.config import Config from gns3server.utils.port_allocator import link_id_to_display, link_id_to_port + from .docker_client import DockerHTTPClient logger = logging.getLogger(__name__) diff --git a/gns3server/agent/web_wireshark/setup_wireshark_image.py b/gns3server/agent/web_wireshark/setup_wireshark_image.py index 92949a923..01159fee3 100644 --- a/gns3server/agent/web_wireshark/setup_wireshark_image.py +++ b/gns3server/agent/web_wireshark/setup_wireshark_image.py @@ -23,12 +23,11 @@ This script pulls or builds the gns3/web-wireshark Docker image. Run with: pip install gns3server && gns3server-web-wireshark-setup """ +import argparse import os -import sys import shutil import subprocess -import argparse - +import sys DOCKER_IMAGE = "gns3/web-wireshark:latest" DOCKERFILE_NAME = "Dockerfile" diff --git a/gns3server/api/routes/compute/__init__.py b/gns3server/api/routes/compute/__init__.py index 7606e6ddf..934243922 100644 --- a/gns3server/api/routes/compute/__init__.py +++ b/gns3server/api/routes/compute/__init__.py @@ -15,43 +15,44 @@ # along with this program. If not, see . -from fastapi import FastAPI, Request, Depends +import logging + +from fastapi import Depends, FastAPI, Request from fastapi.responses import JSONResponse from starlette.exceptions import HTTPException as StarletteHTTPException -from gns3server.controller.gns3vm.gns3_vm_error import GNS3VMError -from gns3server.compute.error import ImageMissingError, NodeError -from gns3server.compute.ubridge.ubridge_error import UbridgeError - -from .dependencies.authentication import compute_authentication from gns3server.compute.compute_error import ( ComputeError, + ComputeForbiddenError, ComputeNotFoundError, ComputeTimeoutError, - ComputeForbiddenError, ComputeUnauthorizedError, ) +from gns3server.compute.error import ImageMissingError, NodeError +from gns3server.compute.ubridge.ubridge_error import UbridgeError +from gns3server.controller.gns3vm.gns3_vm_error import GNS3VMError -from . import capabilities -from . import compute -from . import projects -from . import notifications -from . import images -from . import atm_switch_nodes -from . import cloud_nodes -from . import docker_nodes -from . import dynamips_nodes -from . import ethernet_hub_nodes -from . import ethernet_switch_nodes -from . import frame_relay_switch_nodes -from . import iou_nodes -from . import nat_nodes -from . import qemu_nodes -from . import virtualbox_nodes -from . import vmware_nodes -from . import vpcs_nodes - -import logging +from . import ( + atm_switch_nodes, + capabilities, + cloud_nodes, + compute, + docker_nodes, + dynamips_nodes, + ethernet_hub_nodes, + ethernet_switch_nodes, + frame_relay_switch_nodes, + images, + iou_nodes, + nat_nodes, + notifications, + projects, + qemu_nodes, + virtualbox_nodes, + vmware_nodes, + vpcs_nodes, +) +from .dependencies.authentication import compute_authentication log = logging.getLogger(__name__) diff --git a/gns3server/api/routes/compute/atm_switch_nodes.py b/gns3server/api/routes/compute/atm_switch_nodes.py index 1282a162d..e62a54eb1 100644 --- a/gns3server/api/routes/compute/atm_switch_nodes.py +++ b/gns3server/api/routes/compute/atm_switch_nodes.py @@ -18,13 +18,13 @@ API routes for ATM switch nodes. """ -from typing import Any import os +from typing import Any +from uuid import UUID -from fastapi import APIRouter, Depends, Body, Path, status, HTTPException +from fastapi import APIRouter, Body, Depends, HTTPException, Path, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse -from uuid import UUID from gns3server import schemas from gns3server.compute.dynamips import Dynamips diff --git a/gns3server/api/routes/compute/capabilities.py b/gns3server/api/routes/compute/capabilities.py index 42154d4e1..363b2906b 100644 --- a/gns3server/api/routes/compute/capabilities.py +++ b/gns3server/api/routes/compute/capabilities.py @@ -19,14 +19,14 @@ API routes for capabilities """ import sys -import psutil +import psutil from fastapi import APIRouter, Request -from gns3server.version import __version__ +from gns3server import schemas from gns3server.compute import MODULES from gns3server.utils.path import get_default_project_directory -from gns3server import schemas +from gns3server.version import __version__ router = APIRouter() diff --git a/gns3server/api/routes/compute/cloud_nodes.py b/gns3server/api/routes/compute/cloud_nodes.py index d0a4ead9e..53b4ed432 100644 --- a/gns3server/api/routes/compute/cloud_nodes.py +++ b/gns3server/api/routes/compute/cloud_nodes.py @@ -19,13 +19,13 @@ API routes for cloud nodes. """ import os - -from fastapi import APIRouter, Depends, Path, status, HTTPException -from fastapi.encoders import jsonable_encoder -from fastapi.responses import StreamingResponse from typing import Any, Union from uuid import UUID +from fastapi import APIRouter, Depends, HTTPException, Path, status +from fastapi.encoders import jsonable_encoder +from fastapi.responses import StreamingResponse + from gns3server import schemas from gns3server.compute.builtin import Builtin from gns3server.compute.builtin.nodes.cloud import Cloud diff --git a/gns3server/api/routes/compute/compute.py b/gns3server/api/routes/compute/compute.py index c98b1a256..cd750edb9 100644 --- a/gns3server/api/routes/compute/compute.py +++ b/gns3server/api/routes/compute/compute.py @@ -20,26 +20,26 @@ API routes for compute. """ import os -import psutil -import cpuinfo - from functools import lru_cache -from gns3server.config import Config -from gns3server.utils.cpu_percent import CpuPercent -from gns3server.version import __version__ -from gns3server.utils.path import get_default_project_directory, is_safe_path +from typing import List, Optional +from uuid import UUID + +import cpuinfo +import psutil +from fastapi import APIRouter, Body, HTTPException, Response, status +from fastapi.encoders import jsonable_encoder + +from gns3server import schemas from gns3server.compute.port_manager import PortManager from gns3server.compute.project_manager import ProjectManager -from gns3server.utils.interfaces import interfaces from gns3server.compute.qemu import Qemu from gns3server.compute.virtualbox import VirtualBox from gns3server.compute.vmware import VMware -from gns3server import schemas - -from fastapi import APIRouter, HTTPException, Body, Response, status -from fastapi.encoders import jsonable_encoder -from uuid import UUID -from typing import Optional, List +from gns3server.config import Config +from gns3server.utils.cpu_percent import CpuPercent +from gns3server.utils.interfaces import interfaces +from gns3server.utils.path import get_default_project_directory, is_safe_path +from gns3server.version import __version__ router = APIRouter() diff --git a/gns3server/api/routes/compute/dependencies/authentication.py b/gns3server/api/routes/compute/dependencies/authentication.py index 0412a4136..db5a3f0d0 100644 --- a/gns3server/api/routes/compute/dependencies/authentication.py +++ b/gns3server/api/routes/compute/dependencies/authentication.py @@ -14,16 +14,17 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import secrets import base64 import binascii import logging +import secrets +from typing import Optional, Union from fastapi import Depends, HTTPException, WebSocket, status from fastapi.security import HTTPBasic, HTTPBasicCredentials from fastapi.security.utils import get_authorization_scheme_param + from gns3server.config import Config -from typing import Optional, Union log = logging.getLogger(__name__) security = HTTPBasic(auto_error=False) diff --git a/gns3server/api/routes/compute/docker_nodes.py b/gns3server/api/routes/compute/docker_nodes.py index 9dee90dda..37c00d5a3 100644 --- a/gns3server/api/routes/compute/docker_nodes.py +++ b/gns3server/api/routes/compute/docker_nodes.py @@ -19,16 +19,17 @@ API routes for Docker nodes. """ import os +from typing import Any, Union +from uuid import UUID -from fastapi import APIRouter, WebSocket, Depends, Body, status, HTTPException +from fastapi import APIRouter, Body, Depends, HTTPException, WebSocket, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse -from uuid import UUID -from typing import Any, Union from gns3server import schemas from gns3server.compute.docker import Docker from gns3server.compute.docker.docker_vm import DockerVM + from .dependencies.authentication import compute_authentication, ws_compute_authentication responses: dict[int | str, dict[str, Any]] = { diff --git a/gns3server/api/routes/compute/dynamips_nodes.py b/gns3server/api/routes/compute/dynamips_nodes.py index ccfcd58fb..99c1b53cd 100644 --- a/gns3server/api/routes/compute/dynamips_nodes.py +++ b/gns3server/api/routes/compute/dynamips_nodes.py @@ -19,16 +19,16 @@ API routes for Dynamips nodes. """ import os - -from fastapi import APIRouter, WebSocket, Body, Depends, status, HTTPException -from fastapi.encoders import jsonable_encoder -from fastapi.responses import StreamingResponse from typing import Any, List, Optional, Union from uuid import UUID +from fastapi import APIRouter, Body, Depends, HTTPException, WebSocket, status +from fastapi.encoders import jsonable_encoder +from fastapi.responses import StreamingResponse + +from gns3server import schemas from gns3server.compute.dynamips import Dynamips from gns3server.compute.dynamips.nodes.router import Router -from gns3server import schemas from .dependencies.authentication import compute_authentication, ws_compute_authentication diff --git a/gns3server/api/routes/compute/ethernet_hub_nodes.py b/gns3server/api/routes/compute/ethernet_hub_nodes.py index 150d18e64..05985100c 100644 --- a/gns3server/api/routes/compute/ethernet_hub_nodes.py +++ b/gns3server/api/routes/compute/ethernet_hub_nodes.py @@ -18,17 +18,17 @@ API routes for Ethernet hub nodes. """ -from typing import Any import os - -from fastapi import APIRouter, Depends, Body, Path, status, HTTPException -from fastapi.encoders import jsonable_encoder -from fastapi.responses import StreamingResponse +from typing import Any from uuid import UUID +from fastapi import APIRouter, Body, Depends, HTTPException, Path, status +from fastapi.encoders import jsonable_encoder +from fastapi.responses import StreamingResponse + +from gns3server import schemas from gns3server.compute.dynamips import Dynamips from gns3server.compute.dynamips.nodes.ethernet_hub import EthernetHub -from gns3server import schemas responses: dict[int | str, dict[str, Any]] = { 404: {"model": schemas.ErrorMessage, "description": "Could not find project or Ethernet hub node"} diff --git a/gns3server/api/routes/compute/ethernet_switch_nodes.py b/gns3server/api/routes/compute/ethernet_switch_nodes.py index 9c7736e9c..e6e13e94d 100644 --- a/gns3server/api/routes/compute/ethernet_switch_nodes.py +++ b/gns3server/api/routes/compute/ethernet_switch_nodes.py @@ -22,17 +22,17 @@ through uBridge's ``brctl`` module (see ``gns3server.compute.builtin.nodes.ethernet_switch``). """ -from typing import Any import os - -from fastapi import APIRouter, Depends, Body, Path, status, HTTPException -from fastapi.encoders import jsonable_encoder -from fastapi.responses import StreamingResponse +from typing import Any from uuid import UUID +from fastapi import APIRouter, Body, Depends, HTTPException, Path, status +from fastapi.encoders import jsonable_encoder +from fastapi.responses import StreamingResponse + +from gns3server import schemas from gns3server.compute.builtin import Builtin from gns3server.compute.builtin.nodes.ethernet_switch import EthernetSwitch -from gns3server import schemas responses: dict[int | str, dict[str, Any]] = { 404: {"model": schemas.ErrorMessage, "description": "Could not find project or Ethernet switch node"} diff --git a/gns3server/api/routes/compute/frame_relay_switch_nodes.py b/gns3server/api/routes/compute/frame_relay_switch_nodes.py index bd8bb1f18..0c298f8b9 100644 --- a/gns3server/api/routes/compute/frame_relay_switch_nodes.py +++ b/gns3server/api/routes/compute/frame_relay_switch_nodes.py @@ -18,13 +18,13 @@ API routes for Frame Relay switch nodes. """ -from typing import Any import os +from typing import Any +from uuid import UUID -from fastapi import APIRouter, Depends, Body, Path, status, HTTPException +from fastapi import APIRouter, Body, Depends, HTTPException, Path, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse -from uuid import UUID from gns3server import schemas from gns3server.compute.dynamips import Dynamips diff --git a/gns3server/api/routes/compute/images.py b/gns3server/api/routes/compute/images.py index fd49974a1..966063cc8 100644 --- a/gns3server/api/routes/compute/images.py +++ b/gns3server/api/routes/compute/images.py @@ -20,11 +20,11 @@ API routes for images. import os import urllib.parse - -from fastapi import APIRouter, Body, Request, status, Response, HTTPException -from fastapi.responses import FileResponse from typing import List +from fastapi import APIRouter, Body, HTTPException, Request, Response, status +from fastapi.responses import FileResponse + from gns3server.compute.docker import Docker from gns3server.compute.dynamips import Dynamips from gns3server.compute.iou import IOU diff --git a/gns3server/api/routes/compute/iou_nodes.py b/gns3server/api/routes/compute/iou_nodes.py index 5285c07b5..50600a734 100644 --- a/gns3server/api/routes/compute/iou_nodes.py +++ b/gns3server/api/routes/compute/iou_nodes.py @@ -19,13 +19,13 @@ API routes for IOU nodes. """ import os - -from fastapi import APIRouter, WebSocket, Depends, Body, status, HTTPException -from fastapi.encoders import jsonable_encoder -from fastapi.responses import StreamingResponse from typing import Any, Union from uuid import UUID +from fastapi import APIRouter, Body, Depends, HTTPException, WebSocket, status +from fastapi.encoders import jsonable_encoder +from fastapi.responses import StreamingResponse + from gns3server import schemas from gns3server.compute.iou import IOU from gns3server.compute.iou.iou_vm import IOUVM diff --git a/gns3server/api/routes/compute/nat_nodes.py b/gns3server/api/routes/compute/nat_nodes.py index 37d8b4401..43d1e33d5 100644 --- a/gns3server/api/routes/compute/nat_nodes.py +++ b/gns3server/api/routes/compute/nat_nodes.py @@ -19,13 +19,13 @@ API routes for NAT nodes. """ import os - -from fastapi import APIRouter, Depends, Path, status, HTTPException -from fastapi.encoders import jsonable_encoder -from fastapi.responses import StreamingResponse from typing import Any, Union from uuid import UUID +from fastapi import APIRouter, Depends, HTTPException, Path, status +from fastapi.encoders import jsonable_encoder +from fastapi.responses import StreamingResponse + from gns3server import schemas from gns3server.compute.builtin import Builtin from gns3server.compute.builtin.nodes.nat import Nat diff --git a/gns3server/api/routes/compute/notifications.py b/gns3server/api/routes/compute/notifications.py index 66de26675..24f8ee059 100644 --- a/gns3server/api/routes/compute/notifications.py +++ b/gns3server/api/routes/compute/notifications.py @@ -18,14 +18,15 @@ API routes for compute notifications. """ -from fastapi import APIRouter, Depends, WebSocket, WebSocketDisconnect +import logging from typing import Union + +from fastapi import APIRouter, Depends, WebSocket, WebSocketDisconnect from websockets.exceptions import ConnectionClosed, WebSocketException from gns3server.compute.notification_manager import NotificationManager -from .dependencies.authentication import ws_compute_authentication -import logging +from .dependencies.authentication import ws_compute_authentication log = logging.getLogger(__name__) diff --git a/gns3server/api/routes/compute/projects.py b/gns3server/api/routes/compute/projects.py index 729510055..0ab1caa1f 100644 --- a/gns3server/api/routes/compute/projects.py +++ b/gns3server/api/routes/compute/projects.py @@ -18,28 +18,27 @@ API routes for projects. """ +import asyncio +import inspect +import logging import os import shutil import urllib.parse -import inspect -import asyncio - -import logging log = logging.getLogger() -from fastapi import APIRouter, Depends, HTTPException, Request, Response, status, Query -from fastapi.encoders import jsonable_encoder -from fastapi.responses import FileResponse from typing import List from uuid import UUID -from gns3server.compute.project_manager import ProjectManager -from gns3server.compute.project import Project -from gns3server.compute.base_manager import BaseManager -from gns3server.utils.path import is_safe_path -from gns3server import schemas +from fastapi import APIRouter, Depends, HTTPException, Query, Request, Response, status +from fastapi.encoders import jsonable_encoder +from fastapi.responses import FileResponse +from gns3server import schemas +from gns3server.compute.base_manager import BaseManager +from gns3server.compute.project import Project +from gns3server.compute.project_manager import ProjectManager +from gns3server.utils.path import is_safe_path router = APIRouter() diff --git a/gns3server/api/routes/compute/qemu_nodes.py b/gns3server/api/routes/compute/qemu_nodes.py index 6f1794fb9..1f5574654 100644 --- a/gns3server/api/routes/compute/qemu_nodes.py +++ b/gns3server/api/routes/compute/qemu_nodes.py @@ -18,21 +18,21 @@ API routes for Qemu nodes. """ +import logging import os - -from fastapi import APIRouter, WebSocket, Depends, Body, Path, status, HTTPException -from fastapi.encoders import jsonable_encoder -from fastapi.responses import StreamingResponse from typing import Any, Union from uuid import UUID +from fastapi import APIRouter, Body, Depends, HTTPException, Path, WebSocket, status +from fastapi.encoders import jsonable_encoder +from fastapi.responses import StreamingResponse + from gns3server import schemas from gns3server.compute import qemu from gns3server.compute.qemu import Qemu from gns3server.compute.qemu.qemu_vm import QemuVM -from .dependencies.authentication import compute_authentication, ws_compute_authentication -import logging +from .dependencies.authentication import compute_authentication, ws_compute_authentication log = logging.getLogger(__name__) diff --git a/gns3server/api/routes/compute/virtualbox_nodes.py b/gns3server/api/routes/compute/virtualbox_nodes.py index 9f137d066..49e7f7316 100644 --- a/gns3server/api/routes/compute/virtualbox_nodes.py +++ b/gns3server/api/routes/compute/virtualbox_nodes.py @@ -19,12 +19,12 @@ API routes for VirtualBox nodes. """ import os +from typing import Any, Union +from uuid import UUID -from fastapi import APIRouter, WebSocket, Depends, Path, status +from fastapi import APIRouter, Depends, Path, WebSocket, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse -from uuid import UUID -from typing import Any, Union from gns3server import schemas from gns3server.compute.virtualbox import VirtualBox diff --git a/gns3server/api/routes/compute/vmware_nodes.py b/gns3server/api/routes/compute/vmware_nodes.py index 61849da30..ffb476215 100644 --- a/gns3server/api/routes/compute/vmware_nodes.py +++ b/gns3server/api/routes/compute/vmware_nodes.py @@ -19,12 +19,12 @@ API routes for VMware nodes. """ import os +from typing import Any, Union +from uuid import UUID -from fastapi import APIRouter, WebSocket, Depends, Path, status +from fastapi import APIRouter, Depends, Path, WebSocket, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse -from uuid import UUID -from typing import Any, Union from gns3server import schemas from gns3server.compute.vmware import VMware diff --git a/gns3server/api/routes/compute/vpcs_nodes.py b/gns3server/api/routes/compute/vpcs_nodes.py index a9f96bdc5..255ce33f6 100644 --- a/gns3server/api/routes/compute/vpcs_nodes.py +++ b/gns3server/api/routes/compute/vpcs_nodes.py @@ -19,16 +19,17 @@ API routes for VPCS nodes. """ import os - -from fastapi import APIRouter, WebSocket, Depends, Body, Path, status, HTTPException -from fastapi.encoders import jsonable_encoder -from fastapi.responses import StreamingResponse from typing import Any, Union from uuid import UUID +from fastapi import APIRouter, Body, Depends, HTTPException, Path, WebSocket, status +from fastapi.encoders import jsonable_encoder +from fastapi.responses import StreamingResponse + from gns3server import schemas from gns3server.compute.vpcs import VPCS from gns3server.compute.vpcs.vpcs_vm import VPCSVM + from .dependencies.authentication import compute_authentication, ws_compute_authentication responses: dict[int | str, dict[str, Any]] = { diff --git a/gns3server/api/routes/controller/__init__.py b/gns3server/api/routes/controller/__init__.py index 9236e17c0..e22d3d507 100644 --- a/gns3server/api/routes/controller/__init__.py +++ b/gns3server/api/routes/controller/__init__.py @@ -21,9 +21,7 @@ from gns3server.agent import AI_COPILOT_AVAILABLE # Conditionally import AI-dependent routes if AI_COPILOT_AVAILABLE: - from . import chat - from . import copilot - from . import llm_model_configs + from . import chat, copilot, llm_model_configs _chat_router = chat.router _copilot_router = copilot.router @@ -44,28 +42,29 @@ else: ) -from . import controller -from . import appliances -from . import computes -from . import drawings -from . import gns3vm -from . import links -from . import nodes -from . import projects -from . import snapshots -from . import symbols -from . import templates -from . import images -from . import users -from . import groups -from . import roles -from . import acl -from . import pools -from . import privileges -from . import api_keys -from . import netmiko -from . import settings - +from . import ( + acl, + api_keys, + appliances, + computes, + controller, + drawings, + gns3vm, + groups, + images, + links, + netmiko, + nodes, + pools, + privileges, + projects, + roles, + settings, + snapshots, + symbols, + templates, + users, +) from .dependencies.authentication import get_current_active_user router = APIRouter() diff --git a/gns3server/api/routes/controller/acl.py b/gns3server/api/routes/controller/acl.py index ccc6b7a1d..7febf226b 100644 --- a/gns3server/api/routes/controller/acl.py +++ b/gns3server/api/routes/controller/acl.py @@ -19,29 +19,27 @@ API routes for ACL. """ +import logging import re +from typing import Iterator, List, Optional, Sequence +from uuid import UUID from fastapi import APIRouter, Depends, Request, status from fastapi.routing import APIRoute, _IncludedRouter from starlette.routing import BaseRoute, Mount -from uuid import UUID -from typing import Iterator, List, Optional, Sequence - -from gns3server import schemas -from gns3server.controller.controller_error import ControllerBadRequestError, ControllerNotFoundError - -from gns3server.controller import Controller import gns3server.db.models as models -from gns3server.db.repositories.users import UsersRepository -from gns3server.db.repositories.rbac import RbacRepository +from gns3server import schemas +from gns3server.controller import Controller +from gns3server.controller.controller_error import ControllerBadRequestError, ControllerNotFoundError from gns3server.db.repositories.images import ImagesRepository +from gns3server.db.repositories.rbac import RbacRepository from gns3server.db.repositories.templates import TemplatesRepository +from gns3server.db.repositories.users import UsersRepository + from .dependencies.database import get_repository from .dependencies.rbac import has_privilege -import logging - log = logging.getLogger(__name__) router = APIRouter() diff --git a/gns3server/api/routes/controller/api_keys.py b/gns3server/api/routes/controller/api_keys.py index a3bfa4b14..42f1d66c2 100644 --- a/gns3server/api/routes/controller/api_keys.py +++ b/gns3server/api/routes/controller/api_keys.py @@ -18,18 +18,18 @@ API routes for API key management. """ +import logging import secrets -import bcrypt -from uuid import uuid4, UUID +from uuid import UUID, uuid4 -from fastapi import APIRouter, Depends, status, HTTPException +import bcrypt +from fastapi import APIRouter, Depends, HTTPException, status from gns3server import schemas from gns3server.db.repositories.api_keys import ApiKeysRepository -from .dependencies.database import get_repository -from .dependencies.authentication import get_current_active_user -import logging +from .dependencies.authentication import get_current_active_user +from .dependencies.database import get_repository log = logging.getLogger(__name__) diff --git a/gns3server/api/routes/controller/appliances.py b/gns3server/api/routes/controller/appliances.py index 46c187940..ad8645554 100644 --- a/gns3server/api/routes/controller/appliances.py +++ b/gns3server/api/routes/controller/appliances.py @@ -19,24 +19,22 @@ API routes for appliances. """ import logging +from typing import List, Optional, Union +from uuid import UUID from fastapi import APIRouter, Depends, status -from typing import Optional, List, Union -from uuid import UUID from gns3server import schemas from gns3server.controller import Controller -from gns3server.controller.controller_error import ControllerError, ControllerBadRequestError, ControllerNotFoundError - +from gns3server.controller.controller_error import ControllerBadRequestError, ControllerError, ControllerNotFoundError from gns3server.db.repositories.images import ImagesRepository -from gns3server.db.repositories.templates import TemplatesRepository from gns3server.db.repositories.rbac import RbacRepository +from gns3server.db.repositories.templates import TemplatesRepository from .dependencies.authentication import get_current_active_user from .dependencies.database import get_repository from .dependencies.rbac import has_privilege - log = logging.getLogger(__name__) router = APIRouter() diff --git a/gns3server/api/routes/controller/chat.py b/gns3server/api/routes/controller/chat.py index e55e722f7..3573b5e1e 100644 --- a/gns3server/api/routes/controller/chat.py +++ b/gns3server/api/routes/controller/chat.py @@ -24,16 +24,16 @@ import json import logging import uuid from typing import Any, List, Optional +from uuid import UUID from fastapi import APIRouter, Depends, HTTPException, Request, status from fastapi.responses import StreamingResponse -from uuid import UUID from gns3server import schemas -from gns3server.controller import Controller -from gns3server.controller.project import Project -from gns3server.controller.controller_error import ControllerNotFoundError from gns3server.agent.gns3_copilot.project_agent_manager import get_project_agent_manager +from gns3server.controller import Controller +from gns3server.controller.controller_error import ControllerNotFoundError +from gns3server.controller.project import Project from gns3server.db.tasks import get_user_llm_config_full from .dependencies.authentication import get_current_active_user diff --git a/gns3server/api/routes/controller/computes.py b/gns3server/api/routes/controller/computes.py index c62c859ac..6dbaa30cd 100644 --- a/gns3server/api/routes/controller/computes.py +++ b/gns3server/api/routes/controller/computes.py @@ -18,16 +18,17 @@ API routes for computes. """ -from fastapi import APIRouter, Body, Depends, status -from typing import Any, List, Union, Optional +from typing import Any, List, Optional, Union from uuid import UUID -from gns3server.controller import Controller +from fastapi import APIRouter, Body, Depends, status + import gns3server.db.models as models +from gns3server import schemas +from gns3server.controller import Controller from gns3server.db.repositories.computes import ComputesRepository from gns3server.db.repositories.rbac import RbacRepository from gns3server.services.computes import ComputesService -from gns3server import schemas from .dependencies.database import get_repository from .dependencies.rbac import has_privilege diff --git a/gns3server/api/routes/controller/controller.py b/gns3server/api/routes/controller/controller.py index bd6502135..25999bdd9 100644 --- a/gns3server/api/routes/controller/controller.py +++ b/gns3server/api/routes/controller/controller.py @@ -15,30 +15,28 @@ # along with this program. If not, see . import asyncio -import signal +import logging import os +import signal import time -import psutil +from typing import Dict, List -from fastapi import APIRouter, FastAPI, Request, Depends, WebSocket, WebSocketDisconnect, status -from fastapi.responses import StreamingResponse +import psutil +from fastapi import APIRouter, Depends, FastAPI, Request, WebSocket, WebSocketDisconnect, status from fastapi.encoders import jsonable_encoder +from fastapi.responses import StreamingResponse from fastapi.routing import Mount from websockets.exceptions import ConnectionClosed, WebSocketException -from typing import List, Dict - +from gns3server import schemas +from gns3server.agent.web_wireshark.stats import collect_webwireshark_stats from gns3server.config import Config from gns3server.controller import Controller -from gns3server.agent.web_wireshark.stats import collect_webwireshark_stats -from gns3server.version import __version__ from gns3server.controller.controller_error import ControllerError, ControllerForbiddenError -from gns3server import schemas +from gns3server.version import __version__ from .dependencies.authentication import get_current_active_user, get_current_active_user_from_websocket -import logging - log = logging.getLogger(__name__) router = APIRouter() diff --git a/gns3server/api/routes/controller/copilot.py b/gns3server/api/routes/controller/copilot.py index 050792392..489d96cb3 100644 --- a/gns3server/api/routes/controller/copilot.py +++ b/gns3server/api/routes/controller/copilot.py @@ -21,7 +21,9 @@ API routes for GNS3 Copilot global operations (non-project). import logging from fastapi import APIRouter, Depends, HTTPException, status + from gns3server import schemas + from .dependencies.authentication import get_current_active_user log = logging.getLogger(__name__) diff --git a/gns3server/api/routes/controller/dependencies/authentication.py b/gns3server/api/routes/controller/dependencies/authentication.py index 1517e0572..b5689ade8 100644 --- a/gns3server/api/routes/controller/dependencies/authentication.py +++ b/gns3server/api/routes/controller/dependencies/authentication.py @@ -17,21 +17,22 @@ import asyncio import hashlib import logging -import bcrypt - -from fastapi import Request, Query, Depends, HTTPException, WebSocket, status -from fastapi.security import OAuth2PasswordBearer from typing import Optional from uuid import UUID -from gns3server import schemas +import bcrypt +from fastapi import Depends, HTTPException, Query, Request, WebSocket, status +from fastapi.security import OAuth2PasswordBearer + import gns3server.db.models as models +from gns3server import schemas from gns3server.db.repositories.api_keys import ApiKeysRepository -from gns3server.db.repositories.users import UsersRepository from gns3server.db.repositories.rbac import RbacRepository +from gns3server.db.repositories.users import UsersRepository from gns3server.schemas.controller.tokens import TokenData -from gns3server.services import auth_service, access_ticket_service +from gns3server.services import access_ticket_service, auth_service from gns3server.services.access_tickets import TICKET_PREFIX + from .database import get_repository log = logging.getLogger(__name__) diff --git a/gns3server/api/routes/controller/dependencies/database.py b/gns3server/api/routes/controller/dependencies/database.py index 86375507d..e9a3001ea 100644 --- a/gns3server/api/routes/controller/dependencies/database.py +++ b/gns3server/api/routes/controller/dependencies/database.py @@ -15,9 +15,10 @@ # along with this program. If not, see . from typing import AsyncGenerator, Callable, Type + from fastapi import Depends -from starlette.requests import HTTPConnection from sqlalchemy.ext.asyncio import AsyncSession +from starlette.requests import HTTPConnection from gns3server.db.repositories.base import BaseRepository diff --git a/gns3server/api/routes/controller/dependencies/rbac.py b/gns3server/api/routes/controller/dependencies/rbac.py index 995055e1d..447e6b0b6 100644 --- a/gns3server/api/routes/controller/dependencies/rbac.py +++ b/gns3server/api/routes/controller/dependencies/rbac.py @@ -14,16 +14,17 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging import re -from fastapi import Request, WebSocket, Depends, HTTPException +from fastapi import Depends, HTTPException, Request, WebSocket + from gns3server import schemas from gns3server.db.repositories.rbac import RbacRepository + from .authentication import get_current_active_user, get_current_active_user_from_websocket from .database import get_repository -import logging - log = logging.getLogger() diff --git a/gns3server/api/routes/controller/drawings.py b/gns3server/api/routes/controller/drawings.py index 6df9ddd91..6b9cb3553 100644 --- a/gns3server/api/routes/controller/drawings.py +++ b/gns3server/api/routes/controller/drawings.py @@ -18,14 +18,15 @@ API routes for drawings. """ -from fastapi import APIRouter, Depends, status -from fastapi.encoders import jsonable_encoder from typing import Any, List from uuid import UUID +from fastapi import APIRouter, Depends, status +from fastapi.encoders import jsonable_encoder + +from gns3server import schemas from gns3server.controller import Controller from gns3server.db.repositories.rbac import RbacRepository -from gns3server import schemas from .dependencies.database import get_repository from .dependencies.rbac import has_privilege diff --git a/gns3server/api/routes/controller/gns3vm.py b/gns3server/api/routes/controller/gns3vm.py index d019189bd..e0ae90eba 100644 --- a/gns3server/api/routes/controller/gns3vm.py +++ b/gns3server/api/routes/controller/gns3vm.py @@ -19,12 +19,13 @@ 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 fastapi import APIRouter +from fastapi.encoders import jsonable_encoder + from gns3server import schemas +from gns3server.controller import Controller router = APIRouter() diff --git a/gns3server/api/routes/controller/groups.py b/gns3server/api/routes/controller/groups.py index 1b5de02d2..4022a6053 100644 --- a/gns3server/api/routes/controller/groups.py +++ b/gns3server/api/routes/controller/groups.py @@ -19,26 +19,25 @@ API routes for user groups. """ -from fastapi import APIRouter, Depends, status -from uuid import UUID +import logging from typing import List, Optional +from uuid import UUID -from gns3server import schemas -from gns3server.controller.controller_error import ( - ControllerError, - ControllerBadRequestError, - ControllerNotFoundError, - ControllerForbiddenError, -) +from fastapi import APIRouter, Depends, status import gns3server.db.models as models -from gns3server.db.repositories.users import UsersRepository +from gns3server import schemas +from gns3server.controller.controller_error import ( + ControllerBadRequestError, + ControllerError, + ControllerForbiddenError, + ControllerNotFoundError, +) from gns3server.db.repositories.rbac import RbacRepository +from gns3server.db.repositories.users import UsersRepository -from .dependencies.rbac import has_privilege from .dependencies.database import get_repository - -import logging +from .dependencies.rbac import has_privilege log = logging.getLogger(__name__) diff --git a/gns3server/api/routes/controller/images.py b/gns3server/api/routes/controller/images.py index 0496e29ee..981774419 100644 --- a/gns3server/api/routes/controller/images.py +++ b/gns3server/api/routes/controller/images.py @@ -18,40 +18,40 @@ API routes for images. """ -import os import logging -import urllib.parse +import os import tempfile +import urllib.parse +from typing import List, Literal, Optional -from fastapi import APIRouter, Request, Response, Depends, Query, status +from fastapi import APIRouter, Depends, Query, Request, Response, status from fastapi.encoders import jsonable_encoder -from starlette.requests import ClientDisconnect -from sqlalchemy.orm.exc import MultipleResultsFound from sqlalchemy.exc import SQLAlchemyError -from typing import List, Optional, Literal +from sqlalchemy.orm.exc import MultipleResultsFound +from starlette.requests import ClientDisconnect +import gns3server.db.models as models from gns3server import schemas -from gns3server.config import Config from gns3server.compute.qemu import Qemu +from gns3server.config import Config +from gns3server.controller import Controller +from gns3server.controller.controller_error import ( + ControllerBadRequestError, + ControllerError, + ControllerForbiddenError, + ControllerNotFoundError, +) +from gns3server.db.repositories.images import ImagesRepository +from gns3server.db.repositories.rbac import RbacRepository +from gns3server.db.repositories.templates import TemplatesRepository +from gns3server.services.image_reconciliation import get_image_reconciliation_service +from gns3server.utils.image_inventory import ImageLockBusy, contained_path, fingerprint, image_lock, publish_image from gns3server.utils.images import ( InvalidImageError, - write_image, - read_image_info, default_images_directory, get_builtin_disks, -) -import gns3server.db.models as models -from gns3server.db.repositories.images import ImagesRepository -from gns3server.db.repositories.templates import TemplatesRepository -from gns3server.db.repositories.rbac import RbacRepository -from gns3server.controller import Controller -from gns3server.services.image_reconciliation import get_image_reconciliation_service -from gns3server.utils.image_inventory import contained_path, image_lock, publish_image, fingerprint, ImageLockBusy -from gns3server.controller.controller_error import ( - ControllerError, - ControllerNotFoundError, - ControllerForbiddenError, - ControllerBadRequestError, + read_image_info, + write_image, ) from .dependencies.authentication import get_current_active_user diff --git a/gns3server/api/routes/controller/links.py b/gns3server/api/routes/controller/links.py index 2f5eddee3..6d805d4ae 100644 --- a/gns3server/api/routes/controller/links.py +++ b/gns3server/api/routes/controller/links.py @@ -19,31 +19,30 @@ API routes for links. """ import asyncio +import logging import os -import multidict -import aiohttp - -from fastapi import APIRouter, Depends, Request, status, WebSocket -from fastapi.responses import FileResponse, StreamingResponse -from fastapi.encoders import jsonable_encoder from typing import Any, List, Union from uuid import UUID, uuid4 +import aiohttp +import multidict +from fastapi import APIRouter, Depends, Request, WebSocket, status +from fastapi.encoders import jsonable_encoder +from fastapi.responses import FileResponse, StreamingResponse + +from gns3server import schemas +from gns3server.agent.web_wireshark.manager import WebWiresharkManager from gns3server.controller import Controller from gns3server.controller.controller_error import ControllerError +from gns3server.controller.link import _UNSET, Link from gns3server.db.repositories.rbac import RbacRepository -from gns3server.controller.link import Link, _UNSET from gns3server.utils.http_client import HTTPClient from gns3server.utils.port_allocator import link_id_to_port from gns3server.utils.websocket_to_websocket import websocket_proxy -from gns3server import schemas -from gns3server.agent.web_wireshark.manager import WebWiresharkManager from .dependencies.database import get_repository from .dependencies.rbac import has_privilege, has_privilege_on_websocket -import logging - log = logging.getLogger(__name__) responses: dict[int | str, dict[str, Any]] = { diff --git a/gns3server/api/routes/controller/llm_model_configs.py b/gns3server/api/routes/controller/llm_model_configs.py index c36912a02..b7675bf6d 100644 --- a/gns3server/api/routes/controller/llm_model_configs.py +++ b/gns3server/api/routes/controller/llm_model_configs.py @@ -19,24 +19,23 @@ API routes for LLM model configurations. """ -from fastapi import APIRouter, Depends, HTTPException, status -from uuid import UUID +import logging from typing import List +from uuid import UUID + +from fastapi import APIRouter, Depends, HTTPException, status from gns3server import schemas from gns3server.controller.controller_error import ( ControllerBadRequestError, ControllerNotFoundError, ) - from gns3server.db.repositories.llm_model_configs import LLMModelConfigsRepository from gns3server.db.repositories.users import UsersRepository from .dependencies.database import get_repository from .dependencies.rbac import has_privilege -import logging - log = logging.getLogger(__name__) router = APIRouter() diff --git a/gns3server/api/routes/controller/netmiko.py b/gns3server/api/routes/controller/netmiko.py index 44c9c9f42..3e71d67c8 100644 --- a/gns3server/api/routes/controller/netmiko.py +++ b/gns3server/api/routes/controller/netmiko.py @@ -19,6 +19,7 @@ API routes for Netmiko metadata. """ +import logging from typing import Optional from fastapi import APIRouter, Depends, HTTPException, status @@ -27,8 +28,6 @@ from gns3server import schemas from .dependencies.authentication import get_current_active_user -import logging - log = logging.getLogger(__name__) diff --git a/gns3server/api/routes/controller/nodes.py b/gns3server/api/routes/controller/nodes.py index 2b691e098..1395a60ea 100644 --- a/gns3server/api/routes/controller/nodes.py +++ b/gns3server/api/routes/controller/nodes.py @@ -18,33 +18,32 @@ API routes for nodes. """ -import aiohttp import asyncio import contextlib import ipaddress +import logging +from typing import Any, Callable, List, Optional +from uuid import UUID -from fastapi import APIRouter, Depends, WebSocket, WebSocketDisconnect, Request, Response, status, Query, HTTPException +import aiohttp +from fastapi import APIRouter, Depends, HTTPException, Query, Request, Response, WebSocket, WebSocketDisconnect, status from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from fastapi.routing import APIRoute -from typing import Any, List, Callable, Optional -from uuid import UUID -from gns3server.controller import Controller +from gns3server import schemas from gns3server.config import Config +from gns3server.controller import Controller +from gns3server.controller.controller_error import ControllerBadRequestError, ControllerForbiddenError from gns3server.controller.node import Node from gns3server.controller.project import Project +from gns3server.db.repositories.rbac import RbacRepository from gns3server.utils import force_unix_path from gns3server.utils.http_client import HTTPClient -from gns3server.controller.controller_error import ControllerForbiddenError, ControllerBadRequestError -from gns3server.db.repositories.rbac import RbacRepository -from gns3server import schemas from .dependencies.database import get_repository from .dependencies.rbac import has_privilege, has_privilege_on_websocket -import logging - log = logging.getLogger(__name__) node_locks: dict[str, dict[str, Any]] = {} diff --git a/gns3server/api/routes/controller/pools.py b/gns3server/api/routes/controller/pools.py index 882c05264..71a01a2ce 100644 --- a/gns3server/api/routes/controller/pools.py +++ b/gns3server/api/routes/controller/pools.py @@ -19,22 +19,21 @@ API routes for resource pools. """ -from fastapi import APIRouter, Depends, status -from uuid import UUID -from typing import List, Optional - -from gns3server import schemas -from gns3server.controller.controller_error import ControllerError, ControllerBadRequestError, ControllerNotFoundError - -from gns3server.controller import Controller -import gns3server.db.models as models -from gns3server.db.repositories.rbac import RbacRepository -from gns3server.db.repositories.pools import ResourcePoolsRepository - -from .dependencies.rbac import has_privilege -from .dependencies.database import get_repository - import logging +from typing import List, Optional +from uuid import UUID + +from fastapi import APIRouter, Depends, status + +import gns3server.db.models as models +from gns3server import schemas +from gns3server.controller import Controller +from gns3server.controller.controller_error import ControllerBadRequestError, ControllerError, ControllerNotFoundError +from gns3server.db.repositories.pools import ResourcePoolsRepository +from gns3server.db.repositories.rbac import RbacRepository + +from .dependencies.database import get_repository +from .dependencies.rbac import has_privilege log = logging.getLogger(__name__) diff --git a/gns3server/api/routes/controller/privileges.py b/gns3server/api/routes/controller/privileges.py index 1f34ec1ff..88b7481b9 100644 --- a/gns3server/api/routes/controller/privileges.py +++ b/gns3server/api/routes/controller/privileges.py @@ -15,14 +15,16 @@ API route for privileges """ -from typing import List -import gns3server.db.models as models -from gns3server.db.repositories.rbac import RbacRepository -from .dependencies.database import get_repository -from fastapi import APIRouter, Depends import logging +from typing import List +from fastapi import APIRouter, Depends + +import gns3server.db.models as models from gns3server import schemas +from gns3server.db.repositories.rbac import RbacRepository + +from .dependencies.database import get_repository log = logging.getLogger(__name__) router = APIRouter() diff --git a/gns3server/api/routes/controller/projects.py b/gns3server/api/routes/controller/projects.py index 83dfcff8e..fab2691d2 100644 --- a/gns3server/api/routes/controller/projects.py +++ b/gns3server/api/routes/controller/projects.py @@ -18,44 +18,45 @@ API routes for projects. """ -import os import asyncio +import logging +import os import tempfile -import aiofiles import time import urllib.parse -import gns3server.utils.zipfile_zstd as zipfile -import logging +import aiofiles + +import gns3server.utils.zipfile_zstd as zipfile log = logging.getLogger() -from fastapi import APIRouter, Depends, Request, Body, HTTPException, status, WebSocket, WebSocketDisconnect -from fastapi.encoders import jsonable_encoder -from fastapi.responses import StreamingResponse, FileResponse -from websockets.exceptions import ConnectionClosed, WebSocketException from typing import Any, List, Optional from uuid import UUID +from fastapi import APIRouter, Body, Depends, HTTPException, Request, WebSocket, WebSocketDisconnect, status +from fastapi.encoders import jsonable_encoder +from fastapi.responses import FileResponse, StreamingResponse +from websockets.exceptions import ConnectionClosed, WebSocketException + from gns3server import schemas -from gns3server.controller import Controller -from gns3server.controller.project import Project -from gns3server.controller.link import _UNSET -from gns3server.controller.controller_error import ControllerError, ControllerBadRequestError -from gns3server.controller.import_project import import_project as import_controller_project +from gns3server.controller import Controller, marker_replay +from gns3server.controller.controller_error import ControllerBadRequestError, ControllerError from gns3server.controller.export_project import export_project as export_controller_project -from gns3server.controller import marker_replay +from gns3server.controller.import_project import import_project as import_controller_project +from gns3server.controller.link import _UNSET from gns3server.controller.marker_replay import SharkdError, SharkdMissingError +from gns3server.controller.project import Project +from gns3server.db.repositories.pools import ResourcePoolsRepository +from gns3server.db.repositories.rbac import RbacRepository +from gns3server.db.repositories.templates import TemplatesRepository +from gns3server.services.templates import TemplatesService from gns3server.utils.asyncio import aiozipstream from gns3server.utils.path import is_safe_path -from gns3server.db.repositories.templates import TemplatesRepository -from gns3server.db.repositories.rbac import RbacRepository -from gns3server.db.repositories.pools import ResourcePoolsRepository -from gns3server.services.templates import TemplatesService -from .dependencies.rbac import has_privilege, has_privilege_on_websocket from .dependencies.authentication import get_current_active_user from .dependencies.database import get_repository +from .dependencies.rbac import has_privilege, has_privilege_on_websocket responses: dict[int | str, dict[str, Any]] = { 404: {"model": schemas.ErrorMessage, "description": "Could not find project"} diff --git a/gns3server/api/routes/controller/roles.py b/gns3server/api/routes/controller/roles.py index 3f6e854a1..119738dd2 100644 --- a/gns3server/api/routes/controller/roles.py +++ b/gns3server/api/routes/controller/roles.py @@ -19,25 +19,25 @@ API routes for roles. """ -from fastapi import APIRouter, Depends, status -from uuid import UUID +import logging from typing import List, Optional +from uuid import UUID -from gns3server import schemas -from gns3server.controller.controller_error import ( - ControllerError, - ControllerBadRequestError, - ControllerNotFoundError, - ControllerForbiddenError, -) +from fastapi import APIRouter, Depends, status import gns3server.db.models as models +from gns3server import schemas +from gns3server.controller.controller_error import ( + ControllerBadRequestError, + ControllerError, + ControllerForbiddenError, + ControllerNotFoundError, +) from gns3server.db.repositories.rbac import RbacRepository + from .dependencies.database import get_repository from .dependencies.rbac import has_privilege -import logging - log = logging.getLogger(__name__) router = APIRouter() diff --git a/gns3server/api/routes/controller/settings.py b/gns3server/api/routes/controller/settings.py index 466edc726..eaae57bd3 100644 --- a/gns3server/api/routes/controller/settings.py +++ b/gns3server/api/routes/controller/settings.py @@ -19,8 +19,9 @@ API routes for managing the server settings (gns3_server.conf). """ -from fastapi import APIRouter, Depends, HTTPException +import logging +from fastapi import APIRouter, Depends, HTTPException from pydantic import ValidationError from gns3server import schemas @@ -31,8 +32,6 @@ from gns3server.schemas.controller.settings import SECRET_MASK from .dependencies.rbac import has_privilege -import logging - log = logging.getLogger(__name__) router = APIRouter() diff --git a/gns3server/api/routes/controller/snapshots.py b/gns3server/api/routes/controller/snapshots.py index 4ec8c467c..eddcd029e 100644 --- a/gns3server/api/routes/controller/snapshots.py +++ b/gns3server/api/routes/controller/snapshots.py @@ -23,14 +23,15 @@ import logging log = logging.getLogger() -from fastapi import APIRouter, Depends, status from typing import Any, List from uuid import UUID -from gns3server.controller.project import Project -from gns3server.db.repositories.rbac import RbacRepository +from fastapi import APIRouter, Depends, status + from gns3server import schemas from gns3server.controller import Controller +from gns3server.controller.project import Project +from gns3server.db.repositories.rbac import RbacRepository from .dependencies.database import get_repository from .dependencies.rbac import has_privilege diff --git a/gns3server/api/routes/controller/symbols.py b/gns3server/api/routes/controller/symbols.py index 5f004ffa6..98d6a0c91 100644 --- a/gns3server/api/routes/controller/symbols.py +++ b/gns3server/api/routes/controller/symbols.py @@ -19,21 +19,20 @@ API routes for symbols. """ +import logging import os - -from fastapi import APIRouter, Request, Depends, Response, status -from fastapi.responses import FileResponse from typing import List -from gns3server.controller import Controller +from fastapi import APIRouter, Depends, Request, Response, status +from fastapi.responses import FileResponse + from gns3server import schemas -from gns3server.controller.controller_error import ControllerError, ControllerNotFoundError, ControllerForbiddenError +from gns3server.controller import Controller +from gns3server.controller.controller_error import ControllerError, ControllerForbiddenError, ControllerNotFoundError from gns3server.utils.get_resource import get_resource from .dependencies.rbac import has_privilege -import logging - log = logging.getLogger(__name__) diff --git a/gns3server/api/routes/controller/templates.py b/gns3server/api/routes/controller/templates.py index 3c35eea16..4263acede 100644 --- a/gns3server/api/routes/controller/templates.py +++ b/gns3server/api/routes/controller/templates.py @@ -18,30 +18,30 @@ API routes for templates. """ -import os import hashlib import json - import logging +import os log = logging.getLogger(__name__) -from fastapi import APIRouter, Request, HTTPException, Depends, Response, status, Query from typing import Any, List, Optional, Union from uuid import UUID +from fastapi import APIRouter, Depends, HTTPException, Query, Request, Response, status + from gns3server import schemas +from gns3server.controller import Controller +from gns3server.controller.controller_error import ControllerBadRequestError, ControllerError +from gns3server.db.repositories.images import ImagesRepository +from gns3server.db.repositories.rbac import RbacRepository from gns3server.db.repositories.templates import TemplatesRepository from gns3server.services.templates import TemplatesService -from gns3server.db.repositories.rbac import RbacRepository -from gns3server.db.repositories.images import ImagesRepository -from gns3server.controller import Controller -from gns3server.controller.controller_error import ControllerError, ControllerBadRequestError from gns3server.utils.images import get_builtin_disks from .dependencies.authentication import get_current_active_user -from .dependencies.rbac import has_privilege from .dependencies.database import get_repository +from .dependencies.rbac import has_privilege responses: dict[int | str, dict[str, Any]] = { 404: {"model": schemas.ErrorMessage, "description": "Could not find template"} diff --git a/gns3server/api/routes/controller/users.py b/gns3server/api/routes/controller/users.py index 673886195..1ba9a2eff 100644 --- a/gns3server/api/routes/controller/users.py +++ b/gns3server/api/routes/controller/users.py @@ -19,30 +19,29 @@ API routes for users. """ +import logging +from typing import List, Optional +from uuid import UUID + from fastapi import APIRouter, Depends, HTTPException, Response, status from fastapi.security import OAuth2PasswordRequestForm -from uuid import UUID -from typing import List, Optional - -from gns3server import schemas -from gns3server.controller.controller_error import ( - ControllerError, - ControllerBadRequestError, - ControllerNotFoundError, - ControllerForbiddenError, -) import gns3server.db.models as models -from gns3server.db.repositories.users import UsersRepository +from gns3server import schemas +from gns3server.controller.controller_error import ( + ControllerBadRequestError, + ControllerError, + ControllerForbiddenError, + ControllerNotFoundError, +) from gns3server.db.repositories.rbac import RbacRepository +from gns3server.db.repositories.users import UsersRepository from gns3server.services import auth_service from .dependencies.authentication import get_current_active_user from .dependencies.database import get_repository from .dependencies.rbac import has_privilege -import logging - log = logging.getLogger(__name__) router = APIRouter() diff --git a/gns3server/api/routes/index.py b/gns3server/api/routes/index.py index 0c4719725..c06bd36b2 100644 --- a/gns3server/api/routes/index.py +++ b/gns3server/api/routes/index.py @@ -16,12 +16,12 @@ import os -from fastapi import APIRouter, Request, HTTPException, status -from fastapi.responses import RedirectResponse, HTMLResponse, FileResponse +from fastapi import APIRouter, HTTPException, Request, status +from fastapi.responses import FileResponse, HTMLResponse, RedirectResponse from fastapi.templating import Jinja2Templates -from gns3server.version import __version__ from gns3server.utils.get_resource import get_resource +from gns3server.version import __version__ router = APIRouter() templates = Jinja2Templates(directory=os.path.join("gns3server", "templates")) diff --git a/gns3server/api/server.py b/gns3server/api/server.py index 7827aec7c..4ea037e83 100644 --- a/gns3server/api/server.py +++ b/gns3server/api/server.py @@ -21,36 +21,33 @@ FastAPI app from typing import cast -from fastapi import FastAPI, Request, HTTPException, status -from fastapi.middleware.cors import CORSMiddleware -from fastapi.responses import JSONResponse +from fastapi import FastAPI, HTTPException, Request, status from fastapi.exceptions import RequestValidationError -from fastapi.staticfiles import StaticFiles -from sqlalchemy.exc import SQLAlchemyError -from uvicorn.main import Server as UvicornServer - +from fastapi.middleware.cors import CORSMiddleware from fastapi.openapi.docs import ( get_redoc_html, get_swagger_ui_html, get_swagger_ui_oauth2_redirect_html, ) - -from gns3server.controller.controller_error import ( - ControllerError, - ControllerNotFoundError, - ControllerBadRequestError, - ControllerTimeoutError, - ControllerForbiddenError, - ControllerUnauthorizedError, - ComputeConflictError, -) - -from gns3server.api.routes import controller, index -from gns3server.api.routes.compute import compute_api -from gns3server.core import tasks +from fastapi.responses import JSONResponse +from fastapi.staticfiles import StaticFiles +from sqlalchemy.exc import SQLAlchemyError +from uvicorn.main import Server as UvicornServer # MCP is an optional feature — import only if dependencies are installed from gns3server.agent import MCP_AVAILABLE +from gns3server.api.routes import controller, index +from gns3server.api.routes.compute import compute_api +from gns3server.controller.controller_error import ( + ComputeConflictError, + ControllerBadRequestError, + ControllerError, + ControllerForbiddenError, + ControllerNotFoundError, + ControllerTimeoutError, + ControllerUnauthorizedError, +) +from gns3server.core import tasks if MCP_AVAILABLE: from gns3server.agent import mcp diff --git a/gns3server/compute/__init__.py b/gns3server/compute/__init__.py index 9b7a6cc18..1b453bde3 100644 --- a/gns3server/compute/__init__.py +++ b/gns3server/compute/__init__.py @@ -14,15 +14,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys import os +import sys from .builtin import Builtin -from .vpcs import VPCS -from .virtualbox import VirtualBox from .dynamips import Dynamips from .qemu import Qemu +from .virtualbox import VirtualBox from .vmware import VMware +from .vpcs import VPCS MODULES = [Builtin, VPCS, VirtualBox, Dynamips, Qemu, VMware] diff --git a/gns3server/compute/base_manager.py b/gns3server/compute/base_manager.py index 6ee63f427..a455beb97 100644 --- a/gns3server/compute/base_manager.py +++ b/gns3server/compute/base_manager.py @@ -14,37 +14,38 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys -import os -import struct -import stat import asyncio -import aiofiles -import socket -import shutil -import re -import logging import inspect +import logging +import os +import re +import shutil +import socket +import stat +import struct +import sys + +import aiofiles log = logging.getLogger(__name__) -from gns3server.utils.asyncio import cancellable_wait_run_in_executor +from typing import Type +from uuid import UUID, uuid4 + from gns3server.compute.compute_error import ComputeError, ComputeForbiddenError, ComputeNotFoundError +from gns3server.utils.asyncio import cancellable_wait_run_in_executor from gns3server.utils.interfaces import is_interface_up -from uuid import UUID, uuid4 -from typing import Type from ..config import Config from ..utils import force_unix_path -from .project_manager import ProjectManager -from .port_manager import PortManager +from ..utils.images import default_images_directory, images_directories, list_images, md5sum, remove_checksum from .base_node import BaseNode - -from .nios.nio_udp import NIOUDP -from .nios.nio_tap import NIOTAP +from .error import ImageMissingError, NodeError from .nios.nio_ethernet import NIOEthernet -from ..utils.images import md5sum, remove_checksum, images_directories, default_images_directory, list_images -from .error import NodeError, ImageMissingError +from .nios.nio_tap import NIOTAP +from .nios.nio_udp import NIOUDP +from .port_manager import PortManager +from .project_manager import ProjectManager CHUNK_SIZE = 1024 * 8 # 8KB diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py index 0f56bdd04..8bfbb70c7 100644 --- a/gns3server/compute/base_node.py +++ b/gns3server/compute/base_node.py @@ -14,33 +14,34 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys -import os -import stat -import shutil import asyncio import contextlib import json -import struct -import tempfile -import psutil +import logging +import os import platform import re -import asyncssh +import shutil +import stat +import struct +import sys +import tempfile +import asyncssh +import psutil from fastapi import WebSocketDisconnect -from gns3server.utils.interfaces import interfaces + from gns3server.compute.compute_error import ComputeError -from ..compute.port_manager import PortManager -from ..utils.asyncio import wait_run_in_executor, locking -from ..utils.asyncio.ssh_server import AsyncioSSHServer -from ..utils.asyncio.telnet_server import AsyncioTelnetServer from gns3server.compute.ubridge.hypervisor import Hypervisor from gns3server.compute.ubridge.ubridge_error import UbridgeError -from .nios.nio_udp import NIOUDP -from .error import NodeError +from gns3server.utils.interfaces import interfaces -import logging +from ..compute.port_manager import PortManager +from ..utils.asyncio import locking, wait_run_in_executor +from ..utils.asyncio.ssh_server import AsyncioSSHServer +from ..utils.asyncio.telnet_server import AsyncioTelnetServer +from .error import NodeError +from .nios.nio_udp import NIOUDP log = logging.getLogger(__name__) diff --git a/gns3server/compute/builtin/__init__.py b/gns3server/compute/builtin/__init__.py index 94b20748b..86bbc2e15 100644 --- a/gns3server/compute/builtin/__init__.py +++ b/gns3server/compute/builtin/__init__.py @@ -18,11 +18,11 @@ Builtin nodes server module. """ -from ..base_manager import BaseManager -from .builtin_node_factory import BuiltinNodeFactory, BUILTIN_NODES - import logging +from ..base_manager import BaseManager +from .builtin_node_factory import BUILTIN_NODES, BuiltinNodeFactory + log = logging.getLogger(__name__) diff --git a/gns3server/compute/builtin/builtin_node_factory.py b/gns3server/compute/builtin/builtin_node_factory.py index eafa1d544..082b78c54 100644 --- a/gns3server/compute/builtin/builtin_node_factory.py +++ b/gns3server/compute/builtin/builtin_node_factory.py @@ -15,13 +15,13 @@ # along with this program. If not, see . +import logging + from ..error import NodeError from .nodes.cloud import Cloud -from .nodes.nat import Nat from .nodes.ethernet_hub import EthernetHub from .nodes.ethernet_switch import EthernetSwitch - -import logging +from .nodes.nat import Nat log = logging.getLogger(__name__) diff --git a/gns3server/compute/builtin/nodes/cloud.py b/gns3server/compute/builtin/nodes/cloud.py index 8e40e5ea6..5737a196d 100644 --- a/gns3server/compute/builtin/nodes/cloud.py +++ b/gns3server/compute/builtin/nodes/cloud.py @@ -14,18 +14,17 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys +import logging import subprocess +import sys -from ...error import NodeError -from ...base_node import BaseNode -from ...nios.nio_udp import NIOUDP +import gns3server.utils.asyncio +import gns3server.utils.interfaces from gns3server.compute.ubridge.ubridge_error import UbridgeError -import gns3server.utils.interfaces -import gns3server.utils.asyncio - -import logging +from ...base_node import BaseNode +from ...error import NodeError +from ...nios.nio_udp import NIOUDP log = logging.getLogger(__name__) diff --git a/gns3server/compute/builtin/nodes/ethernet_hub.py b/gns3server/compute/builtin/nodes/ethernet_hub.py index 0edc82ae5..8fa5b29f6 100644 --- a/gns3server/compute/builtin/nodes/ethernet_hub.py +++ b/gns3server/compute/builtin/nodes/ethernet_hub.py @@ -15,11 +15,10 @@ # along with this program. If not, see . import asyncio +import logging from ...base_node import BaseNode -import logging - log = logging.getLogger(__name__) diff --git a/gns3server/compute/builtin/nodes/ethernet_switch.py b/gns3server/compute/builtin/nodes/ethernet_switch.py index 153cb0af6..759f8a638 100644 --- a/gns3server/compute/builtin/nodes/ethernet_switch.py +++ b/gns3server/compute/builtin/nodes/ethernet_switch.py @@ -37,12 +37,13 @@ be the switch). ESW ``access``/``dot1q``/``qinq`` port modes are composed from the ``brctl`` VLAN primitives here -- see ``_apply_port_vlan``. """ -from ...base_node import BaseNode -from ...nios.nio_udp import NIOUDP -from ...error import NodeError +import logging + from gns3server.compute.ubridge.ubridge_error import UbridgeError -import logging +from ...base_node import BaseNode +from ...error import NodeError +from ...nios.nio_udp import NIOUDP log = logging.getLogger(__name__) diff --git a/gns3server/compute/builtin/nodes/nat.py b/gns3server/compute/builtin/nodes/nat.py index 4a75d9a48..ce5a4b77e 100644 --- a/gns3server/compute/builtin/nodes/nat.py +++ b/gns3server/compute/builtin/nodes/nat.py @@ -15,15 +15,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging import sys -from .cloud import Cloud -from ...error import NodeError - import gns3server.utils.interfaces from gns3server.config import Config -import logging +from ...error import NodeError +from .cloud import Cloud log = logging.getLogger(__name__) diff --git a/gns3server/compute/docker/__init__.py b/gns3server/compute/docker/__init__.py index a6b1d4dae..bc643ee67 100644 --- a/gns3server/compute/docker/__init__.py +++ b/gns3server/compute/docker/__init__.py @@ -18,28 +18,29 @@ Docker server module. """ -import os -import sys -import json import asyncio +import json import logging -import aiohttp +import os import shutil +import sys + +import aiohttp import platformdirs -from gns3server.utils import parse_version -from gns3server.config import Config -from gns3server.utils.asyncio import locking from gns3server.compute.base_manager import BaseManager -from gns3server.compute.docker.docker_vm import DockerVM -from gns3server.compute.docker.vendor_docker_vm import VendorDockerVM -from gns3server.compute.docker.iol_docker_vm import IOLDockerVM from gns3server.compute.docker.docker_error import ( DockerError, DockerHttp304Error, DockerHttp404Error, DockerHttp409Error, ) +from gns3server.compute.docker.docker_vm import DockerVM +from gns3server.compute.docker.iol_docker_vm import IOLDockerVM +from gns3server.compute.docker.vendor_docker_vm import VendorDockerVM +from gns3server.config import Config +from gns3server.utils import parse_version +from gns3server.utils.asyncio import locking log = logging.getLogger(__name__) diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py index 4837a8693..4c33c311f 100644 --- a/gns3server/compute/docker/docker_vm.py +++ b/gns3server/compute/docker/docker_vm.py @@ -18,38 +18,35 @@ Docker container instance. """ -import sys import asyncio import contextlib import json -import shutil -import psutil -import shlex -import aiohttp -import subprocess +import logging import os import re +import shlex +import shutil +import subprocess +import sys +import aiohttp +import psutil + +from gns3server.compute.compute_error import ComputeError +from gns3server.compute.ubridge.ubridge_error import UbridgeError, UbridgeNamespaceError +from gns3server.utils import int_to_macaddress, macaddress_to_int +from gns3server.utils.asyncio import monitor_process, wait_for_file_creation, wait_run_in_executor +from gns3server.utils.asyncio.raw_command_server import AsyncioRawCommandServer from gns3server.utils.asyncio.ssh_server import AsyncioSSHServer from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer -from gns3server.utils.asyncio.raw_command_server import AsyncioRawCommandServer -from gns3server.utils.asyncio import wait_for_file_creation -from gns3server.utils.asyncio import monitor_process -from gns3server.utils.asyncio import wait_run_in_executor from gns3server.utils.get_resource import get_resource from gns3server.utils.hostname import is_rfc1123_hostname_valid -from gns3server.utils import macaddress_to_int, int_to_macaddress - -from gns3server.compute.ubridge.ubridge_error import UbridgeError, UbridgeNamespaceError -from gns3server.compute.compute_error import ComputeError -from ..base_node import BaseNode from ..adapters.ethernet_adapter import EthernetAdapter +from ..base_node import BaseNode +from ..error import ImageMissingError from ..nios.nio_udp import NIOUDP from .docker_error import DockerError, DockerHttp304Error, DockerHttp404Error, DockerHttp409Error -from ..error import ImageMissingError - -import logging log = logging.getLogger(__name__) diff --git a/gns3server/compute/docker/vendor_docker_vm.py b/gns3server/compute/docker/vendor_docker_vm.py index 1adb5a951..33af64e15 100644 --- a/gns3server/compute/docker/vendor_docker_vm.py +++ b/gns3server/compute/docker/vendor_docker_vm.py @@ -34,10 +34,10 @@ import os import shutil import tempfile +from gns3server.compute.docker.docker_error import DockerError, DockerHttp304Error, DockerHttp404Error +from gns3server.compute.docker.docker_vm import DockerVM from gns3server.utils.asyncio import wait_for_file_creation from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer -from gns3server.compute.docker.docker_vm import DockerVM -from gns3server.compute.docker.docker_error import DockerError, DockerHttp304Error, DockerHttp404Error log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/__init__.py b/gns3server/compute/dynamips/__init__.py index cbedaa6ad..ec2cdacc1 100644 --- a/gns3server/compute/dynamips/__init__.py +++ b/gns3server/compute/dynamips/__init__.py @@ -18,49 +18,38 @@ Dynamips server module. """ -import sys +import asyncio +import glob +import logging import os +import re import shutil import socket -import time -import asyncio -import tempfile -import logging import subprocess -import glob -import re +import sys +import tempfile +import time log = logging.getLogger(__name__) -from gns3server.utils.interfaces import is_interface_up -from gns3server.utils.asyncio import wait_run_in_executor, subprocess_check_output -from gns3server.utils import parse_version from uuid import uuid4 + +from gns3server.utils import parse_version +from gns3server.utils.asyncio import subprocess_check_output, wait_run_in_executor +from gns3server.utils.interfaces import is_interface_up + from ..base_manager import BaseManager from ..port_manager import PortManager -from .dynamips_error import DynamipsError -from .hypervisor import Hypervisor -from .nodes.router import Router -from .dynamips_factory import DynamipsFactory - -# NIOs -from .nios.nio_udp import NIOUDP -from .nios.nio_unix import NIOUNIX -from .nios.nio_vde import NIOVDE -from .nios.nio_tap import NIOTAP -from .nios.nio_generic_ethernet import NIOGenericEthernet -from .nios.nio_linux_ethernet import NIOLinuxEthernet -from .nios.nio_null import NIONull # Adapters from .adapters.c7200_io_2fe import C7200_IO_2FE from .adapters.c7200_io_fe import C7200_IO_FE from .adapters.c7200_io_ge_e import C7200_IO_GE_E -from .adapters.nm_16esw import NM_16ESW from .adapters.nm_1e import NM_1E from .adapters.nm_1fe_tx import NM_1FE_TX from .adapters.nm_4e import NM_4E from .adapters.nm_4t import NM_4T +from .adapters.nm_16esw import NM_16ESW from .adapters.pa_2fe_tx import PA_2FE_TX from .adapters.pa_4e import PA_4E from .adapters.pa_4t import PA_4T @@ -73,7 +62,19 @@ from .adapters.pa_pos_oc3 import PA_POS_OC3 from .adapters.wic_1enet import WIC_1ENET from .adapters.wic_1t import WIC_1T from .adapters.wic_2t import WIC_2T +from .dynamips_error import DynamipsError +from .dynamips_factory import DynamipsFactory +from .hypervisor import Hypervisor +from .nios.nio_generic_ethernet import NIOGenericEthernet +from .nios.nio_linux_ethernet import NIOLinuxEthernet +from .nios.nio_null import NIONull +from .nios.nio_tap import NIOTAP +# NIOs +from .nios.nio_udp import NIOUDP +from .nios.nio_unix import NIOUNIX +from .nios.nio_vde import NIOVDE +from .nodes.router import Router ADAPTER_MATRIX = { "C7200-IO-2FE": C7200_IO_2FE, diff --git a/gns3server/compute/dynamips/dynamips_factory.py b/gns3server/compute/dynamips/dynamips_factory.py index cbafc4934..4febe9b7d 100644 --- a/gns3server/compute/dynamips/dynamips_factory.py +++ b/gns3server/compute/dynamips/dynamips_factory.py @@ -15,7 +15,10 @@ # along with this program. If not, see . +import logging + from .dynamips_error import DynamipsError +from .nodes.atm_switch import ATMSwitch from .nodes.c1700 import C1700 from .nodes.c2600 import C2600 from .nodes.c2691 import C2691 @@ -23,13 +26,10 @@ from .nodes.c3600 import C3600 from .nodes.c3725 import C3725 from .nodes.c3745 import C3745 from .nodes.c7200 import C7200 -from .nodes.atm_switch import ATMSwitch -from .nodes.ethernet_switch import EthernetSwitch from .nodes.ethernet_hub import EthernetHub +from .nodes.ethernet_switch import EthernetSwitch from .nodes.frame_relay_switch import FrameRelaySwitch -import logging - log = logging.getLogger(__name__) PLATFORMS = { diff --git a/gns3server/compute/dynamips/dynamips_hypervisor.py b/gns3server/compute/dynamips/dynamips_hypervisor.py index 514e75360..b2c1f7640 100644 --- a/gns3server/compute/dynamips/dynamips_hypervisor.py +++ b/gns3server/compute/dynamips/dynamips_hypervisor.py @@ -19,10 +19,10 @@ Interface for Dynamips hypervisor management module ("hypervisor") http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L46 """ +import asyncio +import logging import re import time -import logging -import asyncio from .dynamips_error import DynamipsError diff --git a/gns3server/compute/dynamips/hypervisor.py b/gns3server/compute/dynamips/hypervisor.py index 403c38c7e..c528c3e6f 100644 --- a/gns3server/compute/dynamips/hypervisor.py +++ b/gns3server/compute/dynamips/hypervisor.py @@ -18,16 +18,16 @@ Represents a Dynamips hypervisor and starts/stops the associated Dynamips process. """ -import sys +import asyncio +import logging import os import subprocess -import asyncio +import sys from gns3server.utils.asyncio import wait_for_process_termination -from .dynamips_hypervisor import DynamipsHypervisor -from .dynamips_error import DynamipsError -import logging +from .dynamips_error import DynamipsError +from .dynamips_hypervisor import DynamipsHypervisor log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nios/nio.py b/gns3server/compute/dynamips/nios/nio.py index 512a10699..3b4c74969 100644 --- a/gns3server/compute/dynamips/nios/nio.py +++ b/gns3server/compute/dynamips/nios/nio.py @@ -20,10 +20,10 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L451 """ import asyncio -from ..dynamips_error import DynamipsError - import logging +from ..dynamips_error import DynamipsError + log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nios/nio_generic_ethernet.py b/gns3server/compute/dynamips/nios/nio_generic_ethernet.py index 1407c6694..679c8bc60 100644 --- a/gns3server/compute/dynamips/nios/nio_generic_ethernet.py +++ b/gns3server/compute/dynamips/nios/nio_generic_ethernet.py @@ -19,10 +19,10 @@ Interface for generic Ethernet NIOs (PCAP library). """ import asyncio -import uuid -from .nio import NIO - import logging +import uuid + +from .nio import NIO log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nios/nio_linux_ethernet.py b/gns3server/compute/dynamips/nios/nio_linux_ethernet.py index c11039a5c..b85eb4b81 100644 --- a/gns3server/compute/dynamips/nios/nio_linux_ethernet.py +++ b/gns3server/compute/dynamips/nios/nio_linux_ethernet.py @@ -19,10 +19,10 @@ Interface for Linux Ethernet NIOs (Linux only). """ import asyncio -import uuid -from .nio import NIO - import logging +import uuid + +from .nio import NIO log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nios/nio_null.py b/gns3server/compute/dynamips/nios/nio_null.py index 1f56a12e8..d47170329 100644 --- a/gns3server/compute/dynamips/nios/nio_null.py +++ b/gns3server/compute/dynamips/nios/nio_null.py @@ -19,10 +19,10 @@ Interface for dummy NIOs (mostly for tests). """ import asyncio -import uuid -from .nio import NIO - import logging +import uuid + +from .nio import NIO log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nios/nio_tap.py b/gns3server/compute/dynamips/nios/nio_tap.py index acd3a864e..47ac30494 100644 --- a/gns3server/compute/dynamips/nios/nio_tap.py +++ b/gns3server/compute/dynamips/nios/nio_tap.py @@ -19,10 +19,10 @@ Interface for TAP NIOs (UNIX based OSes only). """ import asyncio -import uuid -from .nio import NIO - import logging +import uuid + +from .nio import NIO log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nios/nio_udp.py b/gns3server/compute/dynamips/nios/nio_udp.py index c811858d9..4419bf71f 100644 --- a/gns3server/compute/dynamips/nios/nio_udp.py +++ b/gns3server/compute/dynamips/nios/nio_udp.py @@ -19,14 +19,13 @@ Interface for UDP NIOs. """ import asyncio +import logging import uuid from gns3server.compute.nios import nio_udp + from .nio import NIO - -import logging - log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nios/nio_unix.py b/gns3server/compute/dynamips/nios/nio_unix.py index bab9ee06e..37fbc0858 100644 --- a/gns3server/compute/dynamips/nios/nio_unix.py +++ b/gns3server/compute/dynamips/nios/nio_unix.py @@ -19,10 +19,10 @@ Interface for UNIX NIOs (Unix based OSes only). """ import asyncio -import uuid -from .nio import NIO - import logging +import uuid + +from .nio import NIO log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nios/nio_vde.py b/gns3server/compute/dynamips/nios/nio_vde.py index 7218179ce..c44787a46 100644 --- a/gns3server/compute/dynamips/nios/nio_vde.py +++ b/gns3server/compute/dynamips/nios/nio_vde.py @@ -19,10 +19,10 @@ Interface for VDE (Virtual Distributed Ethernet) NIOs (Unix based OSes only). """ import asyncio -import uuid -from .nio import NIO - import logging +import uuid + +from .nio import NIO log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nodes/atm_switch.py b/gns3server/compute/dynamips/nodes/atm_switch.py index 38e9d4ecb..0c4591399 100644 --- a/gns3server/compute/dynamips/nodes/atm_switch.py +++ b/gns3server/compute/dynamips/nodes/atm_switch.py @@ -20,13 +20,12 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L593 """ import asyncio +import logging import re -from .device import Device -from ..nios.nio_udp import NIOUDP from ..dynamips_error import DynamipsError - -import logging +from ..nios.nio_udp import NIOUDP +from .device import Device log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nodes/bridge.py b/gns3server/compute/dynamips/nodes/bridge.py index 04c1651f8..57b74e5e2 100644 --- a/gns3server/compute/dynamips/nodes/bridge.py +++ b/gns3server/compute/dynamips/nodes/bridge.py @@ -20,6 +20,7 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L538 """ import asyncio + from .device import Device diff --git a/gns3server/compute/dynamips/nodes/c1700.py b/gns3server/compute/dynamips/nodes/c1700.py index b2d24b25b..7ead2f8df 100644 --- a/gns3server/compute/dynamips/nodes/c1700.py +++ b/gns3server/compute/dynamips/nodes/c1700.py @@ -20,11 +20,11 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L428 """ import asyncio -from .router import Router +import logging + from ..adapters.c1700_mb_1fe import C1700_MB_1FE from ..adapters.c1700_mb_wic1 import C1700_MB_WIC1 - -import logging +from .router import Router log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nodes/c2600.py b/gns3server/compute/dynamips/nodes/c2600.py index 774d67e54..89159f57d 100644 --- a/gns3server/compute/dynamips/nodes/c2600.py +++ b/gns3server/compute/dynamips/nodes/c2600.py @@ -20,14 +20,14 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L404 """ import asyncio -from .router import Router -from ..adapters.c2600_mb_1e import C2600_MB_1E -from ..adapters.c2600_mb_2e import C2600_MB_2E -from ..adapters.c2600_mb_1fe import C2600_MB_1FE -from ..adapters.c2600_mb_2fe import C2600_MB_2FE - import logging +from ..adapters.c2600_mb_1e import C2600_MB_1E +from ..adapters.c2600_mb_1fe import C2600_MB_1FE +from ..adapters.c2600_mb_2e import C2600_MB_2E +from ..adapters.c2600_mb_2fe import C2600_MB_2FE +from .router import Router + log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nodes/c2691.py b/gns3server/compute/dynamips/nodes/c2691.py index c28d1c161..94a6bc499 100644 --- a/gns3server/compute/dynamips/nodes/c2691.py +++ b/gns3server/compute/dynamips/nodes/c2691.py @@ -20,11 +20,11 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L387 """ import asyncio -from .router import Router +import logging + from ..adapters.gt96100_fe import GT96100_FE from ..dynamips_error import DynamipsError - -import logging +from .router import Router log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nodes/c3600.py b/gns3server/compute/dynamips/nodes/c3600.py index d4d5f7235..87f4bc55f 100644 --- a/gns3server/compute/dynamips/nodes/c3600.py +++ b/gns3server/compute/dynamips/nodes/c3600.py @@ -20,11 +20,11 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L366 """ import asyncio -from .router import Router -from ..adapters.leopard_2fe import Leopard_2FE - import logging +from ..adapters.leopard_2fe import Leopard_2FE +from .router import Router + log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nodes/c3725.py b/gns3server/compute/dynamips/nodes/c3725.py index 3f9c22e1d..73f73831e 100644 --- a/gns3server/compute/dynamips/nodes/c3725.py +++ b/gns3server/compute/dynamips/nodes/c3725.py @@ -20,11 +20,11 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L346 """ import asyncio -from .router import Router +import logging + from ..adapters.gt96100_fe import GT96100_FE from ..dynamips_error import DynamipsError - -import logging +from .router import Router log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nodes/c3745.py b/gns3server/compute/dynamips/nodes/c3745.py index 36eac087d..74ed2d1b7 100644 --- a/gns3server/compute/dynamips/nodes/c3745.py +++ b/gns3server/compute/dynamips/nodes/c3745.py @@ -20,11 +20,11 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L326 """ import asyncio -from .router import Router +import logging + from ..adapters.gt96100_fe import GT96100_FE from ..dynamips_error import DynamipsError - -import logging +from .router import Router log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nodes/c7200.py b/gns3server/compute/dynamips/nodes/c7200.py index 98541b87f..3cf37b44c 100644 --- a/gns3server/compute/dynamips/nodes/c7200.py +++ b/gns3server/compute/dynamips/nodes/c7200.py @@ -20,13 +20,12 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L294 """ import asyncio +import logging -from .router import Router from ..adapters.c7200_io_fe import C7200_IO_FE from ..adapters.c7200_io_ge_e import C7200_IO_GE_E from ..dynamips_error import DynamipsError - -import logging +from .router import Router log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nodes/ethernet_hub.py b/gns3server/compute/dynamips/nodes/ethernet_hub.py index e8ea75062..e093fff2e 100644 --- a/gns3server/compute/dynamips/nodes/ethernet_hub.py +++ b/gns3server/compute/dynamips/nodes/ethernet_hub.py @@ -18,13 +18,13 @@ Hub object that uses the Bridge interface to create a hub with ports. """ -from .bridge import Bridge -from ..nios.nio_udp import NIOUDP -from ..dynamips_error import DynamipsError -from ...error import NodeError - import logging +from ...error import NodeError +from ..dynamips_error import DynamipsError +from ..nios.nio_udp import NIOUDP +from .bridge import Bridge + log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nodes/ethernet_switch.py b/gns3server/compute/dynamips/nodes/ethernet_switch.py index df3adf349..78af98783 100644 --- a/gns3server/compute/dynamips/nodes/ethernet_switch.py +++ b/gns3server/compute/dynamips/nodes/ethernet_switch.py @@ -20,17 +20,16 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L558 """ import asyncio +import logging + from gns3server.utils import parse_version -# from gns3server.utils.asyncio.embed_shell import EmbedShell, create_telnet_shell - - -from .device import Device -from ..nios.nio_udp import NIOUDP -from ..dynamips_error import DynamipsError from ...error import NodeError +from ..dynamips_error import DynamipsError +from ..nios.nio_udp import NIOUDP -import logging +# from gns3server.utils.asyncio.embed_shell import EmbedShell, create_telnet_shell +from .device import Device log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nodes/frame_relay_switch.py b/gns3server/compute/dynamips/nodes/frame_relay_switch.py index 5839e1cdf..5bed4fa17 100644 --- a/gns3server/compute/dynamips/nodes/frame_relay_switch.py +++ b/gns3server/compute/dynamips/nodes/frame_relay_switch.py @@ -20,13 +20,12 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L642 """ import asyncio - -from .device import Device -from ..nios.nio_udp import NIOUDP -from ..dynamips_error import DynamipsError - import logging +from ..dynamips_error import DynamipsError +from ..nios.nio_udp import NIOUDP +from .device import Device + log = logging.getLogger(__name__) diff --git a/gns3server/compute/dynamips/nodes/router.py b/gns3server/compute/dynamips/nodes/router.py index 8aabf6ddd..809fab8d9 100644 --- a/gns3server/compute/dynamips/nodes/router.py +++ b/gns3server/compute/dynamips/nodes/router.py @@ -20,26 +20,26 @@ http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L77 """ import asyncio -import time -import sys +import base64 +import binascii +import glob +import logging import os import re -import glob -import base64 import shutil -import binascii -import logging +import sys +import time log = logging.getLogger(__name__) -from ...base_node import BaseNode -from ..dynamips_error import DynamipsError - +from gns3server.utils.asyncio import monitor_process, wait_run_in_executor from gns3server.utils.file_watcher import FileWatcher -from gns3server.utils.asyncio import wait_run_in_executor, monitor_process from gns3server.utils.hostname import is_ios_hostname_valid from gns3server.utils.images import md5sum +from ...base_node import BaseNode +from ..dynamips_error import DynamipsError + class Router(BaseNode): """ diff --git a/gns3server/compute/iou/__init__.py b/gns3server/compute/iou/__init__.py index afe2766a2..b89381f06 100644 --- a/gns3server/compute/iou/__init__.py +++ b/gns3server/compute/iou/__init__.py @@ -18,15 +18,14 @@ IOU server module. """ -import os import asyncio +import logging +import os from ..base_manager import BaseManager from .iou_error import IOUError from .iou_vm import IOUVM -import logging - log = logging.getLogger(__name__) diff --git a/gns3server/compute/iou/iou_vm.py b/gns3server/compute/iou/iou_vm.py index b0f99a4c2..531f719a2 100644 --- a/gns3server/compute/iou/iou_vm.py +++ b/gns3server/compute/iou/iou_vm.py @@ -19,37 +19,37 @@ IOU VM management (creates command line, processes, files etc.) in order to run an IOU VM. """ -import os -import socket -import re import asyncio -import subprocess -import shutil -import configparser -import struct -import hashlib -import glob import binascii +import configparser import functools +import glob +import hashlib +import logging +import os +import re +import shutil +import socket +import struct +import subprocess +import sys -from .iou_error import IOUError -from ..adapters.ethernet_adapter import EthernetAdapter -from ..adapters.serial_adapter import SerialAdapter -from ..nios.nio_udp import NIOUDP -from ..base_node import BaseNode -from .utils.iou_import import nvram_import -from .utils.iou_export import nvram_export -from gns3server.compute.ubridge.ubridge_error import UbridgeError -from gns3server.utils.file_watcher import FileWatcher -from gns3server.utils.asyncio.ssh_server import AsyncioSSHServer -from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer -from gns3server.utils.hostname import is_ios_hostname_valid -from gns3server.utils.asyncio import locking import gns3server.utils.asyncio import gns3server.utils.images +from gns3server.compute.ubridge.ubridge_error import UbridgeError +from gns3server.utils.asyncio import locking +from gns3server.utils.asyncio.ssh_server import AsyncioSSHServer +from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer +from gns3server.utils.file_watcher import FileWatcher +from gns3server.utils.hostname import is_ios_hostname_valid -import logging -import sys +from ..adapters.ethernet_adapter import EthernetAdapter +from ..adapters.serial_adapter import SerialAdapter +from ..base_node import BaseNode +from ..nios.nio_udp import NIOUDP +from .iou_error import IOUError +from .utils.iou_export import nvram_export +from .utils.iou_import import nvram_import log = logging.getLogger(__name__) diff --git a/gns3server/compute/notification_manager.py b/gns3server/compute/notification_manager.py index f4eecf76c..5a4e5d603 100644 --- a/gns3server/compute/notification_manager.py +++ b/gns3server/compute/notification_manager.py @@ -17,6 +17,7 @@ import asyncio from contextlib import contextmanager + from gns3server.utils.notification_queue import NotificationQueue diff --git a/gns3server/compute/port_manager.py b/gns3server/compute/port_manager.py index ece70c3ab..df5293733 100644 --- a/gns3server/compute/port_manager.py +++ b/gns3server/compute/port_manager.py @@ -14,13 +14,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import socket import ipaddress -import threading -from fastapi import HTTPException, status -from gns3server.config import Config - import logging +import socket +import threading + +from fastapi import HTTPException, status + +from gns3server.config import Config log = logging.getLogger(__name__) diff --git a/gns3server/compute/project.py b/gns3server/compute/project.py index 8e6ef7648..3e4296110 100644 --- a/gns3server/compute/project.py +++ b/gns3server/compute/project.py @@ -14,24 +14,24 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import asyncio +import datetime +import hashlib +import logging import os import shutil -import magic -import asyncio -import hashlib -import datetime - from uuid import UUID, uuid4 + +import magic from fastapi import HTTPException, status -from gns3server.compute.compute_error import ComputeError, ComputeNotFoundError, ComputeForbiddenError -from .port_manager import PortManager -from .notification_manager import NotificationManager +from gns3server.compute.compute_error import ComputeError, ComputeForbiddenError, ComputeNotFoundError + from ..config import Config from ..utils.asyncio import wait_run_in_executor from ..utils.path import check_path_allowed, get_default_project_directory - -import logging +from .notification_manager import NotificationManager +from .port_manager import PortManager log = logging.getLogger(__name__) diff --git a/gns3server/compute/project_manager.py b/gns3server/compute/project_manager.py index 91f4757b4..1bcbae019 100644 --- a/gns3server/compute/project_manager.py +++ b/gns3server/compute/project_manager.py @@ -15,14 +15,15 @@ # along with this program. If not, see . -import psutil +import logging import platform -from .project import Project from uuid import UUID +import psutil + from gns3server.compute.compute_error import ComputeError, ComputeNotFoundError -import logging +from .project import Project log = logging.getLogger(__name__) diff --git a/gns3server/compute/qemu/__init__.py b/gns3server/compute/qemu/__init__.py index 5a01be047..fc4b3d062 100644 --- a/gns3server/compute/qemu/__init__.py +++ b/gns3server/compute/qemu/__init__.py @@ -19,25 +19,24 @@ Qemu server module. """ import asyncio +import logging import os import platform -import shutil -import shlex -import sys import re +import shlex +import shutil import subprocess +import sys from ...utils.asyncio import subprocess_check_output from ...utils.get_resource import get_resource from ..base_manager import BaseManager -from ..error import NodeError, ImageMissingError +from ..error import ImageMissingError, NodeError from .qemu_error import QemuError from .qemu_vm import QemuVM from .utils.guest_cid import get_next_guest_cid from .utils.ziputils import unpack_zip -import logging - log = logging.getLogger(__name__) diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index f5c6ae4ff..e6021a3f1 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -19,40 +19,40 @@ QEMU VM management (creates command line, processes, files etc.) in order to run a QEMU VM. """ -import sys +import asyncio +import json +import logging +import math import os import re -import math -import shutil -import struct -import asyncio -import socket -import gns3server -import subprocess -import time -import json import shlex +import shutil +import socket +import struct +import subprocess +import sys +import time +from pathlib import Path + import psutil -from pathlib import Path +import gns3server +from gns3server.schemas.compute.qemu_nodes import Qemu, QemuPlatform from gns3server.utils import parse_version -from gns3server.utils.asyncio import subprocess_check_output, cancellable_wait_run_in_executor +from gns3server.utils.asyncio import cancellable_wait_run_in_executor, subprocess_check_output + +from ...utils import int_to_macaddress, is_ipv6_enabled, macaddress_to_int +from ...utils.asyncio import monitor_process +from ...utils.hostname import is_rfc1123_hostname_valid +from ...utils.images import md5sum +from ..adapters.ethernet_adapter import EthernetAdapter +from ..base_node import BaseNode +from ..error import ImageMissingError, NodeError +from ..nios.nio_tap import NIOTAP +from ..nios.nio_udp import NIOUDP from .qemu_error import QemuError from .utils.qcow2 import Qcow2, Qcow2Error from .utils.ziputils import pack_zip, unpack_zip -from ..adapters.ethernet_adapter import EthernetAdapter -from ..error import NodeError, ImageMissingError -from ..nios.nio_udp import NIOUDP -from ..nios.nio_tap import NIOTAP -from ..base_node import BaseNode -from ...utils.asyncio import monitor_process -from ...utils.images import md5sum -from ...utils import macaddress_to_int, int_to_macaddress, is_ipv6_enabled -from ...utils.hostname import is_rfc1123_hostname_valid - -from gns3server.schemas.compute.qemu_nodes import Qemu, QemuPlatform - -import logging log = logging.getLogger(__name__) diff --git a/gns3server/compute/qemu/utils/guest_cid.py b/gns3server/compute/qemu/utils/guest_cid.py index b8b34b1d0..c61b46af1 100644 --- a/gns3server/compute/qemu/utils/guest_cid.py +++ b/gns3server/compute/qemu/utils/guest_cid.py @@ -14,10 +14,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from ..qemu_error import QemuError - import logging +from ..qemu_error import QemuError + log = logging.getLogger(__name__) diff --git a/gns3server/compute/qemu/utils/qcow2.py b/gns3server/compute/qemu/utils/qcow2.py index 9ea5fb40a..3b50c9fd7 100644 --- a/gns3server/compute/qemu/utils/qcow2.py +++ b/gns3server/compute/qemu/utils/qcow2.py @@ -15,9 +15,9 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import asyncio import json import os -import asyncio import struct diff --git a/gns3server/compute/qemu/utils/ziputils.py b/gns3server/compute/qemu/utils/ziputils.py index 165e5e7ce..4e229e0ea 100644 --- a/gns3server/compute/qemu/utils/ziputils.py +++ b/gns3server/compute/qemu/utils/ziputils.py @@ -16,8 +16,8 @@ # along with this program. If not, see . import os -import time import shutil +import time import zipfile diff --git a/gns3server/compute/ubridge/hypervisor.py b/gns3server/compute/ubridge/hypervisor.py index addc5cc9f..66dddd99a 100644 --- a/gns3server/compute/ubridge/hypervisor.py +++ b/gns3server/compute/ubridge/hypervisor.py @@ -18,20 +18,19 @@ Represents a uBridge hypervisor and starts/stops the associated uBridge process. """ +import asyncio +import logging import os +import re import socket import subprocess -import asyncio import tempfile -import re from gns3server.utils import parse_version -from gns3server.utils.asyncio import wait_for_process_termination -from gns3server.utils.asyncio import subprocess_check_output -from .ubridge_hypervisor import UBridgeHypervisor -from .ubridge_error import UbridgeError +from gns3server.utils.asyncio import subprocess_check_output, wait_for_process_termination -import logging +from .ubridge_error import UbridgeError +from .ubridge_hypervisor import UBridgeHypervisor log = logging.getLogger(__name__) diff --git a/gns3server/compute/ubridge/ubridge_hypervisor.py b/gns3server/compute/ubridge/ubridge_hypervisor.py index b03752b69..6256f0142 100644 --- a/gns3server/compute/ubridge/ubridge_hypervisor.py +++ b/gns3server/compute/ubridge/ubridge_hypervisor.py @@ -14,12 +14,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import asyncio +import logging import re import time -import logging -import asyncio from gns3server.utils.asyncio import locking + from .ubridge_error import UbridgeError log = logging.getLogger(__name__) diff --git a/gns3server/compute/virtualbox/__init__.py b/gns3server/compute/virtualbox/__init__.py index 3f3e92634..27313318f 100644 --- a/gns3server/compute/virtualbox/__init__.py +++ b/gns3server/compute/virtualbox/__init__.py @@ -18,19 +18,19 @@ VirtualBox server module. """ +import asyncio +import logging import os import re -import sys import shutil -import asyncio import subprocess -import logging +import sys log = logging.getLogger(__name__) from ..base_manager import BaseManager -from .virtualbox_vm import VirtualBoxVM from .virtualbox_error import VirtualBoxError +from .virtualbox_vm import VirtualBoxVM class VirtualBox(BaseManager): diff --git a/gns3server/compute/virtualbox/virtualbox_vm.py b/gns3server/compute/virtualbox/virtualbox_vm.py index e2e144e9f..729455d3d 100644 --- a/gns3server/compute/virtualbox/virtualbox_vm.py +++ b/gns3server/compute/virtualbox/virtualbox_vm.py @@ -18,28 +18,27 @@ VirtualBox VM instance. """ -import re -import os -import sys +import asyncio import json -import uuid +import logging +import os +import re import shlex import shutil -import asyncio +import sys import tempfile +import uuid import xml.etree.ElementTree as ET -from gns3server.utils import parse_version -from gns3server.utils.asyncio.ssh_server import AsyncioSSHServer -from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer -from gns3server.utils.asyncio.serial import asyncio_open_serial -from gns3server.utils.asyncio import locking -from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError -from gns3server.compute.nios.nio_udp import NIOUDP from gns3server.compute.adapters.ethernet_adapter import EthernetAdapter from gns3server.compute.base_node import BaseNode - -import logging +from gns3server.compute.nios.nio_udp import NIOUDP +from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError +from gns3server.utils import parse_version +from gns3server.utils.asyncio import locking +from gns3server.utils.asyncio.serial import asyncio_open_serial +from gns3server.utils.asyncio.ssh_server import AsyncioSSHServer +from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer log = logging.getLogger(__name__) diff --git a/gns3server/compute/vmware/__init__.py b/gns3server/compute/vmware/__init__.py index c814fc55f..7aa615927 100644 --- a/gns3server/compute/vmware/__init__.py +++ b/gns3server/compute/vmware/__init__.py @@ -18,27 +18,27 @@ VMware player/workstation server module. """ -import os -import sys -import re -import shutil import asyncio -import subprocess -import logging import codecs import ipaddress +import logging +import os +import re import shlex - +import shutil +import subprocess +import sys from collections import OrderedDict -from gns3server.utils.interfaces import interfaces -from gns3server.utils.asyncio import subprocess_check_output + from gns3server.utils import parse_version +from gns3server.utils.asyncio import subprocess_check_output +from gns3server.utils.interfaces import interfaces log = logging.getLogger(__name__) from gns3server.compute.base_manager import BaseManager -from gns3server.compute.vmware.vmware_vm import VMwareVM from gns3server.compute.vmware.vmware_error import VMwareError +from gns3server.compute.vmware.vmware_vm import VMwareVM class VMware(BaseManager): diff --git a/gns3server/compute/vmware/vmware_vm.py b/gns3server/compute/vmware/vmware_vm.py index b56b420a2..f4636f55a 100644 --- a/gns3server/compute/vmware/vmware_vm.py +++ b/gns3server/compute/vmware/vmware_vm.py @@ -18,25 +18,24 @@ VMware VM instance. """ -import sys -import os import asyncio -import tempfile +import logging +import os import platform +import sys +import tempfile +from collections import OrderedDict -from gns3server.utils.asyncio.ssh_server import AsyncioSSHServer -from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer -from gns3server.utils.asyncio.serial import asyncio_open_serial from gns3server.utils import parse_version from gns3server.utils.asyncio import locking -from collections import OrderedDict -from .vmware_error import VMwareError -from ..nios.nio_udp import NIOUDP +from gns3server.utils.asyncio.serial import asyncio_open_serial +from gns3server.utils.asyncio.ssh_server import AsyncioSSHServer +from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer + from ..adapters.ethernet_adapter import EthernetAdapter from ..base_node import BaseNode - - -import logging +from ..nios.nio_udp import NIOUDP +from .vmware_error import VMwareError log = logging.getLogger(__name__) diff --git a/gns3server/compute/vpcs/__init__.py b/gns3server/compute/vpcs/__init__.py index d9073a193..15ab54f3e 100644 --- a/gns3server/compute/vpcs/__init__.py +++ b/gns3server/compute/vpcs/__init__.py @@ -18,8 +18,8 @@ VPCS server module. """ -import os import asyncio +import os from ..base_manager import BaseManager from .vpcs_error import VPCSError diff --git a/gns3server/compute/vpcs/vpcs_vm.py b/gns3server/compute/vpcs/vpcs_vm.py index c72405543..af0acf72e 100644 --- a/gns3server/compute/vpcs/vpcs_vm.py +++ b/gns3server/compute/vpcs/vpcs_vm.py @@ -19,27 +19,23 @@ VPCS VM management (creates command line, processes, files etc.) in order to run a VPCS VM. """ +import asyncio +import logging import os -import sys +import re +import shutil +import signal import socket import subprocess -import signal -import re -import asyncio -import shutil +import sys -from gns3server.utils.asyncio import wait_for_process_termination -from gns3server.utils.asyncio import monitor_process -from gns3server.utils.asyncio import subprocess_check_output from gns3server.utils import parse_version +from gns3server.utils.asyncio import monitor_process, subprocess_check_output, wait_for_process_termination -from .vpcs_error import VPCSError from ..adapters.ethernet_adapter import EthernetAdapter -from ..nios.nio_udp import NIOUDP from ..base_node import BaseNode - - -import logging +from ..nios.nio_udp import NIOUDP +from .vpcs_error import VPCSError log = logging.getLogger(__name__) diff --git a/gns3server/config.py b/gns3server/config.py index ed1507f4e..5b588ac4b 100644 --- a/gns3server/config.py +++ b/gns3server/config.py @@ -18,19 +18,19 @@ Reads the configuration file and store the settings for the server. """ -import sys -import os -import shutil -import secrets import configparser - -from enum import Enum -from pydantic import ValidationError -from .schemas import ServerConfig -from .version import __version_info__ -from .utils.file_watcher import FileWatcher - import logging +import os +import secrets +import shutil +import sys +from enum import Enum + +from pydantic import ValidationError + +from .schemas import ServerConfig +from .utils.file_watcher import FileWatcher +from .version import __version_info__ log = logging.getLogger(__name__) diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py index 026cd2b6e..f2629065c 100644 --- a/gns3server/controller/__init__.py +++ b/gns3server/controller/__init__.py @@ -15,43 +15,42 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os -import sys -import uuid -import shutil import asyncio -import random import json +import os +import random +import shutil +import sys import threading +import uuid try: import importlib_resources except ImportError: from importlib import resources as importlib_resources -from watchdog.events import FileSystemEventHandler, DirDeletedEvent, FileDeletedEvent +import logging + +from watchdog.events import DirDeletedEvent, FileDeletedEvent, FileSystemEventHandler from watchdog.observers import Observer from ..config import Config -from ..utils import parse_version, md5sum -from ..utils.images import default_images_directory +from ..db.tasks import update_disk_checksums +from ..utils import md5sum, parse_version from ..utils.asyncio import wait_run_in_executor - -from .project import Project -from .node import Node +from ..utils.images import default_images_directory +from ..version import __version__ from .appliance import Appliance from .appliance_manager import ApplianceManager from .compute import Compute, ComputeError -from .notification import Notification -from .symbols import Symbols -from .topology import load_topology +from .controller_error import ControllerError, ControllerNotFoundError from .gns3vm import GNS3VM from .gns3vm.gns3_vm_error import GNS3VMError -from .controller_error import ControllerError, ControllerNotFoundError -from ..db.tasks import update_disk_checksums -from ..version import __version__ - -import logging +from .node import Node +from .notification import Notification +from .project import Project +from .symbols import Symbols +from .topology import load_topology log = logging.getLogger(__name__) diff --git a/gns3server/controller/appliance_manager.py b/gns3server/controller/appliance_manager.py index e99320202..fc6836116 100644 --- a/gns3server/controller/appliance_manager.py +++ b/gns3server/controller/appliance_manager.py @@ -15,37 +15,34 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os -import json import asyncio -import platformdirs - - +import json +import logging +import os from typing import List, Optional, Tuple -from aiohttp.client_exceptions import ClientError - from uuid import UUID + +import platformdirs +from aiohttp.client_exceptions import ClientError from pydantic import ValidationError from sqlalchemy.exc import SQLAlchemyError -from .appliance import Appliance +from gns3server import schemas +from gns3server.db.repositories.images import ImagesRepository +from gns3server.db.repositories.rbac import RbacRepository +from gns3server.db.repositories.templates import TemplatesRepository +from gns3server.schemas.controller.appliances import ApplianceModel +from gns3server.services.templates import TemplatesService +from gns3server.utils.images import default_images_directory + from ..config import Config from ..utils.asyncio import locking from ..utils.http_client import HTTPClient -from .controller_error import ControllerBadRequestError, ControllerNotFoundError, ControllerError -from .appliance_to_template import ApplianceToTemplate -from ..utils.images import InvalidImageError, write_image, read_image_info from ..utils.image_inventory import image_lock - -from gns3server import schemas -from gns3server.schemas.controller.appliances import ApplianceModel -from gns3server.utils.images import default_images_directory -from gns3server.db.repositories.images import ImagesRepository -from gns3server.db.repositories.templates import TemplatesRepository -from gns3server.services.templates import TemplatesService -from gns3server.db.repositories.rbac import RbacRepository - -import logging +from ..utils.images import InvalidImageError, read_image_info, write_image +from .appliance import Appliance +from .appliance_to_template import ApplianceToTemplate +from .controller_error import ControllerBadRequestError, ControllerError, ControllerNotFoundError log = logging.getLogger(__name__) diff --git a/gns3server/controller/appliance_to_template.py b/gns3server/controller/appliance_to_template.py index e78eaf56f..8f2f5e175 100644 --- a/gns3server/controller/appliance_to_template.py +++ b/gns3server/controller/appliance_to_template.py @@ -17,6 +17,7 @@ import logging + from .controller_error import ControllerError log = logging.getLogger(__name__) diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py index f42f2e3a0..1b3b65e38 100644 --- a/gns3server/controller/compute.py +++ b/gns3server/controller/compute.py @@ -15,14 +15,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import ipaddress -import aiohttp import asyncio -import socket -import json -import sys import io +import ipaddress +import json +import socket +import sys +import aiohttp from fastapi import HTTPException if sys.version_info >= (3, 11): @@ -30,23 +30,22 @@ if sys.version_info >= (3, 11): else: from async_timeout import timeout as asynctimeout -from ..utils import parse_version -from ..utils.asyncio import locking, async_iterable_to_stream +import logging + from ..controller.controller_error import ( - ControllerError, + ComputeConflictError, + ComputeError, ControllerBadRequestError, - ControllerNotFoundError, + ControllerError, ControllerForbiddenError, + ControllerNotFoundError, ControllerTimeoutError, ControllerUnauthorizedError, - ComputeError, - ComputeConflictError, ) +from ..utils import parse_version +from ..utils.asyncio import async_iterable_to_stream, locking from ..version import __version__, __version_info__ - -import logging - log = logging.getLogger(__name__) diff --git a/gns3server/controller/drawing.py b/gns3server/controller/drawing.py index daf072983..a67a9988a 100644 --- a/gns3server/controller/drawing.py +++ b/gns3server/controller/drawing.py @@ -15,19 +15,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import hashlib import base64 -import uuid -import re +import hashlib +import logging import os +import re +import uuid import xml.etree.ElementTree as ET - from gns3server.utils.picture import get_size - -import logging - log = logging.getLogger(__name__) diff --git a/gns3server/controller/export_project.py b/gns3server/controller/export_project.py index 080d3675c..c1c7aac7b 100644 --- a/gns3server/controller/export_project.py +++ b/gns3server/controller/export_project.py @@ -15,19 +15,18 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import asyncio +import json +import logging import os import sys -import json -import asyncio -import aiofiles -import zipfile import tempfile - -from .controller_error import ControllerError, ControllerNotFoundError, ControllerTimeoutError - +import zipfile from datetime import datetime -import logging +import aiofiles + +from .controller_error import ControllerError, ControllerNotFoundError, ControllerTimeoutError log = logging.getLogger(__name__) diff --git a/gns3server/controller/gns3vm/__init__.py b/gns3server/controller/gns3vm/__init__.py index a20a1e81d..3f69ee001 100644 --- a/gns3server/controller/gns3vm/__init__.py +++ b/gns3server/controller/gns3vm/__init__.py @@ -15,22 +15,21 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys -import copy import asyncio +import copy import ipaddress +import logging +import sys from ...utils.asyncio import locking -from .vmware_gns3_vm import VMwareGNS3VM -from .virtualbox_gns3_vm import VirtualBoxGNS3VM -from .hyperv_gns3_vm import HyperVGNS3VM -from .remote_gns3_vm import RemoteGNS3VM -from .gns3_vm_error import GNS3VMError from ...version import __version__ from ..compute import ComputeError from ..controller_error import ControllerError - -import logging +from .gns3_vm_error import GNS3VMError +from .hyperv_gns3_vm import HyperVGNS3VM +from .remote_gns3_vm import RemoteGNS3VM +from .virtualbox_gns3_vm import VirtualBoxGNS3VM +from .vmware_gns3_vm import VMwareGNS3VM log = logging.getLogger(__name__) diff --git a/gns3server/controller/gns3vm/base_gns3_vm.py b/gns3server/controller/gns3vm/base_gns3_vm.py index 4c5c85788..3abe8679c 100644 --- a/gns3server/controller/gns3vm/base_gns3_vm.py +++ b/gns3server/controller/gns3vm/base_gns3_vm.py @@ -15,10 +15,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import psutil - import logging +import psutil + log = logging.getLogger(__name__) diff --git a/gns3server/controller/gns3vm/hyperv_gns3_vm.py b/gns3server/controller/gns3vm/hyperv_gns3_vm.py index 7ec969223..6505e0349 100644 --- a/gns3server/controller/gns3vm/hyperv_gns3_vm.py +++ b/gns3server/controller/gns3vm/hyperv_gns3_vm.py @@ -15,11 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys -import logging import asyncio -import psutil import ipaddress +import logging +import sys + +import psutil from .base_gns3_vm import BaseGNS3VM from .gns3_vm_error import GNS3VMError diff --git a/gns3server/controller/gns3vm/remote_gns3_vm.py b/gns3server/controller/gns3vm/remote_gns3_vm.py index f71aa9e82..aa3ad4147 100644 --- a/gns3server/controller/gns3vm/remote_gns3_vm.py +++ b/gns3server/controller/gns3vm/remote_gns3_vm.py @@ -15,12 +15,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging + from .base_gns3_vm import BaseGNS3VM from .gns3_vm_error import GNS3VMError - -import logging - log = logging.getLogger(__name__) diff --git a/gns3server/controller/gns3vm/virtualbox_gns3_vm.py b/gns3server/controller/gns3vm/virtualbox_gns3_vm.py index 5fe733cd5..f4e328424 100644 --- a/gns3server/controller/gns3vm/virtualbox_gns3_vm.py +++ b/gns3server/controller/gns3vm/virtualbox_gns3_vm.py @@ -15,21 +15,22 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import re -import sys -import aiohttp -import logging import asyncio -import socket import ipaddress +import logging +import re +import socket +import sys + +import aiohttp -from .base_gns3_vm import BaseGNS3VM -from .gns3_vm_error import GNS3VMError from gns3server.utils import parse_version -from gns3server.utils.http_client import HTTPClient from gns3server.utils.asyncio import wait_run_in_executor +from gns3server.utils.http_client import HTTPClient from ...compute.virtualbox import VirtualBox, VirtualBoxError +from .base_gns3_vm import BaseGNS3VM +from .gns3_vm_error import GNS3VMError log = logging.getLogger(__name__) diff --git a/gns3server/controller/gns3vm/vmware_gns3_vm.py b/gns3server/controller/gns3vm/vmware_gns3_vm.py index b19c85ad9..ff0451463 100644 --- a/gns3server/controller/gns3vm/vmware_gns3_vm.py +++ b/gns3server/controller/gns3vm/vmware_gns3_vm.py @@ -15,9 +15,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os -import logging import asyncio +import logging +import os + import psutil from gns3server.compute.vmware import VMware, VMwareError diff --git a/gns3server/controller/import_project.py b/gns3server/controller/import_project.py index f26c747e2..e844d99e7 100644 --- a/gns3server/controller/import_project.py +++ b/gns3server/controller/import_project.py @@ -15,23 +15,23 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os -import sys -import json -import uuid -import shutil -import aiofiles import itertools -import tempfile +import json +import logging +import os +import shutil import stat +import sys +import tempfile +import uuid + +import aiofiles + import gns3server.utils.zipfile_zstd as zipfile_zstd +from ..utils.asyncio import aiozipstream, wait_run_in_executor from .controller_error import ControllerError from .topology import load_topology -from ..utils.asyncio import wait_run_in_executor -from ..utils.asyncio import aiozipstream - -import logging log = logging.getLogger(__name__) diff --git a/gns3server/controller/link.py b/gns3server/controller/link.py index c2ef20f7a..5cbe94506 100644 --- a/gns3server/controller/link.py +++ b/gns3server/controller/link.py @@ -15,21 +15,21 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import html +import logging import os import re import uuid -import html -from .controller_error import ControllerError, ControllerNotFoundError from gns3server.agent.web_wireshark.manager import WebWiresharkManager from gns3server.config import Config from gns3server.utils.packet_filter_validation import ( - validate_all_filters, - filter_inactive_filters, FilterValidationError, + filter_inactive_filters, + validate_all_filters, ) -import logging +from .controller_error import ControllerError, ControllerNotFoundError log = logging.getLogger(__name__) diff --git a/gns3server/controller/marker_replay.py b/gns3server/controller/marker_replay.py index f5996c159..716c5cf82 100644 --- a/gns3server/controller/marker_replay.py +++ b/gns3server/controller/marker_replay.py @@ -63,7 +63,7 @@ import tempfile import time from contextlib import asynccontextmanager -from .controller_error import ControllerError, ControllerNotFoundError, ControllerBadRequestError +from .controller_error import ControllerBadRequestError, ControllerError, ControllerNotFoundError log = logging.getLogger(__name__) diff --git a/gns3server/controller/node.py b/gns3server/controller/node.py index 6fb64045f..e96d4b704 100644 --- a/gns3server/controller/node.py +++ b/gns3server/controller/node.py @@ -16,21 +16,19 @@ # along with this program. If not, see . import asyncio -import html import copy -import uuid -import os - -from .controller_error import ControllerError, ControllerTimeoutError, ComputeError, ComputeConflictError -from .node_types import BUILTIN_NODE_TYPES -from .ports.port_factory import PortFactory, StandardPortFactory, DynamipsPortFactory -from ..utils.images import images_directories -from ..utils.application_id import is_iol_runner_environment -from ..utils import macaddress_to_int, int_to_macaddress -from ..config import Config - - +import html import logging +import os +import uuid + +from ..config import Config +from ..utils import int_to_macaddress, macaddress_to_int +from ..utils.application_id import is_iol_runner_environment +from ..utils.images import images_directories +from .controller_error import ComputeConflictError, ComputeError, ControllerError, ControllerTimeoutError +from .node_types import BUILTIN_NODE_TYPES +from .ports.port_factory import DynamipsPortFactory, PortFactory, StandardPortFactory log = logging.getLogger(__name__) diff --git a/gns3server/controller/notification.py b/gns3server/controller/notification.py index d3540a746..711fabcc2 100644 --- a/gns3server/controller/notification.py +++ b/gns3server/controller/notification.py @@ -19,6 +19,7 @@ import asyncio from contextlib import contextmanager from gns3server.utils.notification_queue import NotificationQueue + from .controller_error import ControllerError diff --git a/gns3server/controller/ports/port_factory.py b/gns3server/controller/ports/port_factory.py index 0568ef788..dd74ba086 100644 --- a/gns3server/controller/ports/port_factory.py +++ b/gns3server/controller/ports/port_factory.py @@ -15,18 +15,18 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging + from gns3server.controller.controller_error import ControllerError -from gns3server.utils import macaddress_to_int, int_to_macaddress +from gns3server.utils import int_to_macaddress, macaddress_to_int + from .atm_port import ATMPort +from .ethernet_port import EthernetPort +from .fastethernet_port import FastEthernetPort from .frame_relay_port import FrameRelayPort from .gigabitethernet_port import GigabitEthernetPort -from .fastethernet_port import FastEthernetPort -from .ethernet_port import EthernetPort -from .serial_port import SerialPort from .pos_port import POSPort - - -import logging +from .serial_port import SerialPort log = logging.getLogger(__name__) diff --git a/gns3server/controller/project.py b/gns3server/controller/project.py index 83b95b41f..04016ed27 100644 --- a/gns3server/controller/project.py +++ b/gns3server/controller/project.py @@ -15,43 +15,41 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import re -import os -import json -import uuid -import copy -import shutil -import time import asyncio -import aiofiles -import tempfile -import zipfile +import copy +import json +import logging +import os import pathlib - +import re +import shutil +import tempfile +import time +import uuid +import zipfile from uuid import UUID, uuid4 + +import aiofiles from fastapi import HTTPException, status -from .node import Node -from .compute import ComputeError -from .snapshot import Snapshot -from .drawing import Drawing -from .topology import project_to_topology, load_topology -from .udp_link import UDPLink -from .link import _UNSET -from ..config import Config -from ..utils.path import check_path_allowed, get_default_project_directory -from ..utils.application_id import get_next_application_id, is_iol_runner_environment -from ..utils.asyncio.pool import Pool -from ..utils.packet_filter_validation import validate_bpf_syntax -from ..utils.asyncio import locking -from ..utils.asyncio import aiozipstream -from ..utils.asyncio import wait_run_in_executor -from .export_project import export_project -from .import_project import import_project, update_snapshots, regenerate_topology_ids -from .controller_error import ControllerError, ControllerForbiddenError, ControllerNotFoundError from gns3server.agent.web_wireshark.manager import WebWiresharkManager -import logging +from ..config import Config +from ..utils.application_id import get_next_application_id, is_iol_runner_environment +from ..utils.asyncio import aiozipstream, locking, wait_run_in_executor +from ..utils.asyncio.pool import Pool +from ..utils.packet_filter_validation import validate_bpf_syntax +from ..utils.path import check_path_allowed, get_default_project_directory +from .compute import ComputeError +from .controller_error import ControllerError, ControllerForbiddenError, ControllerNotFoundError +from .drawing import Drawing +from .export_project import export_project +from .import_project import import_project, regenerate_topology_ids, update_snapshots +from .link import _UNSET +from .node import Node +from .snapshot import Snapshot +from .topology import load_topology, project_to_topology +from .udp_link import UDPLink log = logging.getLogger(__name__) diff --git a/gns3server/controller/snapshot.py b/gns3server/controller/snapshot.py index d203830f7..66d659b65 100644 --- a/gns3server/controller/snapshot.py +++ b/gns3server/controller/snapshot.py @@ -16,23 +16,22 @@ # along with this program. If not, see . +import logging import os -import uuid import shutil import tempfile -import aiofiles -import zipfile import time +import uuid +import zipfile from datetime import datetime, timezone +import aiofiles + +from ..utils.asyncio import aiozipstream, wait_run_in_executor from .controller_error import ControllerError -from ..utils.asyncio import wait_run_in_executor -from ..utils.asyncio import aiozipstream from .export_project import export_project from .import_project import import_project -import logging - log = logging.getLogger(__name__) diff --git a/gns3server/controller/symbols.py b/gns3server/controller/symbols.py index 2a7ee788d..69302d8bd 100644 --- a/gns3server/controller/symbols.py +++ b/gns3server/controller/symbols.py @@ -15,16 +15,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging import os import posixpath -from .symbol_themes import BUILTIN_SYMBOL_THEMES -from .controller_error import ControllerNotFoundError +from ..config import Config from ..utils.get_resource import get_resource from ..utils.picture import get_size -from ..config import Config - -import logging +from .controller_error import ControllerNotFoundError +from .symbol_themes import BUILTIN_SYMBOL_THEMES log = logging.getLogger(__name__) diff --git a/gns3server/controller/topology.py b/gns3server/controller/topology.py index 1e5dd3810..579b40c22 100644 --- a/gns3server/controller/topology.py +++ b/gns3server/controller/topology.py @@ -15,36 +15,35 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os +import glob import html import json -import uuid -import glob +import logging +import os import shutil +import uuid import zipfile -import pydantic - from typing import Optional -from ..version import __version__ -from ..utils.qt import qt_font_to_style -from ..compute.dynamips import PLATFORMS_DEFAULT_RAM -from .controller_error import ControllerError -from .compute import Compute -from .drawing import Drawing -from .node import Node -from .link import Link +import pydantic +from gns3server.schemas.compute.dynamips_nodes import DynamipsCreate +from gns3server.schemas.controller.topology import Topology from gns3server.utils.hostname import ( is_ios_hostname_valid, is_rfc1123_hostname_valid, - to_rfc1123_hostname, to_ios_hostname, + to_rfc1123_hostname, ) -from gns3server.schemas.controller.topology import Topology -from gns3server.schemas.compute.dynamips_nodes import DynamipsCreate -import logging +from ..compute.dynamips import PLATFORMS_DEFAULT_RAM +from ..utils.qt import qt_font_to_style +from ..version import __version__ +from .compute import Compute +from .controller_error import ControllerError +from .drawing import Drawing +from .link import Link +from .node import Node log = logging.getLogger(__name__) diff --git a/gns3server/controller/udp_link.py b/gns3server/controller/udp_link.py index f5fdcbb9c..1a543bcd3 100644 --- a/gns3server/controller/udp_link.py +++ b/gns3server/controller/udp_link.py @@ -19,10 +19,11 @@ import asyncio import logging +from gns3server.utils.packet_filter_validation import FilterValidationError, validate_bpf_syntax + from .controller_error import ControllerError, ControllerNotFoundError -from .link import Link, _UNSET +from .link import _UNSET, Link from .node_types import BUILTIN_NODE_TYPES -from gns3server.utils.packet_filter_validation import validate_bpf_syntax, FilterValidationError # Node types that can host a marker (have a uBridge bridge to attach the # `mark` filter to). Mirrors _get_filter_node in link.py, minus "nat" diff --git a/gns3server/core/tasks.py b/gns3server/core/tasks.py index 71d15bbb4..bb1f2edd6 100644 --- a/gns3server/core/tasks.py +++ b/gns3server/core/tasks.py @@ -16,21 +16,19 @@ # along with this program. If not, see . import asyncio - -from fastapi import FastAPI +import logging from contextlib import asynccontextmanager -from gns3server.controller import Controller -from gns3server.config import Config +from fastapi import FastAPI + from gns3server.compute import MODULES -from gns3server.compute.port_manager import PortManager from gns3server.compute.marker.marker_manager import MarkerManager -from gns3server.utils.http_client import HTTPClient -from gns3server.db.tasks import connect_to_db, get_computes, disconnect_from_db +from gns3server.compute.port_manager import PortManager +from gns3server.config import Config +from gns3server.controller import Controller +from gns3server.db.tasks import connect_to_db, disconnect_from_db, get_computes from gns3server.services.image_reconciliation import get_image_reconciliation_service - - -import logging +from gns3server.utils.http_client import HTTPClient log = logging.getLogger(__name__) diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py index cba709469..5d407db4a 100644 --- a/gns3server/crash_report.py +++ b/gns3server/crash_report.py @@ -23,17 +23,17 @@ except ImportError: # Sentry SDK is not installed with deb package in order to simplify packaging SENTRY_SDK_AVAILABLE = False -import os -import sys -import struct -import platform import locale +import logging +import os +import platform +import struct +import sys + import distro -from .version import __version__, __version_info__ from .config import Config - -import logging +from .version import __version__, __version_info__ log = logging.getLogger(__name__) diff --git a/gns3server/db/models/__init__.py b/gns3server/db/models/__init__.py index e5e234be4..cf6acc92f 100644 --- a/gns3server/db/models/__init__.py +++ b/gns3server/db/models/__init__.py @@ -15,18 +15,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from .base import Base from .acl import ACE -from .users import User, UserGroup -from .roles import Role -from .privileges import Privilege +from .api_keys import ApiKey +from .base import Base from .computes import Compute from .images import Image, ImageSyncJob -from .pools import Resource, ResourcePool from .llm_model_configs import LLMModelConfig -from .api_keys import ApiKey +from .pools import Resource, ResourcePool +from .privileges import Privilege +from .roles import Role from .templates import ( - Template, CloudTemplate, DockerTemplate, DynamipsTemplate, @@ -34,7 +32,9 @@ from .templates import ( EthernetSwitchTemplate, IOUTemplate, QemuTemplate, + Template, VirtualBoxTemplate, VMwareTemplate, VPCSTemplate, ) +from .users import User, UserGroup diff --git a/gns3server/db/models/acl.py b/gns3server/db/models/acl.py index fc75eedac..19e57d20f 100644 --- a/gns3server/db/models/acl.py +++ b/gns3server/db/models/acl.py @@ -15,12 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from sqlalchemy import Column, String, Boolean, ForeignKey, CheckConstraint +import logging + +from sqlalchemy import Boolean, CheckConstraint, Column, ForeignKey, String from sqlalchemy.orm import relationship -from .base import BaseTable, generate_uuid, GUID - -import logging +from .base import GUID, BaseTable, generate_uuid log = logging.getLogger(__name__) diff --git a/gns3server/db/models/api_keys.py b/gns3server/db/models/api_keys.py index ec320f9dd..b7bbb8c96 100644 --- a/gns3server/db/models/api_keys.py +++ b/gns3server/db/models/api_keys.py @@ -16,10 +16,10 @@ import uuid -from sqlalchemy import Column, String, Boolean, DateTime, ForeignKey, func +from sqlalchemy import Boolean, Column, DateTime, ForeignKey, String, func from sqlalchemy.orm import Mapped, mapped_column -from .base import BaseTable, GUID +from .base import GUID, BaseTable class ApiKey(BaseTable): diff --git a/gns3server/db/models/base.py b/gns3server/db/models/base.py index 5a185a437..522486e93 100644 --- a/gns3server/db/models/base.py +++ b/gns3server/db/models/base.py @@ -21,9 +21,9 @@ from typing import Optional from fastapi.encoders import jsonable_encoder from sqlalchemy import Column, DateTime, func, inspect -from sqlalchemy.types import TypeDecorator, CHAR, VARCHAR from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column +from sqlalchemy.types import CHAR, VARCHAR, TypeDecorator class Base(DeclarativeBase): diff --git a/gns3server/db/models/computes.py b/gns3server/db/models/computes.py index dff176cda..4561e9f82 100644 --- a/gns3server/db/models/computes.py +++ b/gns3server/db/models/computes.py @@ -15,9 +15,9 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from sqlalchemy import Column, String, Integer +from sqlalchemy import Column, Integer, String -from .base import BaseTable, GUID +from .base import GUID, BaseTable class Compute(BaseTable): diff --git a/gns3server/db/models/images.py b/gns3server/db/models/images.py index d5b323564..139f9054d 100644 --- a/gns3server/db/models/images.py +++ b/gns3server/db/models/images.py @@ -15,11 +15,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from sqlalchemy import Table, Column, String, ForeignKey, BigInteger, Integer, DateTime, JSON, Boolean +from sqlalchemy import JSON, BigInteger, Boolean, Column, DateTime, ForeignKey, Integer, String, Table from sqlalchemy.orm import Mapped, mapped_column, relationship -from .base import Base, BaseTable, GUID - +from .base import GUID, Base, BaseTable image_template_map = Table( "image_template_map", diff --git a/gns3server/db/models/llm_model_configs.py b/gns3server/db/models/llm_model_configs.py index 4a95719f4..a710948a4 100644 --- a/gns3server/db/models/llm_model_configs.py +++ b/gns3server/db/models/llm_model_configs.py @@ -15,12 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from sqlalchemy import Column, Boolean, ForeignKey, CheckConstraint, Index, Integer, String, text, JSON +import logging + +from sqlalchemy import JSON, Boolean, CheckConstraint, Column, ForeignKey, Index, Integer, String, text from sqlalchemy.orm import Mapped, mapped_column, relationship -from .base import BaseTable, generate_uuid, GUID - -import logging +from .base import GUID, BaseTable, generate_uuid log = logging.getLogger(__name__) diff --git a/gns3server/db/models/pools.py b/gns3server/db/models/pools.py index cd6616429..49ceaf5b5 100644 --- a/gns3server/db/models/pools.py +++ b/gns3server/db/models/pools.py @@ -15,14 +15,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging import uuid -from sqlalchemy import Table, Column, String, ForeignKey +from sqlalchemy import Column, ForeignKey, String, Table from sqlalchemy.orm import Mapped, mapped_column, relationship -from .base import Base, BaseTable, generate_uuid, GUID - -import logging +from .base import GUID, Base, BaseTable, generate_uuid log = logging.getLogger(__name__) diff --git a/gns3server/db/models/privileges.py b/gns3server/db/models/privileges.py index 49a904ed8..5bf99cd11 100644 --- a/gns3server/db/models/privileges.py +++ b/gns3server/db/models/privileges.py @@ -15,12 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from sqlalchemy import Table, Column, String, ForeignKey, event +import logging + +from sqlalchemy import Column, ForeignKey, String, Table, event from sqlalchemy.orm import relationship -from .base import Base, BaseTable, generate_uuid, GUID - -import logging +from .base import GUID, Base, BaseTable, generate_uuid log = logging.getLogger(__name__) diff --git a/gns3server/db/models/roles.py b/gns3server/db/models/roles.py index b56b6ef95..962070364 100644 --- a/gns3server/db/models/roles.py +++ b/gns3server/db/models/roles.py @@ -15,16 +15,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging import uuid -from sqlalchemy import Column, String, Boolean, event +from sqlalchemy import Boolean, Column, String, event from sqlalchemy.orm import Mapped, mapped_column, relationship -from .base import BaseTable, generate_uuid, GUID +from .base import GUID, BaseTable, generate_uuid from .privileges import privilege_role_map -import logging - log = logging.getLogger(__name__) diff --git a/gns3server/db/models/templates.py b/gns3server/db/models/templates.py index 0450be881..73d18e8b7 100644 --- a/gns3server/db/models/templates.py +++ b/gns3server/db/models/templates.py @@ -19,10 +19,10 @@ import uuid from typing import Optional -from sqlalchemy import Boolean, Column, String, Integer, Float, ForeignKey, JSON +from sqlalchemy import JSON, Boolean, Column, Float, ForeignKey, Integer, String from sqlalchemy.orm import Mapped, mapped_column, relationship -from .base import BaseTable, generate_uuid, GUID +from .base import GUID, BaseTable, generate_uuid from .images import image_template_map diff --git a/gns3server/db/models/users.py b/gns3server/db/models/users.py index a66d20025..6c74a720c 100644 --- a/gns3server/db/models/users.py +++ b/gns3server/db/models/users.py @@ -15,19 +15,18 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging +import uuid from datetime import datetime from typing import Optional -from sqlalchemy import Table, Boolean, Column, Integer, String, DateTime, ForeignKey, event +from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String, Table, event from sqlalchemy.orm import Mapped, mapped_column, relationship -from .base import Base, BaseTable, generate_uuid, GUID - from gns3server.config import Config from gns3server.services import auth_service -import logging -import uuid +from .base import GUID, Base, BaseTable, generate_uuid log = logging.getLogger(__name__) diff --git a/gns3server/db/repositories/api_keys.py b/gns3server/db/repositories/api_keys.py index 1cbfdf25b..2f53824cb 100644 --- a/gns3server/db/repositories/api_keys.py +++ b/gns3server/db/repositories/api_keys.py @@ -14,18 +14,19 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from uuid import UUID -from typing import Optional, List, cast +import logging from datetime import datetime, timezone -from sqlalchemy import select, update, delete, func +from typing import List, Optional, cast +from uuid import UUID + +from sqlalchemy import delete, func, select, update from sqlalchemy.engine import CursorResult from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload -from .base import BaseRepository import gns3server.db.models as models -import logging +from .base import BaseRepository log = logging.getLogger(__name__) diff --git a/gns3server/db/repositories/computes.py b/gns3server/db/repositories/computes.py index df9e5932d..3ccbc668b 100644 --- a/gns3server/db/repositories/computes.py +++ b/gns3server/db/repositories/computes.py @@ -15,18 +15,18 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from typing import List, Optional, Union, cast from uuid import UUID -from typing import Optional, List, Union -from sqlalchemy import select, update, delete -from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy.engine import CursorResult -from typing import cast -from .base import BaseRepository +from sqlalchemy import delete, select, update +from sqlalchemy.engine import CursorResult +from sqlalchemy.ext.asyncio import AsyncSession import gns3server.db.models as models from gns3server import schemas +from .base import BaseRepository + class ComputesRepository(BaseRepository): def __init__(self, db_session: AsyncSession) -> None: diff --git a/gns3server/db/repositories/images.py b/gns3server/db/repositories/images.py index 1d52295e7..dfdff06fb 100644 --- a/gns3server/db/repositories/images.py +++ b/gns3server/db/repositories/images.py @@ -15,23 +15,22 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os import asyncio +import logging +import os from datetime import datetime, timezone +from typing import Callable, List, Optional, cast -from typing import Optional, List, Callable, cast -from sqlalchemy import select, delete, update +from sqlalchemy import delete, select, update from sqlalchemy.engine import CursorResult -from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.exc import IntegrityError +from sqlalchemy.ext.asyncio import AsyncSession + +import gns3server.db.models as models from gns3server.utils.image_inventory import fingerprint, image_lock, normalized_path from .base import BaseRepository -import gns3server.db.models as models - -import logging - log = logging.getLogger(__name__) @@ -73,7 +72,7 @@ class ImagesRepository(BaseRepository): async def is_usable(self, image: models.Image) -> bool: """Validate a checksum candidate without trusting stale catalog/sidecar data.""" - from gns3server.utils.images import inspect_image_file, InvalidImageError + from gns3server.utils.images import InvalidImageError, inspect_image_file try: current = await asyncio.to_thread(fingerprint, image.path) diff --git a/gns3server/db/repositories/llm_model_configs.py b/gns3server/db/repositories/llm_model_configs.py index 6e59d1b3a..f17991f10 100644 --- a/gns3server/db/repositories/llm_model_configs.py +++ b/gns3server/db/repositories/llm_model_configs.py @@ -15,16 +15,17 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from uuid import UUID -from typing import Optional, List, Dict, Any, cast -from sqlalchemy import select, update, delete, and_ -from sqlalchemy.engine import CursorResult -from datetime import datetime - import logging +from datetime import datetime +from typing import Any, Dict, List, Optional, cast +from uuid import UUID + +from sqlalchemy import and_, delete, select, update +from sqlalchemy.engine import CursorResult + +import gns3server.db.models as models from .base import BaseRepository -import gns3server.db.models as models log = logging.getLogger(__name__) diff --git a/gns3server/db/repositories/pools.py b/gns3server/db/repositories/pools.py index a9144166e..d5ead9e05 100644 --- a/gns3server/db/repositories/pools.py +++ b/gns3server/db/repositories/pools.py @@ -15,19 +15,19 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging +from typing import List, Optional, Union, cast from uuid import UUID -from typing import Optional, List, Union, cast -from sqlalchemy import select, update, delete + +from sqlalchemy import delete, select, update from sqlalchemy.engine import CursorResult from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload -from .base import BaseRepository - import gns3server.db.models as models from gns3server import schemas -import logging +from .base import BaseRepository log = logging.getLogger(__name__) diff --git a/gns3server/db/repositories/rbac.py b/gns3server/db/repositories/rbac.py index 72cb1f954..4417e901d 100644 --- a/gns3server/db/repositories/rbac.py +++ b/gns3server/db/repositories/rbac.py @@ -15,20 +15,20 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from uuid import UUID +import logging +from typing import List, Optional, Union, cast from urllib.parse import urlparse -from typing import Optional, List, Union, cast -from sqlalchemy import select, update, delete +from uuid import UUID + +from sqlalchemy import delete, select, update from sqlalchemy.engine import CursorResult from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload -from .base import BaseRepository - import gns3server.db.models as models from gns3server import schemas -import logging +from .base import BaseRepository log = logging.getLogger(__name__) diff --git a/gns3server/db/repositories/templates.py b/gns3server/db/repositories/templates.py index b92dd7fd7..591a72be7 100644 --- a/gns3server/db/repositories/templates.py +++ b/gns3server/db/repositories/templates.py @@ -15,24 +15,24 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging import os import uuid -import logging - +from typing import List, Optional, Union, cast from uuid import UUID -from typing import List, Union, Optional, cast -from sqlalchemy import select, delete + +from sqlalchemy import delete, select from sqlalchemy.engine import CursorResult from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload from sqlalchemy.orm.session import make_transient -from .base import BaseRepository - import gns3server.db.models as models from gns3server import schemas -from gns3server.utils.image_inventory import image_lock from gns3server.controller.controller_error import ControllerNotFoundError +from gns3server.utils.image_inventory import image_lock + +from .base import BaseRepository log = logging.getLogger(__name__) diff --git a/gns3server/db/repositories/users.py b/gns3server/db/repositories/users.py index 556185272..9ab51eaa8 100644 --- a/gns3server/db/repositories/users.py +++ b/gns3server/db/repositories/users.py @@ -15,20 +15,20 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging +from typing import List, Optional, Union, cast from uuid import UUID -from typing import Optional, List, Union, cast -from sqlalchemy import select, update, delete, func + +from sqlalchemy import delete, func, select, update from sqlalchemy.engine import CursorResult from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload -from .base import BaseRepository - import gns3server.db.models as models from gns3server import schemas from gns3server.services import auth_service -import logging +from .base import BaseRepository log = logging.getLogger(__name__) diff --git a/gns3server/db/tasks.py b/gns3server/db/tasks.py index c00abb6e1..efa191762 100644 --- a/gns3server/db/tasks.py +++ b/gns3server/db/tasks.py @@ -15,30 +15,29 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging import os +from typing import List, Optional +import sqlalchemy as sa +from alembic import command, config +from alembic.runtime.migration import MigrationContext +from alembic.script import ScriptDirectory +from alembic.util.exc import CommandError from fastapi import FastAPI from pydantic import ValidationError -from typing import List, Optional from sqlalchemy import event from sqlalchemy.engine import Engine from sqlalchemy.exc import SQLAlchemyError -import sqlalchemy as sa -from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession -from alembic import command, config -from alembic.script import ScriptDirectory -from alembic.runtime.migration import MigrationContext -from alembic.util.exc import CommandError +from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine +from gns3server import schemas +from gns3server.config import Config from gns3server.db.repositories.computes import ComputesRepository from gns3server.db.repositories.images import ImagesRepository from gns3server.utils.images import read_image_info -from gns3server import schemas from .models import Base -from gns3server.config import Config - -import logging log = logging.getLogger(__name__) @@ -141,6 +140,7 @@ async def connect_to_db(app: FastAPI) -> None: # Ensure the additive schema before stamping the current head. def upgrade_inventory(connection): from alembic.operations import Operations + from gns3server.db_migrations.versions.d9e8a2b7c401_image_inventory_reconciliation import ( upgrade, ) @@ -230,6 +230,7 @@ async def get_user_llm_config_full(user_id: str, app: FastAPI) -> Optional[dict] or None if not found. """ from uuid import UUID + from gns3server.db.repositories.llm_model_configs import LLMModelConfigsRepository from gns3server.utils.encryption import decrypt, is_encrypted diff --git a/gns3server/db_migrations/env.py b/gns3server/db_migrations/env.py index f60fef2f6..d7f5ba73b 100644 --- a/gns3server/db_migrations/env.py +++ b/gns3server/db_migrations/env.py @@ -2,11 +2,10 @@ import asyncio import os from logging.config import fileConfig +from alembic import context from sqlalchemy import pool from sqlalchemy.ext.asyncio import async_engine_from_config -from alembic import context - # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config diff --git a/gns3server/db_migrations/versions/20260303_create_llm_model_configs_table.py b/gns3server/db_migrations/versions/20260303_create_llm_model_configs_table.py index 27bdd04ea..47732f3c9 100644 --- a/gns3server/db_migrations/versions/20260303_create_llm_model_configs_table.py +++ b/gns3server/db_migrations/versions/20260303_create_llm_model_configs_table.py @@ -6,8 +6,8 @@ Create Date: 2026-03-03 """ -from alembic import op import sqlalchemy as sa +from alembic import op from sqlalchemy import inspect # revision identifiers, used by Alembic. diff --git a/gns3server/db_migrations/versions/7ceeddd9c9a8_init.py b/gns3server/db_migrations/versions/7ceeddd9c9a8_init.py index 4c218cf5e..05570706e 100644 --- a/gns3server/db_migrations/versions/7ceeddd9c9a8_init.py +++ b/gns3server/db_migrations/versions/7ceeddd9c9a8_init.py @@ -6,9 +6,8 @@ Create Date: 2023-01-11 08:55:25.116126 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = "7ceeddd9c9a8" diff --git a/gns3server/db_migrations/versions/8f2a1c4e9d3b_add_extra_configs_to_docker_templates.py b/gns3server/db_migrations/versions/8f2a1c4e9d3b_add_extra_configs_to_docker_templates.py index 64d1489b4..d821cbe09 100644 --- a/gns3server/db_migrations/versions/8f2a1c4e9d3b_add_extra_configs_to_docker_templates.py +++ b/gns3server/db_migrations/versions/8f2a1c4e9d3b_add_extra_configs_to_docker_templates.py @@ -6,9 +6,8 @@ Create Date: 2026-08-14 10:00:00.000000 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = "8f2a1c4e9d3b" diff --git a/gns3server/db_migrations/versions/98083573d011_add_tags_field_to_templates.py b/gns3server/db_migrations/versions/98083573d011_add_tags_field_to_templates.py index 567aa3107..8744f9115 100644 --- a/gns3server/db_migrations/versions/98083573d011_add_tags_field_to_templates.py +++ b/gns3server/db_migrations/versions/98083573d011_add_tags_field_to_templates.py @@ -6,9 +6,8 @@ Create Date: 2026-02-23 18:23:59.857607 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = "98083573d011" diff --git a/gns3server/db_migrations/versions/9a5292aa4389_add_mac_address_field_in_docker_.py b/gns3server/db_migrations/versions/9a5292aa4389_add_mac_address_field_in_docker_.py index e85dc00f7..25d36675d 100644 --- a/gns3server/db_migrations/versions/9a5292aa4389_add_mac_address_field_in_docker_.py +++ b/gns3server/db_migrations/versions/9a5292aa4389_add_mac_address_field_in_docker_.py @@ -6,9 +6,8 @@ Create Date: 2024-09-18 17:52:53.429522 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = "9a5292aa4389" diff --git a/gns3server/db_migrations/versions/a8829e6c069b_add_llm_config_privileges.py b/gns3server/db_migrations/versions/a8829e6c069b_add_llm_config_privileges.py index fb146edd7..de87baced 100644 --- a/gns3server/db_migrations/versions/a8829e6c069b_add_llm_config_privileges.py +++ b/gns3server/db_migrations/versions/a8829e6c069b_add_llm_config_privileges.py @@ -6,10 +6,11 @@ Create Date: 2026-05-26 """ -from alembic import op -import sqlalchemy as sa from uuid import uuid4 +import sqlalchemy as sa +from alembic import op + # revision identifiers, used by Alembic. revision = "a8829e6c069b" down_revision = "aff810fc119a" diff --git a/gns3server/db_migrations/versions/aff810fc119a_add_token_version_to_users_table.py b/gns3server/db_migrations/versions/aff810fc119a_add_token_version_to_users_table.py index 8de44a283..edf5f997a 100644 --- a/gns3server/db_migrations/versions/aff810fc119a_add_token_version_to_users_table.py +++ b/gns3server/db_migrations/versions/aff810fc119a_add_token_version_to_users_table.py @@ -6,8 +6,8 @@ Create Date: 2026-04-06 19:49:12.155446 """ -from alembic import op import sqlalchemy as sa +from alembic import op # revision identifiers, used by Alembic. revision = "aff810fc119a" diff --git a/gns3server/db_migrations/versions/b3c7e2a91d4f_add_netmiko_device_type_to_templates.py b/gns3server/db_migrations/versions/b3c7e2a91d4f_add_netmiko_device_type_to_templates.py index 661b33d69..6a98aca5c 100644 --- a/gns3server/db_migrations/versions/b3c7e2a91d4f_add_netmiko_device_type_to_templates.py +++ b/gns3server/db_migrations/versions/b3c7e2a91d4f_add_netmiko_device_type_to_templates.py @@ -6,9 +6,8 @@ Create Date: 2026-08-16 10:00:00.000000 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = "b3c7e2a91d4f" diff --git a/gns3server/db_migrations/versions/c7e4a9f1d2b6_add_appliance_metadata_to_templates.py b/gns3server/db_migrations/versions/c7e4a9f1d2b6_add_appliance_metadata_to_templates.py index e0725102f..7bde600dc 100644 --- a/gns3server/db_migrations/versions/c7e4a9f1d2b6_add_appliance_metadata_to_templates.py +++ b/gns3server/db_migrations/versions/c7e4a9f1d2b6_add_appliance_metadata_to_templates.py @@ -6,9 +6,8 @@ Create Date: 2026-08-16 12:00:00.000000 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = "c7e4a9f1d2b6" diff --git a/gns3server/db_migrations/versions/d9e8a2b7c401_image_inventory_reconciliation.py b/gns3server/db_migrations/versions/d9e8a2b7c401_image_inventory_reconciliation.py index bb2ae487b..59a98d502 100644 --- a/gns3server/db_migrations/versions/d9e8a2b7c401_image_inventory_reconciliation.py +++ b/gns3server/db_migrations/versions/d9e8a2b7c401_image_inventory_reconciliation.py @@ -4,8 +4,8 @@ Revision ID: d9e8a2b7c401 Revises: c7e4a9f1d2b6 """ -from alembic import op import sqlalchemy as sa +from alembic import op revision = "d9e8a2b7c401" down_revision = "c7e4a9f1d2b6" diff --git a/gns3server/db_migrations/versions/ec4b7b198555_convert_pickletype_fields_to_json.py b/gns3server/db_migrations/versions/ec4b7b198555_convert_pickletype_fields_to_json.py index d25782c13..a42aa7212 100644 --- a/gns3server/db_migrations/versions/ec4b7b198555_convert_pickletype_fields_to_json.py +++ b/gns3server/db_migrations/versions/ec4b7b198555_convert_pickletype_fields_to_json.py @@ -6,8 +6,8 @@ Create Date: 2026-04-03 19:51:06.173013 """ -from alembic import op import sqlalchemy as sa +from alembic import op # revision identifiers, used by Alembic. revision = "ec4b7b198555" @@ -21,8 +21,8 @@ def convert_pickle_to_json(conn, table_name: str, column_name: str) -> None: Convert a PickleType column to JSON for all rows in a table. """ - import pickle import json + import pickle result = conn.execute(sa.text(f"SELECT template_id, {column_name} FROM {table_name}")) for row in result: @@ -49,8 +49,8 @@ def convert_json_to_pickle(conn, table_name: str, column_name: str) -> None: Convert a JSON column to PickleType for all rows in a table. """ - import pickle import json + import pickle result = conn.execute(sa.text(f"SELECT template_id, {column_name} FROM {table_name}")) for row in result: diff --git a/gns3server/db_migrations/versions/f0b0de2a9_add_api_keys_table.py b/gns3server/db_migrations/versions/f0b0de2a9_add_api_keys_table.py index a52dd05d6..50942c9ed 100644 --- a/gns3server/db_migrations/versions/f0b0de2a9_add_api_keys_table.py +++ b/gns3server/db_migrations/versions/f0b0de2a9_add_api_keys_table.py @@ -6,8 +6,9 @@ Create Date: 2026-06-11 10:00:00.000000 """ -from alembic import op import sqlalchemy as sa +from alembic import op + import gns3server.db.models.base as models # revision identifiers, used by Alembic. diff --git a/gns3server/logger.py b/gns3server/logger.py index 30d99bf39..50fe04017 100644 --- a/gns3server/logger.py +++ b/gns3server/logger.py @@ -17,12 +17,11 @@ """Provide a pretty logging on console""" +import gzip import logging -import sys import os import shutil -import gzip - +import sys from logging.handlers import RotatingFileHandler diff --git a/gns3server/main.py b/gns3server/main.py index 29a2073cf..5692fab79 100644 --- a/gns3server/main.py +++ b/gns3server/main.py @@ -25,14 +25,14 @@ Entry point of the server. It's support daemonize the process # if is not writetable the application crash. It's the user fault # because one day the user as used sudo to run an egg and break his # filesystem permissions, but it's a common mistake. -import gns3server.utils.get_resource - -import os -import sys -import asyncio import argparse +import asyncio import logging +import os import resource +import sys + +import gns3server.utils.get_resource def daemonize(): diff --git a/gns3server/schemas/__init__.py b/gns3server/schemas/__init__.py index 81e5fbc7e..34939c954 100644 --- a/gns3server/schemas/__init__.py +++ b/gns3server/schemas/__init__.py @@ -15,102 +15,107 @@ # along with this program. If not, see . # General schemas -from .config import ServerConfig from .common import ErrorMessage -from .version import Version - -# Controller schemas -from .controller.links import ( - LinkCreate, - LinkUpdate, - Link, - UDPPortInfo, - EthernetPortInfo, - LinkCapture, - MarkerCreate, - MarkerUpdate, - MarkerDefinitionCreate, -) +from .config import ServerConfig +from .controller.appliances import Appliance, ApplianceVersion, ApplianceVersionV8 from .controller.computes import ( + AutoIdlePC, + Compute, ComputeCreate, + ComputeDockerImage, ComputeUpdate, ComputeVirtualBoxVM, ComputeVMwareVM, - ComputeDockerImage, - AutoIdlePC, - Compute, ) -from .controller.templates import TemplateCreate, TemplateUpdate, TemplateUsage, Template -from .controller.images import Image, ImageType, ImageSyncRequest, ImageSyncJob -from .controller.appliances import ApplianceVersion, ApplianceVersionV8, Appliance from .controller.drawings import Drawing from .controller.gns3vm import GNS3VM -from .controller.nodes import NodeCreate, NodeUpdate, NodeDuplicate, NodeCapture, Node -from .controller.projects import ( - ProjectCreate, - ProjectUpdate, - ProjectDuplicate, - Project, - ProjectFile, - ProjectCompression, - NodeFile, +from .controller.images import Image, ImageSyncJob, ImageSyncRequest, ImageType + +# Controller schemas +from .controller.links import ( + EthernetPortInfo, + Link, + LinkCapture, + LinkCreate, + LinkUpdate, + MarkerCreate, + MarkerDefinitionCreate, + MarkerUpdate, + UDPPortInfo, ) +from .controller.nodes import Node, NodeCapture, NodeCreate, NodeDuplicate, NodeUpdate +from .controller.projects import ( + NodeFile, + Project, + ProjectCompression, + ProjectCreate, + ProjectDuplicate, + ProjectFile, + ProjectUpdate, +) +from .controller.templates import Template, TemplateCreate, TemplateUpdate, TemplateUsage from .controller.users import ( - UserCreate, - UserUpdate, + Credentials, LoggedInUserUpdate, User, - Credentials, + UserCreate, + UserGroup, UserGroupCreate, UserGroupUpdate, - UserGroup, + UserUpdate, ) +from .version import Version # Conditionally import AI-related schemas try: - from .controller.llm_model_configs import ( - LLMModelConfigData, - LLMModelConfigCreate, - LLMModelConfigUpdate, - LLMModelConfigResponse, - LLMModelConfigWithSource, - LLMModelConfigInheritedResponse, - LLMModelConfigListResponse, - ) from .controller.chat import ( - OpenAIToolCall, ChatRequest, ChatResponse, - OpenAIMessage, - ConversationHistory, ChatSession, + ConversationHistory, + OpenAIMessage, + OpenAIToolCall, RenameSession, ) + from .controller.llm_model_configs import ( + LLMModelConfigCreate, + LLMModelConfigData, + LLMModelConfigInheritedResponse, + LLMModelConfigListResponse, + LLMModelConfigResponse, + LLMModelConfigUpdate, + LLMModelConfigWithSource, + ) except ImportError: # AI schemas are not available (should not happen as they don't depend on external libs) pass -from .controller.rbac import RoleCreate, RoleUpdate, Role, Privilege, ACECreate, ACEUpdate, ACE -from .controller.settings import SettingsResponse, SettingsUpdate, SettingsUpdateResponse -from .controller.pools import Resource, ResourceCreate, ResourcePoolCreate, ResourcePoolUpdate, ResourcePool -from .controller.tokens import Token, ApiKeyCreate, RefreshTokenRequest -from .controller.snapshots import SnapshotCreate, Snapshot -from .controller.iou_license import IOULicense -from .controller.capabilities import Capabilities -from .controller.netmiko import NetmikoDeviceType, NetmikoDeviceTypeList +from .compute.atm_switch_nodes import ATMSwitch, ATMSwitchCreate, ATMSwitchUpdate +from .compute.cloud_nodes import Cloud, CloudCreate, CloudUpdate +from .compute.docker_nodes import Docker, DockerCreate, DockerUpdate +from .compute.dynamips_nodes import Dynamips, DynamipsCreate, DynamipsUpdate +from .compute.ethernet_hub_nodes import EthernetHub, EthernetHubCreate, EthernetHubUpdate +from .compute.ethernet_switch_nodes import EthernetSwitch, EthernetSwitchCreate, EthernetSwitchUpdate +from .compute.frame_relay_switch_nodes import FrameRelaySwitch, FrameRelaySwitchCreate, FrameRelaySwitchUpdate +from .compute.iou_nodes import IOU, IOUCreate, IOUStart, IOUUpdate +from .compute.nat_nodes import NAT, NATCreate, NATUpdate -# Controller template schemas -from .controller.templates.vpcs_templates import VPCSTemplate, VPCSTemplateUpdate +# Compute schemas +from .compute.nios import TAPNIO, UDPNIO, BatchNIOCreate, BatchNIOEntry, EthernetNIO, MarkerRebuild, MarkerToggle +from .compute.qemu_nodes import Qemu, QemuCreate, QemuUpdate +from .compute.virtualbox_nodes import VirtualBox, VirtualBoxCreate, VirtualBoxUpdate +from .compute.vmware_nodes import VMware, VMwareCreate, VMwareUpdate +from .compute.vpcs_nodes import VPCS, VPCSCreate, VPCSUpdate +from .controller.capabilities import Capabilities +from .controller.iou_license import IOULicense +from .controller.netmiko import NetmikoDeviceType, NetmikoDeviceTypeList +from .controller.pools import Resource, ResourceCreate, ResourcePool, ResourcePoolCreate, ResourcePoolUpdate +from .controller.rbac import ACE, ACECreate, ACEUpdate, Privilege, Role, RoleCreate, RoleUpdate +from .controller.settings import SettingsResponse, SettingsUpdate, SettingsUpdateResponse +from .controller.snapshots import Snapshot, SnapshotCreate from .controller.templates.cloud_templates import CloudTemplate, CloudTemplateUpdate -from .controller.templates.iou_templates import IOUTemplate, IOUTemplateUpdate from .controller.templates.docker_templates import DockerTemplate, DockerTemplateUpdate -from .controller.templates.ethernet_hub_templates import EthernetHubTemplate, EthernetHubTemplateUpdate -from .controller.templates.ethernet_switch_templates import EthernetSwitchTemplate, EthernetSwitchTemplateUpdate -from .controller.templates.virtualbox_templates import VirtualBoxTemplate, VirtualBoxTemplateUpdate -from .controller.templates.vmware_templates import VMwareTemplate, VMwareTemplateUpdate -from .controller.templates.qemu_templates import QemuTemplate, QemuTemplateUpdate from .controller.templates.dynamips_templates import ( - DynamipsTemplate, C1700DynamipsTemplate, C1700DynamipsTemplateUpdate, C2600DynamipsTemplate, @@ -125,23 +130,18 @@ from .controller.templates.dynamips_templates import ( C3745DynamipsTemplateUpdate, C7200DynamipsTemplate, C7200DynamipsTemplateUpdate, + DynamipsTemplate, ) +from .controller.templates.ethernet_hub_templates import EthernetHubTemplate, EthernetHubTemplateUpdate +from .controller.templates.ethernet_switch_templates import EthernetSwitchTemplate, EthernetSwitchTemplateUpdate +from .controller.templates.iou_templates import IOUTemplate, IOUTemplateUpdate +from .controller.templates.qemu_templates import QemuTemplate, QemuTemplateUpdate +from .controller.templates.virtualbox_templates import VirtualBoxTemplate, VirtualBoxTemplateUpdate +from .controller.templates.vmware_templates import VMwareTemplate, VMwareTemplateUpdate -# Compute schemas -from .compute.nios import UDPNIO, TAPNIO, EthernetNIO, MarkerToggle, MarkerRebuild, BatchNIOEntry, BatchNIOCreate -from .compute.atm_switch_nodes import ATMSwitchCreate, ATMSwitchUpdate, ATMSwitch -from .compute.cloud_nodes import CloudCreate, CloudUpdate, Cloud -from .compute.docker_nodes import DockerCreate, DockerUpdate, Docker -from .compute.dynamips_nodes import DynamipsCreate, DynamipsUpdate, Dynamips -from .compute.ethernet_hub_nodes import EthernetHubCreate, EthernetHubUpdate, EthernetHub -from .compute.ethernet_switch_nodes import EthernetSwitchCreate, EthernetSwitchUpdate, EthernetSwitch -from .compute.frame_relay_switch_nodes import FrameRelaySwitchCreate, FrameRelaySwitchUpdate, FrameRelaySwitch -from .compute.qemu_nodes import QemuCreate, QemuUpdate, Qemu -from .compute.iou_nodes import IOUCreate, IOUUpdate, IOUStart, IOU -from .compute.nat_nodes import NATCreate, NATUpdate, NAT -from .compute.vpcs_nodes import VPCSCreate, VPCSUpdate, VPCS -from .compute.vmware_nodes import VMwareCreate, VMwareUpdate, VMware -from .compute.virtualbox_nodes import VirtualBoxCreate, VirtualBoxUpdate, VirtualBox +# Controller template schemas +from .controller.templates.vpcs_templates import VPCSTemplate, VPCSTemplateUpdate +from .controller.tokens import ApiKeyCreate, RefreshTokenRequest, Token # Schemas for both controller and compute -from .qemu_disk_image import QemuDiskImageFormat, QemuDiskImageCreate, QemuDiskImageUpdate +from .qemu_disk_image import QemuDiskImageCreate, QemuDiskImageFormat, QemuDiskImageUpdate diff --git a/gns3server/schemas/common.py b/gns3server/schemas/common.py index 68ca0b861..3b700ee5e 100644 --- a/gns3server/schemas/common.py +++ b/gns3server/schemas/common.py @@ -14,9 +14,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field, field_validator -from typing import Optional from enum import Enum +from typing import Optional + +from pydantic import BaseModel, Field, field_validator class ErrorMessage(BaseModel): diff --git a/gns3server/schemas/compute/atm_switch_nodes.py b/gns3server/schemas/compute/atm_switch_nodes.py index 9d126bfe9..72572d5ff 100644 --- a/gns3server/schemas/compute/atm_switch_nodes.py +++ b/gns3server/schemas/compute/atm_switch_nodes.py @@ -14,10 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel from typing import Optional from uuid import UUID +from pydantic import BaseModel + from ..common import NodeStatus diff --git a/gns3server/schemas/compute/cloud_nodes.py b/gns3server/schemas/compute/cloud_nodes.py index 8fee188a1..5e8c0eb00 100644 --- a/gns3server/schemas/compute/cloud_nodes.py +++ b/gns3server/schemas/compute/cloud_nodes.py @@ -14,11 +14,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field -from typing import Optional, Union, List from enum import Enum +from typing import List, Optional, Union from uuid import UUID +from pydantic import BaseModel, Field + from ..common import NodeStatus diff --git a/gns3server/schemas/compute/docker_nodes.py b/gns3server/schemas/compute/docker_nodes.py index 1745b6d2e..228238fe9 100644 --- a/gns3server/schemas/compute/docker_nodes.py +++ b/gns3server/schemas/compute/docker_nodes.py @@ -14,11 +14,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field, field_validator -from typing import Optional, List +from typing import List, Optional from uuid import UUID -from ..common import NodeStatus, CustomAdapter, ConsoleType, AuxType, ExtraConfig +from pydantic import BaseModel, Field, field_validator + +from ..common import AuxType, ConsoleType, CustomAdapter, ExtraConfig, NodeStatus class DockerBase(BaseModel): diff --git a/gns3server/schemas/compute/dynamips_nodes.py b/gns3server/schemas/compute/dynamips_nodes.py index 6292b400b..efb04a2b6 100644 --- a/gns3server/schemas/compute/dynamips_nodes.py +++ b/gns3server/schemas/compute/dynamips_nodes.py @@ -15,11 +15,12 @@ # along with this program. If not, see . -from pydantic import BaseModel, Field -from typing import Optional, List from enum import Enum +from typing import List, Optional from uuid import UUID +from pydantic import BaseModel, Field + from ..common import NodeStatus diff --git a/gns3server/schemas/compute/ethernet_hub_nodes.py b/gns3server/schemas/compute/ethernet_hub_nodes.py index 866e57a38..07b2ae30d 100644 --- a/gns3server/schemas/compute/ethernet_hub_nodes.py +++ b/gns3server/schemas/compute/ethernet_hub_nodes.py @@ -14,10 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel -from typing import Optional, List +from typing import List, Optional from uuid import UUID +from pydantic import BaseModel + from ..common import NodeStatus diff --git a/gns3server/schemas/compute/ethernet_switch_nodes.py b/gns3server/schemas/compute/ethernet_switch_nodes.py index 16bd63b3e..2d3dbb154 100644 --- a/gns3server/schemas/compute/ethernet_switch_nodes.py +++ b/gns3server/schemas/compute/ethernet_switch_nodes.py @@ -14,10 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field, model_validator -from typing import Optional, List -from uuid import UUID from enum import Enum +from typing import List, Optional +from uuid import UUID + +from pydantic import BaseModel, Field, model_validator from ..common import NodeStatus diff --git a/gns3server/schemas/compute/frame_relay_switch_nodes.py b/gns3server/schemas/compute/frame_relay_switch_nodes.py index fbb86b553..b44decf3d 100644 --- a/gns3server/schemas/compute/frame_relay_switch_nodes.py +++ b/gns3server/schemas/compute/frame_relay_switch_nodes.py @@ -14,10 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel from typing import Optional from uuid import UUID +from pydantic import BaseModel + from ..common import NodeStatus diff --git a/gns3server/schemas/compute/iou_nodes.py b/gns3server/schemas/compute/iou_nodes.py index e51fa1a28..1b52bf29e 100644 --- a/gns3server/schemas/compute/iou_nodes.py +++ b/gns3server/schemas/compute/iou_nodes.py @@ -14,11 +14,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field from typing import Optional from uuid import UUID -from ..common import NodeStatus, ConsoleType +from pydantic import BaseModel, Field + +from ..common import ConsoleType, NodeStatus class IOUBase(BaseModel): diff --git a/gns3server/schemas/compute/nat_nodes.py b/gns3server/schemas/compute/nat_nodes.py index e3c569251..9e48918fd 100644 --- a/gns3server/schemas/compute/nat_nodes.py +++ b/gns3server/schemas/compute/nat_nodes.py @@ -14,11 +14,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field -from typing import Optional, Union, List from enum import Enum +from typing import List, Optional, Union from uuid import UUID +from pydantic import BaseModel, Field + from ..common import NodeStatus diff --git a/gns3server/schemas/compute/nios.py b/gns3server/schemas/compute/nios.py index f05d82737..38078812c 100644 --- a/gns3server/schemas/compute/nios.py +++ b/gns3server/schemas/compute/nios.py @@ -15,9 +15,10 @@ # along with this program. If not, see . -from pydantic import BaseModel, Field -from typing import Optional, List from enum import Enum +from typing import List, Optional + +from pydantic import BaseModel, Field class UDPNIOType(str, Enum): diff --git a/gns3server/schemas/compute/qemu_nodes.py b/gns3server/schemas/compute/qemu_nodes.py index 275ac92bb..aa72106e2 100644 --- a/gns3server/schemas/compute/qemu_nodes.py +++ b/gns3server/schemas/compute/qemu_nodes.py @@ -14,12 +14,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field -from typing import Optional, List from enum import Enum +from typing import List, Optional from uuid import UUID -from ..common import NodeStatus, CustomAdapter +from pydantic import BaseModel, Field + +from ..common import CustomAdapter, NodeStatus class QemuPlatform(str, Enum): diff --git a/gns3server/schemas/compute/virtualbox_nodes.py b/gns3server/schemas/compute/virtualbox_nodes.py index d05692ebc..ef5258f4e 100644 --- a/gns3server/schemas/compute/virtualbox_nodes.py +++ b/gns3server/schemas/compute/virtualbox_nodes.py @@ -14,12 +14,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field -from typing import Optional, List from enum import Enum +from typing import List, Optional from uuid import UUID -from ..common import NodeStatus, CustomAdapter +from pydantic import BaseModel, Field + +from ..common import CustomAdapter, NodeStatus class VirtualBoxConsoleType(str, Enum): diff --git a/gns3server/schemas/compute/vmware_nodes.py b/gns3server/schemas/compute/vmware_nodes.py index f838419a3..b518eb6d1 100644 --- a/gns3server/schemas/compute/vmware_nodes.py +++ b/gns3server/schemas/compute/vmware_nodes.py @@ -14,12 +14,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field -from typing import Optional, List from enum import Enum +from typing import List, Optional from uuid import UUID -from ..common import NodeStatus, CustomAdapter +from pydantic import BaseModel, Field + +from ..common import CustomAdapter, NodeStatus class VMwareConsoleType(str, Enum): diff --git a/gns3server/schemas/compute/vpcs_nodes.py b/gns3server/schemas/compute/vpcs_nodes.py index fda0634c4..c4a80cc08 100644 --- a/gns3server/schemas/compute/vpcs_nodes.py +++ b/gns3server/schemas/compute/vpcs_nodes.py @@ -14,11 +14,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field -from typing import Optional from enum import Enum +from typing import Optional from uuid import UUID +from pydantic import BaseModel, Field + from ..common import NodeStatus diff --git a/gns3server/schemas/config.py b/gns3server/schemas/config.py index c5becb3b5..f6c978911 100644 --- a/gns3server/schemas/config.py +++ b/gns3server/schemas/config.py @@ -15,11 +15,11 @@ # along with this program. If not, see . import socket - from enum import Enum -from pydantic import ConfigDict, BaseModel, Field, SecretStr, FilePath, DirectoryPath, field_validator, model_validator from typing import List, Optional +from pydantic import BaseModel, ConfigDict, DirectoryPath, Field, FilePath, SecretStr, field_validator, model_validator + class ControllerSettings(BaseModel): jwt_secret_key: Optional[str] = Field( diff --git a/gns3server/schemas/controller/appliances.py b/gns3server/schemas/controller/appliances.py index 3660067b8..16a9810ea 100644 --- a/gns3server/schemas/controller/appliances.py +++ b/gns3server/schemas/controller/appliances.py @@ -19,9 +19,10 @@ from enum import Enum from typing import Annotated, List, Literal, Optional, Union from uuid import UUID -from pydantic import AnyUrl, BaseModel, Discriminator, EmailStr, Field, Tag, model_validator -from ..common import ExtraConfig +from pydantic import AnyUrl, BaseModel, Discriminator, EmailStr, Field, Tag, model_validator + +from ..common import ExtraConfig # ============================================================================ # Shared Enums diff --git a/gns3server/schemas/controller/base.py b/gns3server/schemas/controller/base.py index e413dd479..6e4ac3fae 100644 --- a/gns3server/schemas/controller/base.py +++ b/gns3server/schemas/controller/base.py @@ -14,8 +14,9 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from typing import Optional from datetime import datetime +from typing import Optional + from pydantic import BaseModel diff --git a/gns3server/schemas/controller/capabilities.py b/gns3server/schemas/controller/capabilities.py index e54ab05dd..6e881ede7 100644 --- a/gns3server/schemas/controller/capabilities.py +++ b/gns3server/schemas/controller/capabilities.py @@ -15,9 +15,10 @@ # along with this program. If not, see . -from pydantic import BaseModel, Field from typing import List +from pydantic import BaseModel, Field + from .nodes import NodeType diff --git a/gns3server/schemas/controller/chat.py b/gns3server/schemas/controller/chat.py index 9289baf0b..93ef442f7 100644 --- a/gns3server/schemas/controller/chat.py +++ b/gns3server/schemas/controller/chat.py @@ -18,8 +18,9 @@ Chat API schemas for GNS3 Copilot integration. """ +from typing import Any, Dict, List, Literal, Optional + from pydantic import BaseModel, Field -from typing import Optional, List, Dict, Any, Literal class OpenAIToolCall(BaseModel): diff --git a/gns3server/schemas/controller/computes.py b/gns3server/schemas/controller/computes.py index f8612f43d..95eb09ecb 100644 --- a/gns3server/schemas/controller/computes.py +++ b/gns3server/schemas/controller/computes.py @@ -15,13 +15,13 @@ # along with this program. If not, see . import uuid - -from pydantic import ConfigDict, BaseModel, Field, SecretStr, field_validator, model_validator -from typing import List, Optional, Union, Any from enum import Enum +from typing import Any, List, Optional, Union + +from pydantic import BaseModel, ConfigDict, Field, SecretStr, field_validator, model_validator -from .nodes import NodeType from .base import DateTimeModelMixin +from .nodes import NodeType class Protocol(str, Enum): diff --git a/gns3server/schemas/controller/drawings.py b/gns3server/schemas/controller/drawings.py index f06727279..036829503 100644 --- a/gns3server/schemas/controller/drawings.py +++ b/gns3server/schemas/controller/drawings.py @@ -14,10 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field from typing import Optional from uuid import UUID +from pydantic import BaseModel, Field + class Drawing(BaseModel): """ diff --git a/gns3server/schemas/controller/gns3vm.py b/gns3server/schemas/controller/gns3vm.py index 9ea8e9aa3..71a975d43 100644 --- a/gns3server/schemas/controller/gns3vm.py +++ b/gns3server/schemas/controller/gns3vm.py @@ -14,9 +14,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field -from typing import Optional from enum import Enum +from typing import Optional + +from pydantic import BaseModel, Field class WhenExit(str, Enum): diff --git a/gns3server/schemas/controller/images.py b/gns3server/schemas/controller/images.py index d2569fd26..ed1e98ec9 100644 --- a/gns3server/schemas/controller/images.py +++ b/gns3server/schemas/controller/images.py @@ -14,10 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import ConfigDict, BaseModel, Field -from enum import Enum from datetime import datetime -from typing import Optional, Literal +from enum import Enum +from typing import Literal, Optional + +from pydantic import BaseModel, ConfigDict, Field from .base import DateTimeModelMixin diff --git a/gns3server/schemas/controller/labels.py b/gns3server/schemas/controller/labels.py index 2eb770265..0cfdc0c9c 100644 --- a/gns3server/schemas/controller/labels.py +++ b/gns3server/schemas/controller/labels.py @@ -14,9 +14,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field from typing import Optional, Union +from pydantic import BaseModel, Field + class Label(BaseModel): """ diff --git a/gns3server/schemas/controller/links.py b/gns3server/schemas/controller/links.py index 24c9f00e9..5dd8f1752 100644 --- a/gns3server/schemas/controller/links.py +++ b/gns3server/schemas/controller/links.py @@ -14,11 +14,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field, field_validator -from typing import List, Optional, Tuple from enum import Enum +from typing import List, Optional, Tuple from uuid import UUID, uuid4 +from pydantic import BaseModel, Field, field_validator + from .labels import Label diff --git a/gns3server/schemas/controller/llm_model_configs.py b/gns3server/schemas/controller/llm_model_configs.py index d5de5ee0b..78381d6d8 100644 --- a/gns3server/schemas/controller/llm_model_configs.py +++ b/gns3server/schemas/controller/llm_model_configs.py @@ -14,12 +14,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from typing import Optional, Literal, Union -from pydantic import BaseModel, Field, ConfigDict, field_validator +from typing import Literal, Optional, Union from uuid import UUID -from .base import DateTimeModelMixin +from pydantic import BaseModel, ConfigDict, Field, field_validator +from .base import DateTimeModelMixin # Valid model types ModelType = Literal["text", "vision", "stt", "tts", "multimodal", "embedding", "reranking", "other"] diff --git a/gns3server/schemas/controller/netmiko.py b/gns3server/schemas/controller/netmiko.py index 00eb6e5a4..2f4b3c284 100644 --- a/gns3server/schemas/controller/netmiko.py +++ b/gns3server/schemas/controller/netmiko.py @@ -15,9 +15,10 @@ # along with this program. If not, see . -from pydantic import BaseModel, Field from typing import List +from pydantic import BaseModel, Field + class NetmikoDeviceType(BaseModel): """ diff --git a/gns3server/schemas/controller/nodes.py b/gns3server/schemas/controller/nodes.py index 9faf260d3..d4e9bb43d 100644 --- a/gns3server/schemas/controller/nodes.py +++ b/gns3server/schemas/controller/nodes.py @@ -14,13 +14,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field -from typing import List, Optional, Union from enum import Enum +from typing import List, Optional, Union from uuid import UUID, uuid4 +from pydantic import BaseModel, Field + +from ..common import ConsoleType, CustomAdapter, NodeStatus from .labels import Label -from ..common import ConsoleType, NodeStatus, CustomAdapter class NodeType(str, Enum): diff --git a/gns3server/schemas/controller/pools.py b/gns3server/schemas/controller/pools.py index d0d4f7957..f72c488d4 100644 --- a/gns3server/schemas/controller/pools.py +++ b/gns3server/schemas/controller/pools.py @@ -14,10 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from typing import Optional -from pydantic import ConfigDict, BaseModel, Field -from uuid import UUID from enum import Enum +from typing import Optional +from uuid import UUID + +from pydantic import BaseModel, ConfigDict, Field from .base import DateTimeModelMixin diff --git a/gns3server/schemas/controller/projects.py b/gns3server/schemas/controller/projects.py index e1210f99f..a7e3212b5 100644 --- a/gns3server/schemas/controller/projects.py +++ b/gns3server/schemas/controller/projects.py @@ -15,10 +15,11 @@ # along with this program. If not, see . -from pydantic import BaseModel, Field, HttpUrl +from enum import Enum from typing import List, Optional from uuid import UUID -from enum import Enum + +from pydantic import BaseModel, Field, HttpUrl class ProjectStatus(str, Enum): diff --git a/gns3server/schemas/controller/rbac.py b/gns3server/schemas/controller/rbac.py index 11e0c1d6e..15ec07cab 100644 --- a/gns3server/schemas/controller/rbac.py +++ b/gns3server/schemas/controller/rbac.py @@ -14,10 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from typing import Optional, List -from pydantic import ConfigDict, BaseModel, Field -from uuid import UUID from enum import Enum +from typing import List, Optional +from uuid import UUID + +from pydantic import BaseModel, ConfigDict, Field from .base import DateTimeModelMixin diff --git a/gns3server/schemas/controller/settings.py b/gns3server/schemas/controller/settings.py index 87b4ab2a5..aa457dc31 100644 --- a/gns3server/schemas/controller/settings.py +++ b/gns3server/schemas/controller/settings.py @@ -28,7 +28,7 @@ a secret leak at worst. from pathlib import Path from typing import List, Optional -from pydantic import ConfigDict, BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from ..config import ( BuiltinSymbolTheme, diff --git a/gns3server/schemas/controller/snapshots.py b/gns3server/schemas/controller/snapshots.py index 4bdd6e938..bf46f2bbe 100644 --- a/gns3server/schemas/controller/snapshots.py +++ b/gns3server/schemas/controller/snapshots.py @@ -15,10 +15,11 @@ # along with this program. If not, see . -from pydantic import BaseModel, Field from typing import Optional from uuid import UUID +from pydantic import BaseModel, Field + class SnapshotBase(BaseModel): """ diff --git a/gns3server/schemas/controller/templates/__init__.py b/gns3server/schemas/controller/templates/__init__.py index b71c64772..da207e528 100644 --- a/gns3server/schemas/controller/templates/__init__.py +++ b/gns3server/schemas/controller/templates/__init__.py @@ -14,13 +14,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import ConfigDict, BaseModel, Field -from typing import Optional, List from enum import Enum +from typing import List, Optional from uuid import UUID -from ..nodes import NodeType +from pydantic import BaseModel, ConfigDict, Field + from ..base import DateTimeModelMixin +from ..nodes import NodeType class Category(str, Enum): diff --git a/gns3server/schemas/controller/templates/cloud_templates.py b/gns3server/schemas/controller/templates/cloud_templates.py index e9ec0f6bf..8f7ac6c13 100644 --- a/gns3server/schemas/controller/templates/cloud_templates.py +++ b/gns3server/schemas/controller/templates/cloud_templates.py @@ -15,11 +15,13 @@ # along with this program. If not, see . -from . import Category, TemplateBase -from gns3server.schemas.compute.cloud_nodes import EthernetPort, TAPPort, UDPPort, CloudConsoleType +from typing import List, Optional, Union from pydantic import Field -from typing import Optional, Union, List + +from gns3server.schemas.compute.cloud_nodes import CloudConsoleType, EthernetPort, TAPPort, UDPPort + +from . import Category, TemplateBase class CloudTemplate(TemplateBase): diff --git a/gns3server/schemas/controller/templates/docker_templates.py b/gns3server/schemas/controller/templates/docker_templates.py index 4123630e8..a96c97397 100644 --- a/gns3server/schemas/controller/templates/docker_templates.py +++ b/gns3server/schemas/controller/templates/docker_templates.py @@ -15,11 +15,12 @@ # along with this program. If not, see . -from . import Category, TemplateBase -from ...common import ConsoleType, AuxType, CustomAdapter, ExtraConfig +from typing import List, Optional from pydantic import Field -from typing import Optional, List + +from ...common import AuxType, ConsoleType, CustomAdapter, ExtraConfig +from . import Category, TemplateBase class DockerTemplateBase(TemplateBase): diff --git a/gns3server/schemas/controller/templates/dynamips_templates.py b/gns3server/schemas/controller/templates/dynamips_templates.py index 69505051d..77e3f853a 100644 --- a/gns3server/schemas/controller/templates/dynamips_templates.py +++ b/gns3server/schemas/controller/templates/dynamips_templates.py @@ -14,20 +14,21 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from . import Category, TemplateBase - -from gns3server.schemas.compute.dynamips_nodes import ( - DynamipsConsoleType, - DynamipsPlatform, - DynamipsAdapters, - DynamipsWics, - DynamipsNPE, - DynamipsMidplane, -) +from enum import Enum +from typing import Optional from pydantic import Field -from typing import Optional -from enum import Enum + +from gns3server.schemas.compute.dynamips_nodes import ( + DynamipsAdapters, + DynamipsConsoleType, + DynamipsMidplane, + DynamipsNPE, + DynamipsPlatform, + DynamipsWics, +) + +from . import Category, TemplateBase class DynamipsTemplateBase(TemplateBase): diff --git a/gns3server/schemas/controller/templates/ethernet_hub_templates.py b/gns3server/schemas/controller/templates/ethernet_hub_templates.py index a5b675937..8e273bc40 100644 --- a/gns3server/schemas/controller/templates/ethernet_hub_templates.py +++ b/gns3server/schemas/controller/templates/ethernet_hub_templates.py @@ -14,12 +14,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from . import Category, TemplateBase -from gns3server.schemas.compute.ethernet_hub_nodes import EthernetHubPort +from typing import List, Optional from pydantic import Field -from typing import Optional, List +from gns3server.schemas.compute.ethernet_hub_nodes import EthernetHubPort + +from . import Category, TemplateBase DEFAULT_PORTS = [ EthernetHubPort(port_number=0, name="Ethernet0"), diff --git a/gns3server/schemas/controller/templates/ethernet_switch_templates.py b/gns3server/schemas/controller/templates/ethernet_switch_templates.py index 5e6f81f03..ddcaa05d5 100644 --- a/gns3server/schemas/controller/templates/ethernet_switch_templates.py +++ b/gns3server/schemas/controller/templates/ethernet_switch_templates.py @@ -15,12 +15,14 @@ # along with this program. If not, see . -from . import Category, TemplateBase -from gns3server.schemas.compute.ethernet_switch_nodes import EthernetSwitchPort +from enum import Enum +from typing import List, Optional from pydantic import Field -from typing import Optional, List -from enum import Enum + +from gns3server.schemas.compute.ethernet_switch_nodes import EthernetSwitchPort + +from . import Category, TemplateBase DEFAULT_PORTS = [ EthernetSwitchPort(port_number=0, name="Ethernet0", vlan=1, type="access", ethertype="0x8100"), diff --git a/gns3server/schemas/controller/templates/iou_templates.py b/gns3server/schemas/controller/templates/iou_templates.py index 36468d8aa..a67c6764a 100644 --- a/gns3server/schemas/controller/templates/iou_templates.py +++ b/gns3server/schemas/controller/templates/iou_templates.py @@ -15,11 +15,13 @@ # along with this program. If not, see . -from . import Category, TemplateBase -from gns3server.schemas.compute.iou_nodes import ConsoleType +from typing import Optional from pydantic import Field -from typing import Optional + +from gns3server.schemas.compute.iou_nodes import ConsoleType + +from . import Category, TemplateBase class IOUTemplateBase(TemplateBase): diff --git a/gns3server/schemas/controller/templates/qemu_templates.py b/gns3server/schemas/controller/templates/qemu_templates.py index 116dfc33c..e4f2421b5 100644 --- a/gns3server/schemas/controller/templates/qemu_templates.py +++ b/gns3server/schemas/controller/templates/qemu_templates.py @@ -15,20 +15,22 @@ # along with this program. If not, see . -from . import Category, TemplateBase -from gns3server.schemas.compute.qemu_nodes import ( - QemuConsoleType, - QemuPlatform, - QemuAdapterType, - QemuOnCloseAction, - QemuBootPriority, - QemuDiskInterfaceType, - QemuProcessPriority, - CustomAdapter, -) +from typing import List, Optional from pydantic import Field -from typing import Optional, List + +from gns3server.schemas.compute.qemu_nodes import ( + CustomAdapter, + QemuAdapterType, + QemuBootPriority, + QemuConsoleType, + QemuDiskInterfaceType, + QemuOnCloseAction, + QemuPlatform, + QemuProcessPriority, +) + +from . import Category, TemplateBase class QemuTemplate(TemplateBase): diff --git a/gns3server/schemas/controller/templates/virtualbox_templates.py b/gns3server/schemas/controller/templates/virtualbox_templates.py index b9d966ec1..577f8ddc6 100644 --- a/gns3server/schemas/controller/templates/virtualbox_templates.py +++ b/gns3server/schemas/controller/templates/virtualbox_templates.py @@ -14,16 +14,18 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from . import Category, TemplateBase -from gns3server.schemas.compute.virtualbox_nodes import ( - VirtualBoxConsoleType, - VirtualBoxAdapterType, - VirtualBoxOnCloseAction, - CustomAdapter, -) +from typing import List, Optional from pydantic import Field -from typing import Optional, List + +from gns3server.schemas.compute.virtualbox_nodes import ( + CustomAdapter, + VirtualBoxAdapterType, + VirtualBoxConsoleType, + VirtualBoxOnCloseAction, +) + +from . import Category, TemplateBase class VirtualBoxTemplateBase(TemplateBase): diff --git a/gns3server/schemas/controller/templates/vmware_templates.py b/gns3server/schemas/controller/templates/vmware_templates.py index 85d9dce96..4a0012489 100644 --- a/gns3server/schemas/controller/templates/vmware_templates.py +++ b/gns3server/schemas/controller/templates/vmware_templates.py @@ -15,16 +15,18 @@ # along with this program. If not, see . -from . import Category, TemplateBase -from gns3server.schemas.compute.vmware_nodes import ( - VMwareConsoleType, - VMwareAdapterType, - VMwareOnCloseAction, - CustomAdapter, -) +from typing import List, Optional from pydantic import Field -from typing import Optional, List + +from gns3server.schemas.compute.vmware_nodes import ( + CustomAdapter, + VMwareAdapterType, + VMwareConsoleType, + VMwareOnCloseAction, +) + +from . import Category, TemplateBase class VMwareTemplateBase(TemplateBase): diff --git a/gns3server/schemas/controller/templates/vpcs_templates.py b/gns3server/schemas/controller/templates/vpcs_templates.py index e9f6e0b4f..a9167afc1 100644 --- a/gns3server/schemas/controller/templates/vpcs_templates.py +++ b/gns3server/schemas/controller/templates/vpcs_templates.py @@ -15,11 +15,13 @@ # along with this program. If not, see . -from . import Category, TemplateBase -from gns3server.schemas.compute.vpcs_nodes import ConsoleType +from typing import Optional from pydantic import Field -from typing import Optional + +from gns3server.schemas.compute.vpcs_nodes import ConsoleType + +from . import Category, TemplateBase class VPCSTemplate(TemplateBase): diff --git a/gns3server/schemas/controller/tokens.py b/gns3server/schemas/controller/tokens.py index 2ac14dda6..c6bde5d0e 100644 --- a/gns3server/schemas/controller/tokens.py +++ b/gns3server/schemas/controller/tokens.py @@ -15,6 +15,7 @@ # along with this program. If not, see . from typing import Optional + from pydantic import BaseModel diff --git a/gns3server/schemas/controller/topology.py b/gns3server/schemas/controller/topology.py index 26ff78b3e..0c4f39489 100644 --- a/gns3server/schemas/controller/topology.py +++ b/gns3server/schemas/controller/topology.py @@ -19,18 +19,18 @@ # This file contains the validation for checking a .gns3 file # +from enum import Enum +from typing import List, Optional +from uuid import UUID + +from pydantic import BaseModel, Field + from .computes import Compute from .drawings import Drawing from .links import Link from .nodes import Node - from .projects import Supplier, Variable -from pydantic import BaseModel, Field -from typing import Optional, List -from enum import Enum -from uuid import UUID - class TopologyType(str, Enum): topology = "topology" diff --git a/gns3server/schemas/controller/users.py b/gns3server/schemas/controller/users.py index 8d8b90c13..44593ae31 100644 --- a/gns3server/schemas/controller/users.py +++ b/gns3server/schemas/controller/users.py @@ -16,9 +16,10 @@ from datetime import datetime from typing import Optional -from pydantic import ConfigDict, EmailStr, BaseModel, Field, SecretStr from uuid import UUID +from pydantic import BaseModel, ConfigDict, EmailStr, Field, SecretStr + from .base import DateTimeModelMixin diff --git a/gns3server/schemas/qemu_disk_image.py b/gns3server/schemas/qemu_disk_image.py index 1c0f596ad..9a3b591b9 100644 --- a/gns3server/schemas/qemu_disk_image.py +++ b/gns3server/schemas/qemu_disk_image.py @@ -14,9 +14,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field -from typing import Optional from enum import Enum +from typing import Optional + +from pydantic import BaseModel, Field class QemuDiskImageFormat(str, Enum): diff --git a/gns3server/schemas/version.py b/gns3server/schemas/version.py index db4b95ed5..e258bc6df 100644 --- a/gns3server/schemas/version.py +++ b/gns3server/schemas/version.py @@ -14,9 +14,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pydantic import BaseModel, Field from typing import Optional +from pydantic import BaseModel, Field + class Version(BaseModel): controller_host: Optional[str] = Field(None, description="Controller hostname or IP address") diff --git a/gns3server/server.py b/gns3server/server.py index 7d7eb3186..f9824caab 100644 --- a/gns3server/server.py +++ b/gns3server/server.py @@ -20,25 +20,25 @@ Start the program. Use main.py to load it. """ -import os -import datetime -import locale -import psutil -import sys import asyncio -import signal +import datetime import functools -import uvicorn +import locale +import logging +import os import secrets +import signal import string +import sys + +import psutil +import uvicorn +from pydantic import SecretStr, ValidationError -from gns3server.logger import init_logger -from gns3server.version import __version__ from gns3server.config import Config from gns3server.crash_report import CrashReport -from pydantic import ValidationError, SecretStr - -import logging +from gns3server.logger import init_logger +from gns3server.version import __version__ log = logging.getLogger(__name__) diff --git a/gns3server/services/__init__.py b/gns3server/services/__init__.py index 572a235a2..a1701f719 100644 --- a/gns3server/services/__init__.py +++ b/gns3server/services/__init__.py @@ -14,8 +14,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from .authentication import AuthService from .access_tickets import AccessTicketService +from .authentication import AuthService auth_service = AuthService() access_ticket_service = AccessTicketService() diff --git a/gns3server/services/authentication.py b/gns3server/services/authentication.py index c507c01a8..ecca18578 100644 --- a/gns3server/services/authentication.py +++ b/gns3server/services/authentication.py @@ -14,22 +14,22 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from joserfc import jwt -from joserfc.jwk import OctKey -from joserfc.errors import JoseError, BadSignatureError import base64 import json +import logging import time from datetime import datetime, timedelta, timezone -import bcrypt - from typing import Optional + +import bcrypt from fastapi import HTTPException, status -from gns3server.schemas.controller.tokens import TokenData -from gns3server.config import Config +from joserfc import jwt +from joserfc.errors import BadSignatureError, JoseError +from joserfc.jwk import OctKey from pydantic import ValidationError -import logging +from gns3server.config import Config +from gns3server.schemas.controller.tokens import TokenData log = logging.getLogger(__name__) diff --git a/gns3server/services/computes.py b/gns3server/services/computes.py index c3e3dad80..c8d2b33fe 100644 --- a/gns3server/services/computes.py +++ b/gns3server/services/computes.py @@ -15,19 +15,18 @@ # along with this program. If not, see . -from uuid import UUID from typing import List, Union +from uuid import UUID -from gns3server import schemas import gns3server.db.models as models - -from gns3server.db.repositories.computes import ComputesRepository +from gns3server import schemas from gns3server.controller import Controller from gns3server.controller.controller_error import ( ControllerBadRequestError, - ControllerNotFoundError, ControllerForbiddenError, + ControllerNotFoundError, ) +from gns3server.db.repositories.computes import ComputesRepository class ComputesService: diff --git a/gns3server/services/image_reconciliation.py b/gns3server/services/image_reconciliation.py index 2fa523872..6fac6bb3f 100644 --- a/gns3server/services/image_reconciliation.py +++ b/gns3server/services/image_reconciliation.py @@ -8,7 +8,7 @@ import threading import uuid from datetime import datetime, timezone -from sqlalchemy import select, update, delete +from sqlalchemy import delete, select, update from sqlalchemy.ext.asyncio import AsyncSession from watchdog.events import FileSystemEventHandler from watchdog.observers import Observer @@ -24,7 +24,7 @@ from gns3server.utils.image_inventory import ( image_lock, normalized_path, ) -from gns3server.utils.images import inspect_image_file, InvalidImageError, ImageChangedError +from gns3server.utils.images import ImageChangedError, InvalidImageError, inspect_image_file log = logging.getLogger(__name__) COUNTERS = ( diff --git a/gns3server/services/templates.py b/gns3server/services/templates.py index c4fd274ed..fc5377ff2 100644 --- a/gns3server/services/templates.py +++ b/gns3server/services/templates.py @@ -16,23 +16,22 @@ import os import uuid -import pydantic - -from uuid import UUID -from fastapi.encoders import jsonable_encoder from typing import List, Optional +from uuid import UUID +import pydantic +from fastapi.encoders import jsonable_encoder + +import gns3server.db.models as models from gns3server import schemas from gns3server.config import Config -import gns3server.db.models as models -from gns3server.db.repositories.templates import TemplatesRepository from gns3server.controller.controller_error import ( - ControllerError, ControllerBadRequestError, - ControllerNotFoundError, + ControllerError, ControllerForbiddenError, + ControllerNotFoundError, ) - +from gns3server.db.repositories.templates import TemplatesRepository TEMPLATE_TYPE_TO_SCHEMA: dict[str, type[pydantic.BaseModel]] = { "cloud": schemas.CloudTemplate, diff --git a/gns3server/utils/__init__.py b/gns3server/utils/__init__.py index 386095757..44c224ff7 100644 --- a/gns3server/utils/__init__.py +++ b/gns3server/utils/__init__.py @@ -16,14 +16,14 @@ # along with this program. If not, see . -import sys -import re -import shlex -import textwrap -import posixpath -import socket import errno import hashlib +import posixpath +import re +import shlex +import socket +import sys +import textwrap def force_unix_path(path): diff --git a/gns3server/utils/application_id.py b/gns3server/utils/application_id.py index 488fb70b8..b9241cf29 100644 --- a/gns3server/utils/application_id.py +++ b/gns3server/utils/application_id.py @@ -15,10 +15,10 @@ # along with this program. If not, see . # -from gns3server.controller.controller_error import ControllerError - import logging +from gns3server.controller.controller_error import ControllerError + log = logging.getLogger(__name__) # IOU draws from the lower half: uBridge's iol_bridge uses application_id + 512 diff --git a/gns3server/utils/asyncio/__init__.py b/gns3server/utils/asyncio/__init__.py index 345cd77a8..98b72c66b 100644 --- a/gns3server/utils/asyncio/__init__.py +++ b/gns3server/utils/asyncio/__init__.py @@ -15,12 +15,12 @@ # along with this program. If not, see . -import functools import asyncio -import sys -import os -import threading +import functools import inspect +import os +import sys +import threading async def wait_run_in_executor(func, *args, **kwargs): diff --git a/gns3server/utils/asyncio/aiozipstream.py b/gns3server/utils/asyncio/aiozipstream.py index b9a9d42c9..07770ed0e 100644 --- a/gns3server/utils/asyncio/aiozipstream.py +++ b/gns3server/utils/asyncio/aiozipstream.py @@ -22,16 +22,17 @@ Derived directly from zipfile.py and the zipstream project https://github.com/allanlei/python-zipstream """ +import asyncio import os -import sys import stat import struct +import sys import time import zipfile -import asyncio -import aiofiles from concurrent import futures +import aiofiles + structCentralDir = "<4s4B4HL2L5H2L" structEndArchive64 = "<4sQ2H2L4Q" structEndArchive = b"<4s4H2LH" diff --git a/gns3server/utils/asyncio/embed_shell.py b/gns3server/utils/asyncio/embed_shell.py index 7059c9e29..5f044222d 100644 --- a/gns3server/utils/asyncio/embed_shell.py +++ b/gns3server/utils/asyncio/embed_shell.py @@ -16,24 +16,24 @@ # along with this program. If not, see . -import sys import asyncio import inspect import io +import sys from prompt_toolkit import prompt -from prompt_toolkit.history import InMemoryHistory from prompt_toolkit.contrib.completers import WordCompleter from prompt_toolkit.enums import DEFAULT_BUFFER from prompt_toolkit.eventloop.base import EventLoop +from prompt_toolkit.history import InMemoryHistory +from prompt_toolkit.input import StdinInput from prompt_toolkit.interface import CommandLineInterface from prompt_toolkit.layout.screen import Size -from prompt_toolkit.shortcuts import create_prompt_application, create_asyncio_eventloop +from prompt_toolkit.shortcuts import create_asyncio_eventloop, create_prompt_application from prompt_toolkit.terminal.vt100_output import Vt100_Output -from prompt_toolkit.input import StdinInput -from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer, TelnetConnection from gns3server.utils.asyncio.input_stream import InputStream +from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer, TelnetConnection class EmbedShell: diff --git a/gns3server/utils/asyncio/input_stream.py b/gns3server/utils/asyncio/input_stream.py index 6a9c983c6..90a3398b5 100644 --- a/gns3server/utils/asyncio/input_stream.py +++ b/gns3server/utils/asyncio/input_stream.py @@ -5,11 +5,10 @@ Parser for VT100 input stream. # Copied from prompt_toolkit/terminal/vt100_input.py due to dependency on termios (which is not available on Windows) import re + import six - - -from prompt_toolkit.keys import Keys from prompt_toolkit.key_binding.input_processor import KeyPress +from prompt_toolkit.keys import Keys # __all__ = ( # 'InputStream', diff --git a/gns3server/utils/asyncio/pool.py b/gns3server/utils/asyncio/pool.py index 0b0b43c9f..659222f6d 100644 --- a/gns3server/utils/asyncio/pool.py +++ b/gns3server/utils/asyncio/pool.py @@ -15,8 +15,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys import asyncio +import sys class Pool: diff --git a/gns3server/utils/asyncio/raw_command_server.py b/gns3server/utils/asyncio/raw_command_server.py index 0b7102dc3..87e0dbb05 100644 --- a/gns3server/utils/asyncio/raw_command_server.py +++ b/gns3server/utils/asyncio/raw_command_server.py @@ -14,12 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import re -import copy import asyncio import asyncio.subprocess - +import copy import logging +import re log = logging.getLogger(__name__) diff --git a/gns3server/utils/asyncio/serial.py b/gns3server/utils/asyncio/serial.py index c142a2e38..8a20a0799 100644 --- a/gns3server/utils/asyncio/serial.py +++ b/gns3server/utils/asyncio/serial.py @@ -17,8 +17,8 @@ import asyncio -from gns3server.utils.asyncio import wait_for_file_creation from gns3server.compute.error import NodeError +from gns3server.utils.asyncio import wait_for_file_creation """ This module handle connection to unix socket diff --git a/gns3server/utils/cpu_percent.py b/gns3server/utils/cpu_percent.py index 016c633b6..3f2f701a5 100644 --- a/gns3server/utils/cpu_percent.py +++ b/gns3server/utils/cpu_percent.py @@ -14,9 +14,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import psutil import time +import psutil + class CpuPercent: """ diff --git a/gns3server/utils/encryption.py b/gns3server/utils/encryption.py index 38719a60e..0b0974859 100644 --- a/gns3server/utils/encryption.py +++ b/gns3server/utils/encryption.py @@ -19,9 +19,10 @@ Encryption utilities for sensitive data like API keys. Uses Fernet symmetric encryption. """ -import os import logging +import os from typing import Optional + from cryptography.fernet import Fernet log = logging.getLogger(__name__) diff --git a/gns3server/utils/file_watcher.py b/gns3server/utils/file_watcher.py index 508fda67d..d481b293c 100644 --- a/gns3server/utils/file_watcher.py +++ b/gns3server/utils/file_watcher.py @@ -15,11 +15,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import zlib import asyncio -import os - import logging +import os +import zlib log = logging.getLogger(__name__) diff --git a/gns3server/utils/http_client.py b/gns3server/utils/http_client.py index a6b032a82..62841e4ec 100644 --- a/gns3server/utils/http_client.py +++ b/gns3server/utils/http_client.py @@ -15,11 +15,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import aiohttp -from pydantic import SecretStr +import logging import socket -import logging +import aiohttp +from pydantic import SecretStr log = logging.getLogger(__name__) diff --git a/gns3server/utils/images.py b/gns3server/utils/images.py index d7483ec59..4f6e402bb 100644 --- a/gns3server/utils/images.py +++ b/gns3server/utils/images.py @@ -14,30 +14,31 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os -import hashlib -import stat -import aiofiles import asyncio +import hashlib +import os +import stat import tempfile -from gns3server.utils.image_inventory import fingerprint, stat_fingerprint, image_lock, publish_image, contained_path +import aiofiles + +from gns3server.utils.image_inventory import contained_path, fingerprint, image_lock, publish_image, stat_fingerprint try: import importlib_resources except ImportError: from importlib import resources as importlib_resources -from typing import List, AsyncGenerator -from ..config import Config -from . import force_unix_path +import logging from io import DEFAULT_BUFFER_SIZE +from typing import AsyncGenerator, List import gns3server.db.models as models from gns3server.db.repositories.images import ImagesRepository from gns3server.utils.asyncio import wait_run_in_executor -import logging +from ..config import Config +from . import force_unix_path log = logging.getLogger(__name__) diff --git a/gns3server/utils/interfaces.py b/gns3server/utils/interfaces.py index f48db2c8a..0585028c9 100644 --- a/gns3server/utils/interfaces.py +++ b/gns3server/utils/interfaces.py @@ -16,9 +16,10 @@ import os -import sys import socket import struct +import sys + import psutil from gns3server.compute.compute_error import ComputeError @@ -94,8 +95,8 @@ def get_windows_interfaces(): :returns: list of windows interfaces """ - import win32com.client import pywintypes + import win32com.client interfaces = [] try: diff --git a/gns3server/utils/notification_queue.py b/gns3server/utils/notification_queue.py index b7cf93759..4c0e0d6a4 100644 --- a/gns3server/utils/notification_queue.py +++ b/gns3server/utils/notification_queue.py @@ -17,14 +17,14 @@ import asyncio import json +import logging import time + import psutil from gns3server.utils.cpu_percent import CpuPercent from gns3server.utils.path import get_default_project_directory -import logging - log = logging.getLogger(__name__) diff --git a/gns3server/utils/packet_filter_validation.py b/gns3server/utils/packet_filter_validation.py index d20ac9f24..29febb2fb 100644 --- a/gns3server/utils/packet_filter_validation.py +++ b/gns3server/utils/packet_filter_validation.py @@ -4,7 +4,7 @@ Packet filter parameter validation utilities. import logging import subprocess -from typing import Dict, List, Any, Optional +from typing import Any, Dict, List, Optional log = logging.getLogger(__name__) diff --git a/gns3server/utils/path.py b/gns3server/utils/path.py index d567d065e..35d7cc142 100644 --- a/gns3server/utils/path.py +++ b/gns3server/utils/path.py @@ -16,9 +16,10 @@ # along with this program. If not, see . import os - from pathlib import Path + from fastapi import HTTPException, status + from ..config import Config diff --git a/gns3server/utils/picture.py b/gns3server/utils/picture.py index 61df743e3..814183b05 100644 --- a/gns3server/utils/picture.py +++ b/gns3server/utils/picture.py @@ -15,8 +15,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import re import io +import re import struct from xml.etree.ElementTree import ElementTree, ParseError diff --git a/gns3server/utils/port_allocator.py b/gns3server/utils/port_allocator.py index f08954a97..015142a76 100644 --- a/gns3server/utils/port_allocator.py +++ b/gns3server/utils/port_allocator.py @@ -5,7 +5,6 @@ import hashlib - # Display/port allocation range (stable across process restarts) DISPLAY_RANGE = 10000 DISPLAY_MODULO = 10000 diff --git a/gns3server/utils/request_utils.py b/gns3server/utils/request_utils.py index 297a9e90b..27b8294b3 100644 --- a/gns3server/utils/request_utils.py +++ b/gns3server/utils/request_utils.py @@ -6,8 +6,8 @@ from ASGI scope dictionaries for logging and debugging purposes. """ import logging +from typing import Any, Dict, Optional from urllib.parse import parse_qs -from typing import Dict, Any, Optional log = logging.getLogger(__name__) diff --git a/gns3server/utils/uninstall_ai_features.py b/gns3server/utils/uninstall_ai_features.py index 8a1106bca..aa7f0ff5c 100644 --- a/gns3server/utils/uninstall_ai_features.py +++ b/gns3server/utils/uninstall_ai_features.py @@ -7,10 +7,10 @@ Usage: gns3server-uninstall-ai-features -y """ -import os -import sys -import subprocess import argparse +import os +import subprocess +import sys def _find_base_dir(): diff --git a/gns3server/utils/uuid_validator.py b/gns3server/utils/uuid_validator.py index 08524f4c9..6b099e180 100644 --- a/gns3server/utils/uuid_validator.py +++ b/gns3server/utils/uuid_validator.py @@ -6,7 +6,6 @@ import argparse import re - UUID_PATTERN = re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", re.IGNORECASE) diff --git a/gns3server/utils/vmnet.py b/gns3server/utils/vmnet.py index c9340fc8b..9fe5f39d5 100644 --- a/gns3server/utils/vmnet.py +++ b/gns3server/utils/vmnet.py @@ -15,12 +15,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys -import os -import ipaddress import argparse +import ipaddress +import os import shutil - +import sys from collections import OrderedDict if sys.platform.startswith("darwin"): diff --git a/gns3server/utils/zipfile_zstd/__init__.py b/gns3server/utils/zipfile_zstd/__init__.py index f43df1493..687a808b0 100644 --- a/gns3server/utils/zipfile_zstd/__init__.py +++ b/gns3server/utils/zipfile_zstd/__init__.py @@ -1,7 +1,7 @@ # NOTE: this patches the standard zipfile module -from . import _zipfile - from zipfile import * + +from . import _zipfile from ._zipfile import ( ZIP_ZSTANDARD, ZSTANDARD_VERSION, diff --git a/gns3server/utils/zipfile_zstd/_zipfile.py b/gns3server/utils/zipfile_zstd/_zipfile.py index e4bb61b03..2e26ba61e 100644 --- a/gns3server/utils/zipfile_zstd/_zipfile.py +++ b/gns3server/utils/zipfile_zstd/_zipfile.py @@ -1,8 +1,9 @@ -import zipfile as _zipfile_module -import zstandard as zstd import inspect +import zipfile as _zipfile_module from typing import Any +import zstandard as zstd + from ._patcher import patch zipfile: Any = _zipfile_module diff --git a/pyproject.toml b/pyproject.toml index 78dfc9ac1..68b4bff23 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -98,7 +98,6 @@ ignore = [ "E501", # 655 line-too-long "F401", # 300 unused-import "F841", # 32 unused-variable - "I001", # 441 unsorted-imports "PLW0603", # 21 global-statement "PLW2901", # 30 redefined-loop-name "RUF012", # 23 mutable-class-default diff --git a/scripts/extract_mermaid.py b/scripts/extract_mermaid.py index a134e3eed..82b47da11 100755 --- a/scripts/extract_mermaid.py +++ b/scripts/extract_mermaid.py @@ -27,11 +27,11 @@ Usage: python3 scripts/extract_mermaid.py docs/implemented/ my_svgs/ """ -import re -import os -import sys -import subprocess import argparse +import os +import re +import subprocess +import sys # Chrome binary path discovery PUPPETEER_CACHE = os.environ.get( diff --git a/scripts/publish_api_documentation.py b/scripts/publish_api_documentation.py index ab2e15704..1754d63bf 100644 --- a/scripts/publish_api_documentation.py +++ b/scripts/publish_api_documentation.py @@ -20,8 +20,8 @@ import json from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html -from gns3server.api.server import app +from gns3server.api.server import app if __name__ == "__main__": with open("../docs/openapi.json", "w") as fd: diff --git a/scripts/welcome.py b/scripts/welcome.py index 277a35138..9e9dc4c84 100644 --- a/scripts/welcome.py +++ b/scripts/welcome.py @@ -15,15 +15,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import configparser import locale -import re import os +import re +import subprocess import sys import time -import subprocess -import configparser -from json import loads as convert import urllib.request +from json import loads as convert + from dialog import Dialog, PythonDialogBug diff --git a/tests/agent/mcp/test_device_tools.py b/tests/agent/mcp/test_device_tools.py index 6a7c04169..07339cb5b 100644 --- a/tests/agent/mcp/test_device_tools.py +++ b/tests/agent/mcp/test_device_tools.py @@ -6,9 +6,9 @@ device_config_send / device_show_run / vpcs_config_set. """ import json +from unittest.mock import MagicMock, patch import pytest -from unittest.mock import MagicMock, patch VPCS_MOD = "gns3server.agent.gns3_copilot.tools_v2.vpcs_tools_netmiko" diff --git a/tests/agent/mcp/test_handlers.py b/tests/agent/mcp/test_handlers.py index 97938a35d..9752c4422 100644 --- a/tests/agent/mcp/test_handlers.py +++ b/tests/agent/mcp/test_handlers.py @@ -5,9 +5,9 @@ Tests that handlers correctly transform tool parameters into HTTP calls. """ import json +from unittest.mock import MagicMock, patch import pytest -from unittest.mock import MagicMock, patch def _mock_conn(json_result=None): @@ -222,6 +222,7 @@ class TestNode: def test_create_batch_preserves_submission_order(self, ctx): import time + from gns3server.agent.gns3_copilot.gns3_client.api_handlers import create_node_handler with patch(f"{AH}._get_connector") as m: @@ -249,6 +250,7 @@ class TestNode: def test_create_batch_default_names_created_sequentially(self, ctx): import threading import time + from gns3server.agent.gns3_copilot.gns3_client.api_handlers import create_node_handler def _run(nodes_param): @@ -502,6 +504,7 @@ class TestLink: def test_create_batch_preserves_submission_order(self, ctx): import time + from gns3server.agent.gns3_copilot.gns3_client.api_handlers import create_link_handler with patch(f"{AH}._get_connector") as m: diff --git a/tests/agent/test_gns3_client.py b/tests/agent/test_gns3_client.py index 36e57fd72..d04dc49a7 100644 --- a/tests/agent/test_gns3_client.py +++ b/tests/agent/test_gns3_client.py @@ -27,7 +27,6 @@ Tests for the shared GNS3 REST client layer (gns3_copilot.gns3_client): import pytest - # ── project_inventory ──────────────────────────────────────────────────── @@ -131,8 +130,8 @@ def test_device_ports_prefer_netmiko_field_over_tag(monkeypatch): the tag stays as fallback when the field is missing. """ pytest.importorskip("jwt", reason="ai-features extras not installed") - from gns3server.agent.gns3_copilot.utils import get_gns3_device_port from gns3server.agent.gns3_copilot import gns3_client + from gns3server.agent.gns3_copilot.utils import get_gns3_device_port class _FakeTopology: def _run(self, project_id=None, jwt_token=None, url=None): @@ -164,8 +163,8 @@ def test_device_ports_prefer_netmiko_field_over_tag(monkeypatch): def test_device_ports_error_without_any_device_type(monkeypatch): pytest.importorskip("jwt", reason="ai-features extras not installed") - from gns3server.agent.gns3_copilot.utils import get_gns3_device_port from gns3server.agent.gns3_copilot import gns3_client + from gns3server.agent.gns3_copilot.utils import get_gns3_device_port class _FakeTopology: def _run(self, project_id=None, jwt_token=None, url=None): @@ -193,8 +192,8 @@ def test_device_ports_inject_default_credentials(monkeypatch): keep inheriting from the group. """ pytest.importorskip("jwt", reason="ai-features extras not installed") - from gns3server.agent.gns3_copilot.utils import get_gns3_device_port from gns3server.agent.gns3_copilot import gns3_client + from gns3server.agent.gns3_copilot.utils import get_gns3_device_port class _FakeTopology: def _run(self, project_id=None, jwt_token=None, url=None): diff --git a/tests/agent/test_skills_device_topics.py b/tests/agent/test_skills_device_topics.py index 68d8371c5..6a1ca7acb 100644 --- a/tests/agent/test_skills_device_topics.py +++ b/tests/agent/test_skills_device_topics.py @@ -301,9 +301,9 @@ class TestReloadSkillsValidation: """ def test_invalid_injection_skill_is_dropped(self, tmp_path, monkeypatch): - from gns3server.config import Config from gns3server.agent.gns3_copilot.skills import registry from gns3server.agent.gns3_copilot.skills.manager import SkillsManager + from gns3server.config import Config # SkillsManager derives its local path from /skills injection_dir = tmp_path / "skills" / "injection" diff --git a/tests/api/routes/compute/test_capabilities.py b/tests/api/routes/compute/test_capabilities.py index 9a285c7bc..a401e8f24 100644 --- a/tests/api/routes/compute/test_capabilities.py +++ b/tests/api/routes/compute/test_capabilities.py @@ -16,14 +16,14 @@ import sys -import pytest -import psutil +import psutil +import pytest from fastapi import FastAPI, status from httpx import AsyncClient -from gns3server.version import __version__ from gns3server.utils.path import get_default_project_directory +from gns3server.version import __version__ pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/compute/test_cloud_nodes.py b/tests/api/routes/compute/test_cloud_nodes.py index 01a32ec36..0500356a8 100644 --- a/tests/api/routes/compute/test_cloud_nodes.py +++ b/tests/api/routes/compute/test_cloud_nodes.py @@ -16,13 +16,11 @@ import pytest import pytest_asyncio - from fastapi import FastAPI, status from httpx import AsyncClient -from tests.utils import asyncio_patch - from gns3server.compute.project import Project +from tests.utils import asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/compute/test_compute.py b/tests/api/routes/compute/test_compute.py index 1a9579b77..433b908c6 100644 --- a/tests/api/routes/compute/test_compute.py +++ b/tests/api/routes/compute/test_compute.py @@ -14,16 +14,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from unittest.mock import patch, MagicMock -import pytest +from unittest.mock import MagicMock, patch +import pytest from fastapi import FastAPI, status from httpx import AsyncClient -from gns3server.version import __version__ from gns3server.compute.project import Project from gns3server.config import Config from gns3server.schemas.config import ServerSettings +from gns3server.version import __version__ pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/compute/test_docker_nodes.py b/tests/api/routes/compute/test_docker_nodes.py index e16fb422c..40cb31679 100644 --- a/tests/api/routes/compute/test_docker_nodes.py +++ b/tests/api/routes/compute/test_docker_nodes.py @@ -14,17 +14,17 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from unittest.mock import MagicMock, patch + import pytest import pytest_asyncio - from fastapi import FastAPI, status from httpx import AsyncClient -from tests.utils import asyncio_patch, AsyncioMagicMock -from unittest.mock import patch, MagicMock from gns3server.compute.docker import Docker from gns3server.compute.docker.iol_docker_vm import IOLDockerVM from gns3server.compute.project import Project +from tests.utils import AsyncioMagicMock, asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/compute/test_dynamips_nodes.py b/tests/api/routes/compute/test_dynamips_nodes.py index c5d014ea6..60ea6acf6 100644 --- a/tests/api/routes/compute/test_dynamips_nodes.py +++ b/tests/api/routes/compute/test_dynamips_nodes.py @@ -14,12 +14,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest -import sys import os import stat - +import sys from unittest.mock import patch + +import pytest from fastapi import FastAPI, status from httpx import AsyncClient diff --git a/tests/api/routes/compute/test_ethernet_switch_nodes.py b/tests/api/routes/compute/test_ethernet_switch_nodes.py index cc046e3ef..7930b6bb4 100644 --- a/tests/api/routes/compute/test_ethernet_switch_nodes.py +++ b/tests/api/routes/compute/test_ethernet_switch_nodes.py @@ -14,15 +14,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from unittest.mock import MagicMock, call + import pytest import pytest_asyncio - from fastapi import FastAPI, status from httpx import AsyncClient -from tests.utils import asyncio_patch, AsyncioMagicMock -from unittest.mock import call, MagicMock from gns3server.compute.project import Project +from tests.utils import AsyncioMagicMock, asyncio_patch # The builtin Ethernet switch talks to uBridge (brctl/bridge modules) instead of # the Dynamips hypervisor. These are the seams we stub so the routes can be diff --git a/tests/api/routes/compute/test_images.py b/tests/api/routes/compute/test_images.py index 62209eea1..f1a3da75e 100644 --- a/tests/api/routes/compute/test_images.py +++ b/tests/api/routes/compute/test_images.py @@ -15,9 +15,9 @@ # along with this program. If not, see . import pytest - from fastapi import FastAPI, status from httpx import AsyncClient + from tests.utils import asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/compute/test_iou_nodes.py b/tests/api/routes/compute/test_iou_nodes.py index 65c2e56db..feebe2b87 100644 --- a/tests/api/routes/compute/test_iou_nodes.py +++ b/tests/api/routes/compute/test_iou_nodes.py @@ -14,18 +14,18 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest -import pytest_asyncio import os import stat import uuid - -from fastapi import FastAPI, status -from httpx import AsyncClient -from tests.utils import asyncio_patch from unittest.mock import patch +import pytest +import pytest_asyncio +from fastapi import FastAPI, status +from httpx import AsyncClient + from gns3server.compute.project import Project +from tests.utils import asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/compute/test_nat_nodes.py b/tests/api/routes/compute/test_nat_nodes.py index 0d40cd487..d6f404721 100644 --- a/tests/api/routes/compute/test_nat_nodes.py +++ b/tests/api/routes/compute/test_nat_nodes.py @@ -16,12 +16,11 @@ import pytest import pytest_asyncio - from fastapi import FastAPI, status from httpx import AsyncClient -from tests.utils import asyncio_patch from gns3server.compute.project import Project +from tests.utils import asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/compute/test_notifications.py b/tests/api/routes/compute/test_notifications.py index da8663e6c..b0636d99c 100644 --- a/tests/api/routes/compute/test_notifications.py +++ b/tests/api/routes/compute/test_notifications.py @@ -15,9 +15,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest import json +import pytest + from gns3server.compute.notification_manager import NotificationManager diff --git a/tests/api/routes/compute/test_projects.py b/tests/api/routes/compute/test_projects.py index 2b8637d5b..30866aaa6 100644 --- a/tests/api/routes/compute/test_projects.py +++ b/tests/api/routes/compute/test_projects.py @@ -14,17 +14,17 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest -import uuid import os - +import uuid from unittest.mock import patch -from tests.utils import asyncio_patch + +import pytest from fastapi import FastAPI, status from httpx import AsyncClient -from gns3server.compute.project_manager import ProjectManager from gns3server.compute.project import Project +from gns3server.compute.project_manager import ProjectManager +from tests.utils import asyncio_patch pytestmark = pytest.mark.asyncio @@ -208,6 +208,7 @@ class TestBatchNIOEdgeCases: async def test_dynamips_router_dispatch_to_slot_add_nio_binding(self): """_add_nio_binding dispatches Dynamips router to slot_add_nio_binding.""" from unittest.mock import AsyncMock, MagicMock + from gns3server.api.routes.compute.projects import _add_nio_binding node = MagicMock() @@ -222,6 +223,7 @@ class TestBatchNIOEdgeCases: async def test_dynamips_switch_dispatch_to_add_nio(self): """_add_nio_binding dispatches Dynamips switch to add_nio.""" from unittest.mock import AsyncMock, MagicMock + from gns3server.api.routes.compute.projects import _add_nio_binding node = MagicMock() @@ -239,8 +241,8 @@ class TestBatchNIOEdgeCases: Dynamips.create_nio is async (returns a coroutine) unlike the sync base version. The batch handler must await it. """ - import inspect import asyncio as _asyncio + import inspect class _FakeDynamips: async def create_nio(self, node, nio_settings): @@ -267,6 +269,7 @@ class TestBatchNIOEdgeCases: async def test_qemu_dispatch_to_adapter_add_nio_binding(self): """_add_nio_binding dispatches Qemu to adapter_add_nio_binding.""" from unittest.mock import AsyncMock, MagicMock + from gns3server.api.routes.compute.projects import _add_nio_binding node = MagicMock() @@ -281,6 +284,7 @@ class TestBatchNIOEdgeCases: async def test_iou_dispatch_to_adapter_add_nio_binding(self): """_add_nio_binding dispatches IOU to adapter_add_nio_binding(adapter, port, nio).""" from unittest.mock import AsyncMock, MagicMock + from gns3server.api.routes.compute.projects import _add_nio_binding node = MagicMock() @@ -300,6 +304,7 @@ class TestBatchNIOEdgeCases: cross-wired links (the last entry per node wins). """ from unittest.mock import AsyncMock, MagicMock + from gns3server.api.routes.compute.projects import ( _add_nio_binding, _get_existing_nio, @@ -326,6 +331,7 @@ class TestBatchNIOEdgeCases: async def test_vpcs_dispatch_to_port_add_nio_binding(self): """_add_nio_binding dispatches VPCS to port_add_nio_binding.""" from unittest.mock import AsyncMock, MagicMock + from gns3server.api.routes.compute.projects import _add_nio_binding node = MagicMock() @@ -340,6 +346,7 @@ class TestBatchNIOEdgeCases: async def test_builtin_dispatch_to_add_nio(self): """_add_nio_binding dispatches Builtin nodes to add_nio(nio, port).""" from unittest.mock import AsyncMock, MagicMock + from gns3server.api.routes.compute.projects import _add_nio_binding node = MagicMock() diff --git a/tests/api/routes/compute/test_qemu_nodes.py b/tests/api/routes/compute/test_qemu_nodes.py index 304f330a4..1281f338f 100644 --- a/tests/api/routes/compute/test_qemu_nodes.py +++ b/tests/api/routes/compute/test_qemu_nodes.py @@ -14,19 +14,19 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import os +import shutil +import stat +import uuid +from unittest.mock import MagicMock, patch + import pytest import pytest_asyncio -import os -import stat -import shutil -import uuid - from fastapi import FastAPI, status from httpx import AsyncClient -from tests.utils import asyncio_patch -from unittest.mock import patch, MagicMock from gns3server.compute.project import Project +from tests.utils import asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/compute/test_virtualbox_nodes.py b/tests/api/routes/compute/test_virtualbox_nodes.py index 2de646193..7325805dd 100644 --- a/tests/api/routes/compute/test_virtualbox_nodes.py +++ b/tests/api/routes/compute/test_virtualbox_nodes.py @@ -14,15 +14,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest -import pytest_asyncio - -from fastapi import FastAPI, status -from httpx import AsyncClient -from tests.utils import asyncio_patch from unittest.mock import patch +import pytest +import pytest_asyncio +from fastapi import FastAPI, status +from httpx import AsyncClient + from gns3server.compute.project import Project +from tests.utils import asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/compute/test_vmware_nodes.py b/tests/api/routes/compute/test_vmware_nodes.py index df485774a..b1b4d419d 100644 --- a/tests/api/routes/compute/test_vmware_nodes.py +++ b/tests/api/routes/compute/test_vmware_nodes.py @@ -14,15 +14,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest -import pytest_asyncio - -from fastapi import FastAPI, status -from httpx import AsyncClient -from tests.utils import asyncio_patch from unittest.mock import patch +import pytest +import pytest_asyncio +from fastapi import FastAPI, status +from httpx import AsyncClient + from gns3server.compute.project import Project +from tests.utils import asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/compute/test_vpcs_nodes.py b/tests/api/routes/compute/test_vpcs_nodes.py index fd558d9a9..3fd03cfe6 100644 --- a/tests/api/routes/compute/test_vpcs_nodes.py +++ b/tests/api/routes/compute/test_vpcs_nodes.py @@ -14,15 +14,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest -import pytest_asyncio - -from fastapi import FastAPI, status -from httpx import AsyncClient -from tests.utils import asyncio_patch from unittest.mock import patch +import pytest +import pytest_asyncio +from fastapi import FastAPI, status +from httpx import AsyncClient + from gns3server.compute.project import Project +from tests.utils import asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_access_tickets.py b/tests/api/routes/controller/test_access_tickets.py index b70f135b5..c2fb634cd 100644 --- a/tests/api/routes/controller/test_access_tickets.py +++ b/tests/api/routes/controller/test_access_tickets.py @@ -33,9 +33,9 @@ from gns3server.controller.node import Node from gns3server.controller.project import Project from gns3server.services import access_ticket_service from gns3server.services.access_tickets import ( - AccessTicketService, DEFAULT_TICKET_TTL, TICKET_PREFIX, + AccessTicketService, ) from gns3server.utils.http_client import HTTPClient from tests.api.routes.controller.test_nodes import FakeComputeConsoleWebSocket diff --git a/tests/api/routes/controller/test_acl.py b/tests/api/routes/controller/test_acl.py index ed1fee046..e8f015a7a 100644 --- a/tests/api/routes/controller/test_acl.py +++ b/tests/api/routes/controller/test_acl.py @@ -17,16 +17,15 @@ import pytest import pytest_asyncio - from fastapi import FastAPI, status from httpx import AsyncClient - from sqlalchemy.ext.asyncio import AsyncSession -from gns3server.db.repositories.users import UsersRepository -from gns3server.db.repositories.rbac import RbacRepository -from gns3server.schemas.controller.users import User -from gns3server.schemas.controller.rbac import ACECreate + from gns3server.controller import Controller +from gns3server.db.repositories.rbac import RbacRepository +from gns3server.db.repositories.users import UsersRepository +from gns3server.schemas.controller.rbac import ACECreate +from gns3server.schemas.controller.users import User pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_appliances.py b/tests/api/routes/controller/test_appliances.py index c37f18ddd..94e7673f7 100644 --- a/tests/api/routes/controller/test_appliances.py +++ b/tests/api/routes/controller/test_appliances.py @@ -16,11 +16,12 @@ # along with this program. If not, see . import os -import pytest import shutil +import pytest from fastapi import FastAPI, status from httpx import AsyncClient + from gns3server.controller import Controller pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_computes.py b/tests/api/routes/controller/test_computes.py index ea2317821..3c213c07c 100644 --- a/tests/api/routes/controller/test_computes.py +++ b/tests/api/routes/controller/test_computes.py @@ -16,9 +16,9 @@ # along with this program. If not, see . import uuid -import pytest from unittest.mock import MagicMock, patch +import pytest from fastapi import FastAPI, status from httpx import AsyncClient @@ -26,7 +26,7 @@ from gns3server.schemas.controller.computes import Compute pytestmark = pytest.mark.asyncio -from tests.utils import asyncio_patch, AsyncioMagicMock +from tests.utils import AsyncioMagicMock, asyncio_patch class TestComputeRoutes: diff --git a/tests/api/routes/controller/test_controller.py b/tests/api/routes/controller/test_controller.py index b71a9cf2c..4ef729543 100644 --- a/tests/api/routes/controller/test_controller.py +++ b/tests/api/routes/controller/test_controller.py @@ -16,11 +16,11 @@ # along with this program. If not, see . import os -import pytest +from unittest.mock import MagicMock +import pytest from fastapi import FastAPI, status from httpx import AsyncClient -from unittest.mock import MagicMock from gns3server.config import Config diff --git a/tests/api/routes/controller/test_drawings.py b/tests/api/routes/controller/test_drawings.py index 2096df27a..955b46f86 100644 --- a/tests/api/routes/controller/test_drawings.py +++ b/tests/api/routes/controller/test_drawings.py @@ -15,7 +15,6 @@ # along with this program. If not, see . import pytest - from fastapi import FastAPI, status from httpx import AsyncClient diff --git a/tests/api/routes/controller/test_gns3vm.py b/tests/api/routes/controller/test_gns3vm.py index bf5db4141..c3782eb4d 100644 --- a/tests/api/routes/controller/test_gns3vm.py +++ b/tests/api/routes/controller/test_gns3vm.py @@ -15,9 +15,9 @@ # along with this program. If not, see . import pytest - from fastapi import FastAPI, status from httpx import AsyncClient + from tests.utils import asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_groups.py b/tests/api/routes/controller/test_groups.py index 69ff6183f..5451293f7 100644 --- a/tests/api/routes/controller/test_groups.py +++ b/tests/api/routes/controller/test_groups.py @@ -16,11 +16,10 @@ # along with this program. If not, see . import pytest - from fastapi import FastAPI, status from httpx import AsyncClient - from sqlalchemy.ext.asyncio import AsyncSession + from gns3server.db.repositories.users import UsersRepository from gns3server.schemas.controller.users import User, UserGroupCreate diff --git a/tests/api/routes/controller/test_image_sync.py b/tests/api/routes/controller/test_image_sync.py index 6e1a43d42..de658c204 100644 --- a/tests/api/routes/controller/test_image_sync.py +++ b/tests/api/routes/controller/test_image_sync.py @@ -6,9 +6,9 @@ import pytest import pytest_asyncio from gns3server.db.repositories.images import ImagesRepository -from gns3server.services.image_reconciliation import ImageReconciliationService from gns3server.services import auth_service from gns3server.services.authentication import DEFAULT_JWT_SECRET_KEY +from gns3server.services.image_reconciliation import ImageReconciliationService pytestmark = pytest.mark.asyncio QCOW = b"QFI\xfb\x00\x00\x00" diff --git a/tests/api/routes/controller/test_images.py b/tests/api/routes/controller/test_images.py index ec498f763..c92cbefac 100644 --- a/tests/api/routes/controller/test_images.py +++ b/tests/api/routes/controller/test_images.py @@ -15,22 +15,21 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os -import json -import uuid -import pytest import hashlib +import json +import os +import uuid -from tests.utils import asyncio_patch -from sqlalchemy.ext.asyncio import AsyncSession +import pytest from fastapi import FastAPI, status from httpx import AsyncClient -from tests.utils import AsyncioMagicMock +from sqlalchemy.ext.asyncio import AsyncSession +from gns3server.compute.qemu import Qemu from gns3server.controller import Controller from gns3server.db.repositories.images import ImagesRepository from gns3server.db.repositories.templates import TemplatesRepository -from gns3server.compute.qemu import Qemu +from tests.utils import AsyncioMagicMock, asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_links.py b/tests/api/routes/controller/test_links.py index d6af89d70..518eb22f9 100644 --- a/tests/api/routes/controller/test_links.py +++ b/tests/api/routes/controller/test_links.py @@ -14,23 +14,22 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest import uuid -import pytest_asyncio - from typing import Tuple +from unittest.mock import MagicMock, patch + +import pytest +import pytest_asyncio from fastapi import FastAPI, status from httpx import AsyncClient -from unittest.mock import patch, MagicMock -from tests.utils import asyncio_patch, AsyncioMagicMock - -from gns3server.controller.project import Project from gns3server.controller.compute import Compute +from gns3server.controller.link import FILTERS, Link from gns3server.controller.node import Node from gns3server.controller.ports.ethernet_port import EthernetPort -from gns3server.controller.link import Link, FILTERS +from gns3server.controller.project import Project from gns3server.controller.udp_link import UDPLink +from tests.utils import AsyncioMagicMock, asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_marker_replay.py b/tests/api/routes/controller/test_marker_replay.py index 072190f4c..1ea9faab2 100644 --- a/tests/api/routes/controller/test_marker_replay.py +++ b/tests/api/routes/controller/test_marker_replay.py @@ -32,11 +32,10 @@ import pytest_asyncio from fastapi import FastAPI, status from httpx import AsyncClient +from gns3server.controller import marker_replay from gns3server.controller.project import Project from gns3server.controller.udp_link import UDPLink -from gns3server.controller import marker_replay - -from tests.controller.test_marker_replay import _write_pcap, _icmp_frame, _tcp_syn_frame, _cols +from tests.controller.test_marker_replay import _cols, _icmp_frame, _tcp_syn_frame, _write_pcap pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_markers.py b/tests/api/routes/controller/test_markers.py index 54e4dc8f0..b53ec8533 100644 --- a/tests/api/routes/controller/test_markers.py +++ b/tests/api/routes/controller/test_markers.py @@ -23,10 +23,9 @@ import pytest from fastapi import FastAPI, status from httpx import AsyncClient -from tests.utils import asyncio_patch - from gns3server.controller.project import Project from gns3server.controller.udp_link import UDPLink +from tests.utils import asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_netmiko.py b/tests/api/routes/controller/test_netmiko.py index 6384161bb..a0acc9f12 100644 --- a/tests/api/routes/controller/test_netmiko.py +++ b/tests/api/routes/controller/test_netmiko.py @@ -16,7 +16,6 @@ import pytest - from fastapi import FastAPI, status from httpx import AsyncClient diff --git a/tests/api/routes/controller/test_nodes.py b/tests/api/routes/controller/test_nodes.py index 017e65783..a2d37922a 100644 --- a/tests/api/routes/controller/test_nodes.py +++ b/tests/api/routes/controller/test_nodes.py @@ -18,31 +18,28 @@ import asyncio import contextlib import logging +from types import SimpleNamespace +from typing import List, Optional +from unittest.mock import MagicMock, patch import aiohttp import pytest - -from types import SimpleNamespace -from typing import List, Optional - from fastapi import FastAPI, HTTPException, WebSocketDisconnect, status from httpx import AsyncClient -from pydantic import SecretStr -from httpx_ws import aconnect_ws from httpx_ws import WebSocketDisconnect as HttpxWebSocketDisconnect -from httpx_ws.transport import ASGIWebSocketTransport, ASGIWebSocketAsyncNetworkStream - -from unittest.mock import MagicMock, patch -from tests.utils import AsyncioMagicMock +from httpx_ws import aconnect_ws +from httpx_ws.transport import ASGIWebSocketAsyncNetworkStream, ASGIWebSocketTransport +from pydantic import SecretStr +from gns3server.api.routes.controller.nodes import vnc_console, ws_console from gns3server.config import Config +from gns3server.controller.compute import Compute from gns3server.controller.node import Node from gns3server.controller.project import Project -from gns3server.controller.compute import Compute -from gns3server.utils.http_client import HTTPClient -from gns3server.api.routes.controller.nodes import ws_console, vnc_console from gns3server.services import auth_service from gns3server.services.authentication import DEFAULT_JWT_SECRET_KEY +from gns3server.utils.http_client import HTTPClient +from tests.utils import AsyncioMagicMock pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_pools.py b/tests/api/routes/controller/test_pools.py index f3b78cccb..2a505c63c 100644 --- a/tests/api/routes/controller/test_pools.py +++ b/tests/api/routes/controller/test_pools.py @@ -16,16 +16,16 @@ # along with this program. If not, see . import uuid + import pytest import pytest_asyncio - from fastapi import FastAPI, status from httpx import AsyncClient - from sqlalchemy.ext.asyncio import AsyncSession -from gns3server.db.repositories.pools import ResourcePoolsRepository + from gns3server.controller import Controller from gns3server.controller.project import Project +from gns3server.db.repositories.pools import ResourcePoolsRepository from gns3server.schemas.controller.pools import ResourceCreate, ResourcePoolCreate pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_projects.py b/tests/api/routes/controller/test_projects.py index 0d840a41c..3ae35c689 100644 --- a/tests/api/routes/controller/test_projects.py +++ b/tests/api/routes/controller/test_projects.py @@ -14,21 +14,21 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import uuid -import os import json +import os +import uuid +from unittest.mock import MagicMock, patch + import pytest import pytest_asyncio - from fastapi import FastAPI, status from httpx import AsyncClient -from unittest.mock import patch, MagicMock -from tests.utils import asyncio_patch, AsyncioMagicMock import gns3server.utils.zipfile_zstd as zipfile_zstd from gns3server.controller import Controller -from gns3server.controller.project import Project from gns3server.controller.compute import Compute +from gns3server.controller.project import Project +from tests.utils import AsyncioMagicMock, asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_roles.py b/tests/api/routes/controller/test_roles.py index bdc6f6651..45676a8fb 100644 --- a/tests/api/routes/controller/test_roles.py +++ b/tests/api/routes/controller/test_roles.py @@ -16,11 +16,10 @@ # along with this program. If not, see . import pytest - from fastapi import FastAPI, status from httpx import AsyncClient - from sqlalchemy.ext.asyncio import AsyncSession + from gns3server.db.repositories.rbac import RbacRepository pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_settings.py b/tests/api/routes/controller/test_settings.py index e23d0606c..f7500a295 100644 --- a/tests/api/routes/controller/test_settings.py +++ b/tests/api/routes/controller/test_settings.py @@ -14,11 +14,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os import configparser +import os import pytest - from fastapi import FastAPI, status from httpx import AsyncClient diff --git a/tests/api/routes/controller/test_snapshots.py b/tests/api/routes/controller/test_snapshots.py index 1c2f60a5e..5e0faf1f4 100644 --- a/tests/api/routes/controller/test_snapshots.py +++ b/tests/api/routes/controller/test_snapshots.py @@ -17,9 +17,9 @@ import os import uuid + import pytest import pytest_asyncio - from fastapi import FastAPI, status from httpx import AsyncClient diff --git a/tests/api/routes/controller/test_symbols.py b/tests/api/routes/controller/test_symbols.py index 97f80889e..17446443b 100644 --- a/tests/api/routes/controller/test_symbols.py +++ b/tests/api/routes/controller/test_symbols.py @@ -15,10 +15,10 @@ # along with this program. If not, see . -import pytest import os import urllib.parse +import pytest from fastapi import FastAPI, status from httpx import AsyncClient diff --git a/tests/api/routes/controller/test_templates.py b/tests/api/routes/controller/test_templates.py index 864cc1d57..34e60ef2d 100644 --- a/tests/api/routes/controller/test_templates.py +++ b/tests/api/routes/controller/test_templates.py @@ -15,27 +15,25 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os import json +import os import shutil +import unittest.mock +import uuid +from pathlib import Path import pytest -import uuid -import unittest.mock - -from pathlib import Path from fastapi import FastAPI, status from httpx import AsyncClient from sqlalchemy.ext.asyncio import AsyncSession -from tests.utils import asyncio_patch +from gns3server import schemas +from gns3server.api.routes.controller.dependencies.authentication import get_current_active_user +from gns3server.controller import Config, Controller from gns3server.db.repositories.images import ImagesRepository from gns3server.db.repositories.templates import TemplatesRepository -from gns3server.controller import Controller -from gns3server.controller import Config from gns3server.services.templates import BUILTIN_TEMPLATES -from gns3server.api.routes.controller.dependencies.authentication import get_current_active_user -from gns3server import schemas +from tests.utils import asyncio_patch pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_users.py b/tests/api/routes/controller/test_users.py index 8bdf437ad..0eb708139 100644 --- a/tests/api/routes/controller/test_users.py +++ b/tests/api/routes/controller/test_users.py @@ -15,21 +15,21 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest - from typing import Optional + +import pytest from fastapi import FastAPI, HTTPException, status -from sqlalchemy import update from httpx import AsyncClient from joserfc import jwt from joserfc.jwk import OctKey - +from sqlalchemy import update from sqlalchemy.ext.asyncio import AsyncSession -from gns3server.db.repositories.users import UsersRepository -from gns3server.services import auth_service -from gns3server.config import Config -from gns3server.schemas.controller.users import User + import gns3server.db.models as models +from gns3server.config import Config +from gns3server.db.repositories.users import UsersRepository +from gns3server.schemas.controller.users import User +from gns3server.services import auth_service pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/controller/test_version.py b/tests/api/routes/controller/test_version.py index c7220ed62..b0ea854aa 100644 --- a/tests/api/routes/controller/test_version.py +++ b/tests/api/routes/controller/test_version.py @@ -15,7 +15,6 @@ # along with this program. If not, see . import pytest - from fastapi import FastAPI, status from httpx import AsyncClient diff --git a/tests/api/routes/test_index.py b/tests/api/routes/test_index.py index df3c242b1..8a99c0d54 100644 --- a/tests/api/routes/test_index.py +++ b/tests/api/routes/test_index.py @@ -14,16 +14,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest import os - -from fastapi import FastAPI, status -from httpx import AsyncClient from unittest.mock import patch -from gns3server.version import __version__ +import pytest +from fastapi import FastAPI, status +from httpx import AsyncClient + from gns3server.controller import Controller from gns3server.utils.get_resource import get_resource +from gns3server.version import __version__ pytestmark = pytest.mark.asyncio diff --git a/tests/api/routes/test_routes.py b/tests/api/routes/test_routes.py index e43a8c557..296cd679d 100644 --- a/tests/api/routes/test_routes.py +++ b/tests/api/routes/test_routes.py @@ -14,15 +14,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from typing import Iterator, Sequence, Tuple + import pytest from fastapi import FastAPI, status from fastapi.routing import APIRoute, APIWebSocketRoute, _IncludedRouter -from starlette.routing import BaseRoute, Mount from httpx import AsyncClient from httpx_ws import aconnect_ws from httpx_ws.transport import ASGIWebSocketTransport -from typing import Iterator, Sequence, Tuple - +from starlette.routing import BaseRoute, Mount pytestmark = pytest.mark.asyncio diff --git a/tests/compute/builtin/nodes/test_cloud.py b/tests/compute/builtin/nodes/test_cloud.py index a25e390df..bebec5fc5 100644 --- a/tests/compute/builtin/nodes/test_cloud.py +++ b/tests/compute/builtin/nodes/test_cloud.py @@ -16,15 +16,15 @@ # along with this program. If not, see . import uuid +from unittest.mock import MagicMock, call, patch + import pytest import pytest_asyncio -from unittest.mock import MagicMock, patch, call from gns3server.compute.builtin.nodes.cloud import Cloud from gns3server.compute.nios.nio_udp import NIOUDP from tests.utils import asyncio_patch - pytestmark = pytest.mark.asyncio diff --git a/tests/compute/docker/test_docker.py b/tests/compute/docker/test_docker.py index 14d347ba9..74c7f365b 100644 --- a/tests/compute/docker/test_docker.py +++ b/tests/compute/docker/test_docker.py @@ -16,13 +16,14 @@ # along with this program. If not, see . import asyncio -import pytest -import pytest_asyncio from unittest.mock import MagicMock, patch -from tests.utils import asyncio_patch, AsyncioMagicMock -from gns3server.compute.docker import Docker, DOCKER_PREFERRED_API_VERSION, DOCKER_MINIMUM_API_VERSION +import pytest +import pytest_asyncio + +from gns3server.compute.docker import DOCKER_MINIMUM_API_VERSION, DOCKER_PREFERRED_API_VERSION, Docker from gns3server.compute.docker.docker_error import DockerError, DockerHttp404Error +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest_asyncio.fixture diff --git a/tests/compute/docker/test_docker_vm.py b/tests/compute/docker/test_docker_vm.py index ecb64dd0b..2c15d8927 100644 --- a/tests/compute/docker/test_docker_vm.py +++ b/tests/compute/docker/test_docker_vm.py @@ -14,27 +14,24 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import aiohttp import asyncio -import pytest -import pytest_asyncio -import uuid import os import shutil - +import uuid from types import SimpleNamespace -from unittest.mock import patch -from tests.utils import asyncio_patch, AsyncioMagicMock +from unittest.mock import AsyncMock, MagicMock, call, patch + +import aiohttp +import pytest +import pytest_asyncio -from gns3server.compute.ubridge.ubridge_error import UbridgeNamespaceError from gns3server.compute.compute_error import ComputeError -from gns3server.compute.docker.docker_vm import DockerVM -from gns3server.compute.docker.docker_error import DockerError, DockerHttp404Error -from gns3server.compute.error import ImageMissingError from gns3server.compute.docker import Docker - - -from unittest.mock import AsyncMock, patch, MagicMock, call +from gns3server.compute.docker.docker_error import DockerError, DockerHttp404Error +from gns3server.compute.docker.docker_vm import DockerVM +from gns3server.compute.error import ImageMissingError +from gns3server.compute.ubridge.ubridge_error import UbridgeNamespaceError +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest_asyncio.fixture @@ -2246,6 +2243,7 @@ def test_extra_config_schema_rejects_bad_targets(): """ from pydantic import ValidationError + from gns3server.schemas.common import ExtraConfig for bad in ("relative/path", "/has/../dots", "/", "/etc/", "no-leading-slash"): diff --git a/tests/compute/docker/test_iol_docker_vm.py b/tests/compute/docker/test_iol_docker_vm.py index 66861c8c5..23fcb0e36 100644 --- a/tests/compute/docker/test_iol_docker_vm.py +++ b/tests/compute/docker/test_iol_docker_vm.py @@ -27,22 +27,19 @@ import glob import json import os import uuid +from unittest.mock import MagicMock, call, patch import pytest import pytest_asyncio -from unittest.mock import patch, MagicMock, call - -from tests.utils import asyncio_patch, AsyncioMagicMock - from gns3server.compute.docker import Docker -from gns3server.compute.docker.docker_vm import DockerVM -from gns3server.compute.docker.vendor_docker_vm import VendorDockerVM -from gns3server.compute.docker.iol_docker_vm import IOLDockerVM from gns3server.compute.docker.docker_error import DockerError +from gns3server.compute.docker.docker_vm import DockerVM +from gns3server.compute.docker.iol_docker_vm import IOLDockerVM +from gns3server.compute.docker.vendor_docker_vm import VendorDockerVM from gns3server.compute.iou.utils.iou_export import nvram_export from gns3server.compute.iou.utils.iou_import import nvram_import - +from tests.utils import AsyncioMagicMock, asyncio_patch # --------------------------------------------------------------------------- # Helpers / fixtures diff --git a/tests/compute/docker/test_vendor_docker_vm.py b/tests/compute/docker/test_vendor_docker_vm.py index 2839e93c8..e594cf5fa 100644 --- a/tests/compute/docker/test_vendor_docker_vm.py +++ b/tests/compute/docker/test_vendor_docker_vm.py @@ -30,21 +30,18 @@ These tests cover: * the container-side _fix_permissions passes. """ -import uuid import os +import uuid +from unittest.mock import MagicMock, call, patch import pytest import pytest_asyncio -from unittest.mock import patch, MagicMock, call - -from tests.utils import asyncio_patch, AsyncioMagicMock - from gns3server.compute.docker import Docker +from gns3server.compute.docker.docker_error import DockerError, DockerHttp404Error from gns3server.compute.docker.docker_vm import DockerVM from gns3server.compute.docker.vendor_docker_vm import VendorDockerVM, _LazyExecTelnetServer -from gns3server.compute.docker.docker_error import DockerError, DockerHttp404Error - +from tests.utils import AsyncioMagicMock, asyncio_patch # --------------------------------------------------------------------------- # Helpers / fixtures diff --git a/tests/compute/dynamips/test_dynamips_manager.py b/tests/compute/dynamips/test_dynamips_manager.py index 0d62c014b..2d39592bf 100644 --- a/tests/compute/dynamips/test_dynamips_manager.py +++ b/tests/compute/dynamips/test_dynamips_manager.py @@ -15,16 +15,17 @@ # along with this program. If not, see . -import pytest -import pytest_asyncio +import os import tempfile import uuid -import os +from unittest.mock import patch + +import pytest +import pytest_asyncio from gns3server.compute.dynamips import Dynamips from gns3server.compute.dynamips.dynamips_error import DynamipsError -from unittest.mock import patch -from tests.utils import asyncio_patch, AsyncioMagicMock +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest_asyncio.fixture diff --git a/tests/compute/dynamips/test_dynamips_router.py b/tests/compute/dynamips/test_dynamips_router.py index 068bb5e9e..e98ec98a0 100644 --- a/tests/compute/dynamips/test_dynamips_router.py +++ b/tests/compute/dynamips/test_dynamips_router.py @@ -16,12 +16,13 @@ import os import uuid + import pytest import pytest_asyncio -from gns3server.compute.dynamips.nodes.router import Router -from gns3server.compute.dynamips.dynamips_error import DynamipsError from gns3server.compute.dynamips import Dynamips +from gns3server.compute.dynamips.dynamips_error import DynamipsError +from gns3server.compute.dynamips.nodes.router import Router from gns3server.config import Config diff --git a/tests/compute/dynamips/test_ethernet_switch.py b/tests/compute/dynamips/test_ethernet_switch.py index c34be1952..49a0b1111 100644 --- a/tests/compute/dynamips/test_ethernet_switch.py +++ b/tests/compute/dynamips/test_ethernet_switch.py @@ -15,8 +15,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from tests.utils import AsyncioMagicMock from gns3server.compute.nios.nio_udp import NIOUDP +from tests.utils import AsyncioMagicMock def test_mac_command(): diff --git a/tests/compute/iou/test_iou_vm.py b/tests/compute/iou/test_iou_vm.py index d80cc4356..45ec5973a 100644 --- a/tests/compute/iou/test_iou_vm.py +++ b/tests/compute/iou/test_iou_vm.py @@ -14,22 +14,22 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest -import pytest_asyncio import asyncio import os -import stat +import shutil import socket +import stat import struct import uuid -import shutil - -from tests.utils import asyncio_patch, AsyncioMagicMock - from unittest.mock import MagicMock, call -from gns3server.compute.iou.iou_vm import IOUL1KeepaliveProtocol, IOUVM -from gns3server.compute.iou.iou_error import IOUError + +import pytest +import pytest_asyncio + from gns3server.compute.iou import IOU +from gns3server.compute.iou.iou_error import IOUError +from gns3server.compute.iou.iou_vm import IOUVM, IOUL1KeepaliveProtocol +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest_asyncio.fixture diff --git a/tests/compute/marker/test_marker_manager.py b/tests/compute/marker/test_marker_manager.py index dcd71c3f9..b694340ed 100644 --- a/tests/compute/marker/test_marker_manager.py +++ b/tests/compute/marker/test_marker_manager.py @@ -16,11 +16,11 @@ # along with this program. If not, see . import asyncio + import pytest -from gns3server.compute.marker.marker_manager import MarkerManager from gns3server.compute.marker.marker_listener import MarkerListener - +from gns3server.compute.marker.marker_manager import MarkerManager # --------------------------------------------------------------------------- # Registry diff --git a/tests/compute/qemu/test_qcow2.py b/tests/compute/qemu/test_qcow2.py index dfd86a2e0..e9306a17e 100644 --- a/tests/compute/qemu/test_qcow2.py +++ b/tests/compute/qemu/test_qcow2.py @@ -16,9 +16,10 @@ # along with this program. If not, see . import os -import pytest import shutil +import pytest + from gns3server.compute.qemu.utils.qcow2 import Qcow2, Qcow2Error diff --git a/tests/compute/qemu/test_qemu_manager.py b/tests/compute/qemu/test_qemu_manager.py index 9f3c2afac..bab61bf17 100644 --- a/tests/compute/qemu/test_qemu_manager.py +++ b/tests/compute/qemu/test_qemu_manager.py @@ -15,17 +15,17 @@ # along with this program. If not, see . import os -import stat -import pytest import platform +import stat import sys +from unittest.mock import MagicMock, patch + +import pytest from gns3server.compute.qemu import Qemu from gns3server.compute.qemu.qemu_error import QemuError from tests.utils import asyncio_patch -from unittest.mock import patch, MagicMock - @pytest.fixture def fake_qemu_img_binary(tmpdir): diff --git a/tests/compute/qemu/test_qemu_vm.py b/tests/compute/qemu/test_qemu_vm.py index e20eddcd6..bfeb02bdf 100644 --- a/tests/compute/qemu/test_qemu_vm.py +++ b/tests/compute/qemu/test_qemu_vm.py @@ -14,23 +14,22 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest -import pytest_asyncio import asyncio import os import stat import sys -from tests.utils import asyncio_patch, AsyncioMagicMock - - from unittest import mock -from unittest.mock import patch, MagicMock +from unittest.mock import MagicMock, patch + +import pytest +import pytest_asyncio -from gns3server.compute.qemu.qemu_vm import QemuVM -from gns3server.compute.qemu.qemu_error import QemuError -from gns3server.compute.qemu import Qemu -from gns3server.utils import force_unix_path, macaddress_to_int, int_to_macaddress from gns3server.compute.notification_manager import NotificationManager +from gns3server.compute.qemu import Qemu +from gns3server.compute.qemu.qemu_error import QemuError +from gns3server.compute.qemu.qemu_vm import QemuVM +from gns3server.utils import force_unix_path, int_to_macaddress, macaddress_to_int +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest_asyncio.fixture diff --git a/tests/compute/test_base_node.py b/tests/compute/test_base_node.py index 850db6325..9d4e15374 100644 --- a/tests/compute/test_base_node.py +++ b/tests/compute/test_base_node.py @@ -17,19 +17,18 @@ import os import shutil from collections import OrderedDict +from unittest.mock import MagicMock, patch import pytest import pytest_asyncio -from tests.utils import asyncio_patch, AsyncioMagicMock -from unittest.mock import patch, MagicMock - from gns3server.compute.compute_error import ComputeError -from gns3server.compute.vpcs.vpcs_vm import VPCSVM from gns3server.compute.docker.docker_vm import DockerVM from gns3server.compute.error import NodeError -from gns3server.compute.vpcs import VPCS from gns3server.compute.nios.nio_udp import NIOUDP +from gns3server.compute.vpcs import VPCS +from gns3server.compute.vpcs.vpcs_vm import VPCSVM +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest_asyncio.fixture(scope="function") diff --git a/tests/compute/test_manager.py b/tests/compute/test_manager.py index f0f5bbc46..db9f22586 100644 --- a/tests/compute/test_manager.py +++ b/tests/compute/test_manager.py @@ -14,19 +14,20 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import uuid import os +import uuid +from unittest.mock import MagicMock, patch + import pytest import pytest_asyncio -from unittest.mock import patch, MagicMock -from tests.utils import asyncio_patch -from gns3server.compute.vpcs import VPCS -from gns3server.compute.dynamips import Dynamips -from gns3server.compute.qemu import Qemu -from gns3server.compute.error import NodeError, ImageMissingError from gns3server.compute.compute_error import ComputeError +from gns3server.compute.dynamips import Dynamips +from gns3server.compute.error import ImageMissingError, NodeError +from gns3server.compute.qemu import Qemu +from gns3server.compute.vpcs import VPCS from gns3server.utils import force_unix_path +from tests.utils import asyncio_patch @pytest_asyncio.fixture(scope="function") diff --git a/tests/compute/test_notification_manager.py b/tests/compute/test_notification_manager.py index 3daea1a8c..3ee862302 100644 --- a/tests/compute/test_notification_manager.py +++ b/tests/compute/test_notification_manager.py @@ -15,9 +15,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest import uuid +import pytest + from gns3server.compute.notification_manager import NotificationManager diff --git a/tests/compute/test_port_manager.py b/tests/compute/test_port_manager.py index f28418563..2e55ec8a1 100644 --- a/tests/compute/test_port_manager.py +++ b/tests/compute/test_port_manager.py @@ -14,13 +14,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest import threading import uuid - -from fastapi import HTTPException from unittest.mock import patch +import pytest +from fastapi import HTTPException + from gns3server.compute.port_manager import PortManager from gns3server.compute.project import Project diff --git a/tests/compute/test_project.py b/tests/compute/test_project.py index d46abe4e9..abf969084 100644 --- a/tests/compute/test_project.py +++ b/tests/compute/test_project.py @@ -17,16 +17,17 @@ import os import uuid +from unittest.mock import patch +from uuid import uuid4 + import pytest import pytest_asyncio -from uuid import uuid4 -from unittest.mock import patch -from tests.utils import asyncio_patch -from gns3server.compute.project import Project -from gns3server.compute.notification_manager import NotificationManager from gns3server.compute.compute_error import ComputeError, ComputeForbiddenError +from gns3server.compute.notification_manager import NotificationManager +from gns3server.compute.project import Project from gns3server.compute.vpcs import VPCS, VPCSVM +from tests.utils import asyncio_patch @pytest_asyncio.fixture(scope="function") diff --git a/tests/compute/ubridge/test_hypervisor.py b/tests/compute/ubridge/test_hypervisor.py index 1ee5a555a..74f0be660 100644 --- a/tests/compute/ubridge/test_hypervisor.py +++ b/tests/compute/ubridge/test_hypervisor.py @@ -22,13 +22,13 @@ transport (AF_UNIX ``-U`` vs TCP ``-H``), command building, the human-readable immediately-exiting uBridge process (e.g. an old build that rejects ``-U``). """ +import logging import os import re import stat -import logging +from unittest.mock import AsyncMock, MagicMock, patch import pytest -from unittest.mock import MagicMock, AsyncMock, patch from gns3server.compute.ubridge.hypervisor import Hypervisor from gns3server.compute.ubridge.ubridge_error import UbridgeError diff --git a/tests/compute/virtualbox/test_virtualbox_manager.py b/tests/compute/virtualbox/test_virtualbox_manager.py index 8a23b41df..4e60da7da 100644 --- a/tests/compute/virtualbox/test_virtualbox_manager.py +++ b/tests/compute/virtualbox/test_virtualbox_manager.py @@ -15,14 +15,14 @@ # along with this program. If not, see . -import pytest -import pytest_asyncio -import tempfile import os import stat - +import tempfile from unittest.mock import patch +import pytest +import pytest_asyncio + from gns3server.compute.virtualbox import VirtualBox from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError from tests.utils import asyncio_patch diff --git a/tests/compute/virtualbox/test_virtualbox_vm.py b/tests/compute/virtualbox/test_virtualbox_vm.py index ead5c72fe..d2cab8aa1 100644 --- a/tests/compute/virtualbox/test_virtualbox_vm.py +++ b/tests/compute/virtualbox/test_virtualbox_vm.py @@ -15,13 +15,14 @@ # along with this program. If not, see . import os + import pytest import pytest_asyncio -from tests.utils import asyncio_patch, AsyncioMagicMock -from gns3server.compute.virtualbox.virtualbox_vm import VirtualBoxVM -from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError from gns3server.compute.virtualbox import VirtualBox +from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError +from gns3server.compute.virtualbox.virtualbox_vm import VirtualBoxVM +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest_asyncio.fixture diff --git a/tests/compute/vmware/test_vmware_vm.py b/tests/compute/vmware/test_vmware_vm.py index f2badff9c..f13efb08b 100644 --- a/tests/compute/vmware/test_vmware_vm.py +++ b/tests/compute/vmware/test_vmware_vm.py @@ -17,8 +17,8 @@ import pytest import pytest_asyncio -from gns3server.compute.vmware.vmware_vm import VMwareVM from gns3server.compute.vmware import VMware +from gns3server.compute.vmware.vmware_vm import VMwareVM @pytest_asyncio.fixture diff --git a/tests/compute/vpcs/test_vpcs_manager.py b/tests/compute/vpcs/test_vpcs_manager.py index d567b8674..7aad60146 100644 --- a/tests/compute/vpcs/test_vpcs_manager.py +++ b/tests/compute/vpcs/test_vpcs_manager.py @@ -15,13 +15,13 @@ # along with this program. If not, see . -import pytest import uuid +import pytest +from gns3server.compute.project_manager import ProjectManager from gns3server.compute.vpcs import VPCS from gns3server.compute.vpcs.vpcs_error import VPCSError -from gns3server.compute.project_manager import ProjectManager @pytest.mark.asyncio diff --git a/tests/compute/vpcs/test_vpcs_vm.py b/tests/compute/vpcs/test_vpcs_vm.py index 1d74fdf95..be4d6a364 100644 --- a/tests/compute/vpcs/test_vpcs_vm.py +++ b/tests/compute/vpcs/test_vpcs_vm.py @@ -14,19 +14,19 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest -import pytest_asyncio import asyncio import os +from unittest.mock import ANY, MagicMock, patch -from tests.utils import asyncio_patch, AsyncioMagicMock -from gns3server.utils import parse_version -from unittest.mock import patch, MagicMock, ANY +import pytest +import pytest_asyncio -from gns3server.compute.vpcs.vpcs_vm import VPCSVM -from gns3server.compute.vpcs.vpcs_error import VPCSError -from gns3server.compute.vpcs import VPCS from gns3server.compute.notification_manager import NotificationManager +from gns3server.compute.vpcs import VPCS +from gns3server.compute.vpcs.vpcs_error import VPCSError +from gns3server.compute.vpcs.vpcs_vm import VPCSVM +from gns3server.utils import parse_version +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest_asyncio.fixture diff --git a/tests/conftest.py b/tests/conftest.py index bc9f7c823..4868ff18e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,35 +1,35 @@ -import pytest import asyncio -import pytest_asyncio -import tempfile -import shutil -import sys -import os -import uuid -import configparser import base64 -import stat -import resource +import configparser +import os import platform +import resource +import shutil +import stat +import sys +import tempfile +import uuid +from pathlib import Path +from typing import Any, AsyncGenerator +from unittest.mock import MagicMock, patch +import pytest +import pytest_asyncio from fastapi import FastAPI -from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine from httpx import AsyncClient from httpx_ws.transport import ASGIWebSocketTransport -from unittest.mock import MagicMock, patch -from pathlib import Path -from typing import AsyncGenerator, Any +from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine -from gns3server.controller import Controller -from gns3server.config import Config +from gns3server import schemas +from gns3server.api.routes.controller.dependencies.database import get_db_session from gns3server.compute import MODULES from gns3server.compute.port_manager import PortManager from gns3server.compute.project_manager import ProjectManager -from gns3server.db.models import Base, User, Compute -from gns3server.db.repositories.users import UsersRepository +from gns3server.config import Config +from gns3server.controller import Controller +from gns3server.db.models import Base, Compute, User from gns3server.db.repositories.computes import ComputesRepository -from gns3server.api.routes.controller.dependencies.database import get_db_session -from gns3server import schemas +from gns3server.db.repositories.users import UsersRepository from gns3server.schemas.controller.computes import Protocol from gns3server.services import auth_service from gns3server.services.authentication import DEFAULT_JWT_SECRET_KEY diff --git a/tests/controller/gns3vm/test_remote_gns3_vm.py b/tests/controller/gns3vm/test_remote_gns3_vm.py index 5b475a174..be1620869 100644 --- a/tests/controller/gns3vm/test_remote_gns3_vm.py +++ b/tests/controller/gns3vm/test_remote_gns3_vm.py @@ -16,11 +16,11 @@ # along with this program. If not, see . import pytest - -from gns3server.controller.gns3vm.remote_gns3_vm import RemoteGNS3VM -from gns3server.controller.gns3vm.gns3_vm_error import GNS3VMError from pydantic import SecretStr +from gns3server.controller.gns3vm.gns3_vm_error import GNS3VMError +from gns3server.controller.gns3vm.remote_gns3_vm import RemoteGNS3VM + @pytest.fixture def gns3vm(controller): diff --git a/tests/controller/gns3vm/test_virtualbox_gns3_vm.py b/tests/controller/gns3vm/test_virtualbox_gns3_vm.py index 6ae3cc5a6..fe8f453c3 100644 --- a/tests/controller/gns3vm/test_virtualbox_gns3_vm.py +++ b/tests/controller/gns3vm/test_virtualbox_gns3_vm.py @@ -18,10 +18,9 @@ import pytest import pytest_asyncio -from tests.utils import asyncio_patch -from gns3server.utils.asyncio import wait_run_in_executor - from gns3server.controller.gns3vm.virtualbox_gns3_vm import VirtualBoxGNS3VM +from gns3server.utils.asyncio import wait_run_in_executor +from tests.utils import asyncio_patch @pytest_asyncio.fixture diff --git a/tests/controller/test_appliance.py b/tests/controller/test_appliance.py index 969d90d54..b18a6cb97 100644 --- a/tests/controller/test_appliance.py +++ b/tests/controller/test_appliance.py @@ -22,7 +22,6 @@ from gns3server.controller.appliance import Appliance from gns3server.controller.appliance_to_template import ApplianceToTemplate from gns3server.schemas.controller.appliances import ApplianceModel - # v8 mirror of the XRd Control Plane appliance shape (docker, custom_adapters, no versions) XRD_V8 = { "registry_version": 8, diff --git a/tests/controller/test_appliance_manager.py b/tests/controller/test_appliance_manager.py index 38c343181..0700b0312 100644 --- a/tests/controller/test_appliance_manager.py +++ b/tests/controller/test_appliance_manager.py @@ -16,6 +16,7 @@ # along with this program. If not, see . import uuid + import pytest from gns3server.controller.appliance import Appliance diff --git a/tests/controller/test_appliance_to_template.py b/tests/controller/test_appliance_to_template.py index a50338370..9faff12b4 100644 --- a/tests/controller/test_appliance_to_template.py +++ b/tests/controller/test_appliance_to_template.py @@ -15,14 +15,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest import pydantic +import pytest from gns3server.controller.appliance_to_template import ApplianceToTemplate from gns3server.controller.controller_error import ControllerError from gns3server.schemas.controller.appliances import ApplianceModel - # reduced mirror of the upstream vyos.gns3a (registry version 8, qemu, 2 settings sets) VYOS_V8 = { "registry_version": 8, diff --git a/tests/controller/test_compute.py b/tests/controller/test_compute.py index 04ed1d740..9a05e7c27 100644 --- a/tests/controller/test_compute.py +++ b/tests/controller/test_compute.py @@ -15,25 +15,26 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys -import json import asyncio +import json +import sys +from types import SimpleNamespace +from unittest.mock import MagicMock, patch + import aiohttp import pytest -from types import SimpleNamespace -from unittest.mock import patch, MagicMock +from pydantic import SecretStr -from gns3server.controller.project import Project -from gns3server.controller.compute import Compute from gns3server.api.server import app as gns3_app +from gns3server.controller.compute import Compute from gns3server.controller.controller_error import ( + ComputeConflictError, ControllerError, ControllerNotFoundError, ControllerUnauthorizedError, - ComputeConflictError, ) -from pydantic import SecretStr -from tests.utils import asyncio_patch, AsyncioMagicMock +from gns3server.controller.project import Project +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest.fixture diff --git a/tests/controller/test_controller.py b/tests/controller/test_controller.py index 18edb22ee..355576d3f 100644 --- a/tests/controller/test_controller.py +++ b/tests/controller/test_controller.py @@ -15,21 +15,21 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os -import uuid -import json import asyncio -import pytest +import json +import os import socket +import uuid from unittest.mock import MagicMock, patch -from tests.utils import AsyncioMagicMock, asyncio_patch -from watchdog.events import FileCreatedEvent, DirCreatedEvent +import pytest +from watchdog.events import DirCreatedEvent, FileCreatedEvent + +from gns3server.controller import _ProjectsDirectoryEventHandler from gns3server.controller.compute import Compute from gns3server.controller.controller_error import ControllerError, ControllerNotFoundError -from gns3server.controller import _ProjectsDirectoryEventHandler from gns3server.version import __version__ - +from tests.utils import AsyncioMagicMock, asyncio_patch # def test_save(controller, controller_config_path): # diff --git a/tests/controller/test_drawing.py b/tests/controller/test_drawing.py index cd7946e10..b80e404af 100644 --- a/tests/controller/test_drawing.py +++ b/tests/controller/test_drawing.py @@ -15,14 +15,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from unittest.mock import MagicMock -import pytest -import uuid import os +import uuid +from unittest.mock import MagicMock -from tests.utils import AsyncioMagicMock +import pytest from gns3server.controller.drawing import Drawing +from tests.utils import AsyncioMagicMock @pytest.fixture diff --git a/tests/controller/test_export_project.py b/tests/controller/test_export_project.py index 5927a7e66..3f4009c9a 100644 --- a/tests/controller/test_export_project.py +++ b/tests/controller/test_export_project.py @@ -16,22 +16,21 @@ # along with this program. If not, see . -import os import json +import os +import stat +import zipfile +from pathlib import Path +from unittest.mock import MagicMock, patch + import pytest import pytest_asyncio -import zipfile -import stat -from pathlib import Path -from unittest.mock import patch -from unittest.mock import MagicMock -from tests.utils import AsyncioMagicMock, AsyncioBytesIO - -from gns3server.controller.project import Project -from gns3server.controller.export_project import export_project, _is_exportable -from gns3server.utils.asyncio import aiozipstream from gns3server.controller.controller_error import ControllerError +from gns3server.controller.export_project import _is_exportable, export_project +from gns3server.controller.project import Project +from gns3server.utils.asyncio import aiozipstream +from tests.utils import AsyncioBytesIO, AsyncioMagicMock @pytest_asyncio.fixture diff --git a/tests/controller/test_gns3vm.py b/tests/controller/test_gns3vm.py index 48af40493..d9832e4f5 100644 --- a/tests/controller/test_gns3vm.py +++ b/tests/controller/test_gns3vm.py @@ -15,13 +15,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest import sys -from tests.utils import asyncio_patch, AsyncioMagicMock + +import pytest +from pydantic import SecretStr from gns3server.controller.gns3vm import GNS3VM from gns3server.controller.gns3vm.gns3_vm_error import GNS3VMError -from pydantic import SecretStr +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest.fixture diff --git a/tests/controller/test_import_project.py b/tests/controller/test_import_project.py index b7d7ea042..792d3c012 100644 --- a/tests/controller/test_import_project.py +++ b/tests/controller/test_import_project.py @@ -15,23 +15,22 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest +import json import os import uuid -import json import zipfile +from pathlib import Path +from unittest.mock import MagicMock, patch + import pytest -from pathlib import Path -from tests.utils import asyncio_patch, AsyncioMagicMock -from unittest.mock import patch, MagicMock - -from gns3server.utils.asyncio import aiozipstream -from gns3server.controller.project import Project from gns3server.controller.controller_error import ControllerError from gns3server.controller.export_project import export_project -from gns3server.controller.import_project import import_project, _move_files_to_compute +from gns3server.controller.import_project import _move_files_to_compute, import_project +from gns3server.controller.project import Project +from gns3server.utils.asyncio import aiozipstream from gns3server.version import __version__ +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest.mark.asyncio diff --git a/tests/controller/test_link.py b/tests/controller/test_link.py index 1cfcdb9bf..12436abb5 100644 --- a/tests/controller/test_link.py +++ b/tests/controller/test_link.py @@ -15,15 +15,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest -import pytest_asyncio from unittest.mock import MagicMock +import pytest +import pytest_asyncio + +from gns3server.controller.controller_error import ControllerError from gns3server.controller.link import Link from gns3server.controller.node import Node from gns3server.controller.ports.ethernet_port import EthernetPort from gns3server.controller.ports.serial_port import SerialPort -from gns3server.controller.controller_error import ControllerError from tests.utils import AsyncioBytesIO, AsyncioMagicMock diff --git a/tests/controller/test_marker.py b/tests/controller/test_marker.py index ec23b5d2d..bc27772c5 100644 --- a/tests/controller/test_marker.py +++ b/tests/controller/test_marker.py @@ -25,18 +25,17 @@ Controller-layer tests for the traffic-insight marker feature: """ import uuid +from contextlib import ExitStack +from unittest.mock import MagicMock, patch import pytest -from unittest.mock import MagicMock, patch -from contextlib import ExitStack -from tests.utils import AsyncioMagicMock - -from gns3server.controller.udp_link import UDPLink +from gns3server.controller.controller_error import ControllerError, ControllerNotFoundError +from gns3server.controller.node import Node from gns3server.controller.ports.ethernet_port import EthernetPort from gns3server.controller.ports.serial_port import SerialPort -from gns3server.controller.node import Node -from gns3server.controller.controller_error import ControllerError, ControllerNotFoundError +from gns3server.controller.udp_link import UDPLink +from tests.utils import AsyncioMagicMock def _valid_bpf(): diff --git a/tests/controller/test_marker_replay.py b/tests/controller/test_marker_replay.py index e958d3888..7939b9a03 100644 --- a/tests/controller/test_marker_replay.py +++ b/tests/controller/test_marker_replay.py @@ -43,25 +43,25 @@ from unittest.mock import patch import pytest +from gns3server.controller import marker_replay from gns3server.controller.controller_error import ( ControllerBadRequestError, ControllerError, ControllerNotFoundError, ) -from gns3server.controller import marker_replay from gns3server.controller.marker_replay import ( FilterError, SharkdError, SharkdMissingError, + _count_tree_nodes, + _format_ts, + _parse_ts, + _rename_value, build_timeline, decode_frame, query_frames, read_frame_bytes, scan_pcap_frames, - _count_tree_nodes, - _format_ts, - _parse_ts, - _rename_value, ) pytestmark = pytest.mark.asyncio diff --git a/tests/controller/test_node.py b/tests/controller/test_node.py index 300d410bd..717537a37 100644 --- a/tests/controller/test_node.py +++ b/tests/controller/test_node.py @@ -15,18 +15,18 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import shutil -import pytest -import uuid import os +import shutil +import uuid +from unittest.mock import ANY, MagicMock + +import pytest -from unittest.mock import MagicMock, ANY -from tests.utils import AsyncioMagicMock, asyncio_patch from gns3server.compute.docker.docker_error import DockerError - +from gns3server.controller.controller_error import ComputeConflictError, ControllerError from gns3server.controller.node import Node from gns3server.controller.project import Project -from gns3server.controller.controller_error import ComputeConflictError, ControllerError +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest.fixture diff --git a/tests/controller/test_node_port_name.py b/tests/controller/test_node_port_name.py index bfd108197..76dee1f2f 100644 --- a/tests/controller/test_node_port_name.py +++ b/tests/controller/test_node_port_name.py @@ -15,13 +15,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest import uuid -from tests.utils import AsyncioMagicMock +import pytest from gns3server.controller.node import Node from gns3server.controller.ports.ethernet_port import EthernetPort +from tests.utils import AsyncioMagicMock @pytest.fixture diff --git a/tests/controller/test_notification.py b/tests/controller/test_notification.py index 1369a9b11..53e24f1f2 100644 --- a/tests/controller/test_notification.py +++ b/tests/controller/test_notification.py @@ -15,9 +15,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from unittest.mock import MagicMock + import pytest import pytest_asyncio -from unittest.mock import MagicMock from tests.utils import AsyncioMagicMock diff --git a/tests/controller/test_project.py b/tests/controller/test_project.py index 8256dd450..3a5d3b175 100644 --- a/tests/controller/test_project.py +++ b/tests/controller/test_project.py @@ -15,26 +15,26 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os import json +import os import uuid -import pytest -import pytest_asyncio -from unittest.mock import MagicMock -from tests.utils import AsyncioMagicMock, asyncio_patch -from unittest.mock import patch +from unittest.mock import MagicMock, patch from uuid import uuid4 -from gns3server.controller.project import Project +import pytest +import pytest_asyncio + +from gns3server.config import Config +from gns3server.controller.controller_error import ( + ComputeConflictError, + ControllerError, + ControllerForbiddenError, + ControllerNotFoundError, +) from gns3server.controller.node import Node from gns3server.controller.ports.ethernet_port import EthernetPort -from gns3server.controller.controller_error import ( - ControllerError, - ControllerNotFoundError, - ControllerForbiddenError, - ComputeConflictError, -) -from gns3server.config import Config +from gns3server.controller.project import Project +from tests.utils import AsyncioMagicMock, asyncio_patch @pytest_asyncio.fixture diff --git a/tests/controller/test_project_open.py b/tests/controller/test_project_open.py index 1d5ce49d9..f3830bee3 100644 --- a/tests/controller/test_project_open.py +++ b/tests/controller/test_project_open.py @@ -15,14 +15,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os import json -import pytest +import os -from tests.utils import asyncio_patch +import pytest from gns3server.controller.compute import Compute from gns3server.controller.project import Project +from tests.utils import asyncio_patch @pytest.fixture diff --git a/tests/controller/test_rbac.py b/tests/controller/test_rbac.py index b332f20e0..6dd3b7dd2 100644 --- a/tests/controller/test_rbac.py +++ b/tests/controller/test_rbac.py @@ -15,22 +15,22 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest -import pytest_asyncio import uuid +import pytest +import pytest_asyncio from fastapi import FastAPI, status from httpx import AsyncClient from httpx_ws.transport import ASGIWebSocketTransport - from sqlalchemy.ext.asyncio import AsyncSession + from gns3server.controller import Controller +from gns3server.db.models import User +from gns3server.db.repositories.pools import ResourcePoolsRepository from gns3server.db.repositories.rbac import RbacRepository from gns3server.db.repositories.users import UsersRepository -from gns3server.db.repositories.pools import ResourcePoolsRepository -from gns3server.schemas.controller.rbac import ACECreate from gns3server.schemas.controller.pools import ResourceCreate, ResourcePoolCreate -from gns3server.db.models import User +from gns3server.schemas.controller.rbac import ACECreate from gns3server.services import auth_service pytestmark = pytest.mark.asyncio diff --git a/tests/controller/test_snapshot.py b/tests/controller/test_snapshot.py index 008d0bb57..4e4a1a4a5 100644 --- a/tests/controller/test_snapshot.py +++ b/tests/controller/test_snapshot.py @@ -16,13 +16,13 @@ # along with this program. If not, see . import os +from unittest import mock +from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest -from unittest import mock -from unittest.mock import patch, MagicMock -from gns3server.controller.snapshot import Snapshot +from gns3server.controller.snapshot import Snapshot from tests.utils import AsyncioMagicMock diff --git a/tests/controller/test_symbols.py b/tests/controller/test_symbols.py index 3856427fb..ee9eda8c5 100644 --- a/tests/controller/test_symbols.py +++ b/tests/controller/test_symbols.py @@ -17,8 +17,8 @@ import os -from gns3server.controller.symbols import Symbols from gns3server.controller.symbol_themes import BUILTIN_SYMBOL_THEMES +from gns3server.controller.symbols import Symbols from gns3server.utils.get_resource import get_resource diff --git a/tests/controller/test_topology.py b/tests/controller/test_topology.py index 3419aa794..2e2d5c4ff 100644 --- a/tests/controller/test_topology.py +++ b/tests/controller/test_topology.py @@ -17,15 +17,16 @@ import json import uuid -import pytest from unittest.mock import MagicMock, patch -from tests.utils import asyncio_patch -from gns3server.controller.project import Project +import pytest + from gns3server.controller.compute import Compute -from gns3server.controller.topology import project_to_topology, load_topology, GNS3_FILE_FORMAT_REVISION from gns3server.controller.controller_error import ControllerError +from gns3server.controller.project import Project +from gns3server.controller.topology import GNS3_FILE_FORMAT_REVISION, load_topology, project_to_topology from gns3server.version import __version__ +from tests.utils import asyncio_patch @pytest.mark.asyncio diff --git a/tests/controller/test_udp_link.py b/tests/controller/test_udp_link.py index 7c433a6fb..4a055ae8a 100644 --- a/tests/controller/test_udp_link.py +++ b/tests/controller/test_udp_link.py @@ -15,14 +15,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest from unittest.mock import MagicMock -from tests.utils import AsyncioMagicMock -from gns3server.controller.udp_link import UDPLink -from gns3server.controller.ports.ethernet_port import EthernetPort -from gns3server.controller.node import Node +import pytest + from gns3server.controller.controller_error import ControllerError +from gns3server.controller.node import Node +from gns3server.controller.ports.ethernet_port import EthernetPort +from gns3server.controller.udp_link import UDPLink +from tests.utils import AsyncioMagicMock @pytest.mark.asyncio diff --git a/tests/services/test_image_reconciliation.py b/tests/services/test_image_reconciliation.py index fa8e9beba..c0351ffe0 100644 --- a/tests/services/test_image_reconciliation.py +++ b/tests/services/test_image_reconciliation.py @@ -1,26 +1,26 @@ import asyncio import hashlib import os +import subprocess import sys import threading -import subprocess -from types import SimpleNamespace from pathlib import Path -from unittest.mock import patch, AsyncMock +from types import SimpleNamespace +from unittest.mock import AsyncMock, patch import pytest import pytest_asyncio -from sqlalchemy import select, text, event -from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine +from sqlalchemy import event, select, text from sqlalchemy.exc import SQLAlchemyError -from watchdog.events import FileMovedEvent, FileDeletedEvent, FileModifiedEvent +from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine +from watchdog.events import FileDeletedEvent, FileModifiedEvent, FileMovedEvent from gns3server.db.models import Base, Image, ImageSyncJob, Template from gns3server.db.models.images import image_template_map from gns3server.db.repositories.images import ImagesRepository from gns3server.services.image_reconciliation import ImageReconciliationService, InventoryEvents, enumerate_root -from gns3server.utils.image_inventory import ImageLockBusy, image_lock, fingerprint -from gns3server.utils.images import write_image, inspect_image_file, md5sum, InvalidImageError +from gns3server.utils.image_inventory import ImageLockBusy, fingerprint, image_lock +from gns3server.utils.images import InvalidImageError, inspect_image_file, md5sum, write_image pytestmark = pytest.mark.asyncio QCOW = b"QFI\xfb\x00\x00\x00" @@ -633,6 +633,7 @@ async def test_startup_upgrades_unversioned_existing_catalog(inventory, config, from alembic import command from alembic.config import Config from fastapi import FastAPI + from gns3server.db.tasks import connect_to_db, disconnect_from_db image_file(config) @@ -665,7 +666,9 @@ async def test_startup_upgrades_unversioned_existing_catalog(inventory, config, @pytest.mark.parametrize("reuse_id", [False, True]) async def test_delete_preserves_replacement_created_while_waiting_for_lock(inventory, config, operation, reuse_id): from contextlib import asynccontextmanager + from sqlalchemy import delete + from gns3server.api.routes.controller.images import delete_image from gns3server.controller.controller_error import ControllerError diff --git a/tests/stress/benchmark_running_server.py b/tests/stress/benchmark_running_server.py index fcc5e7640..c19187a7e 100644 --- a/tests/stress/benchmark_running_server.py +++ b/tests/stress/benchmark_running_server.py @@ -6,10 +6,10 @@ This test connects to an already running GNS3 server and measures the response time of the GET /projects endpoint. """ -import asyncio -import time import argparse +import asyncio import sys +import time import uuid from pathlib import Path diff --git a/tests/stress/telnet_race_condition_test.py b/tests/stress/telnet_race_condition_test.py index e808d319f..be996cc4b 100644 --- a/tests/stress/telnet_race_condition_test.py +++ b/tests/stress/telnet_race_condition_test.py @@ -10,12 +10,12 @@ Usage: python telnet_race_condition_test.py --host 127.0.0.1 --port 2000 --connections 10 """ -import asyncio import argparse +import asyncio import logging +import sys import time from typing import List, Optional -import sys # Configure logging logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") diff --git a/tests/test_config.py b/tests/test_config.py index fb2b08dc0..50e9318d2 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -17,13 +17,12 @@ import configparser import os -import pytest -from gns3server.config import Config -from gns3server.config import ConfigConflictError -from gns3server.config import ServerConfig +import pytest from pydantic import ValidationError +from gns3server.config import Config, ConfigConflictError, ServerConfig + def load_config(tmpdir, settings): """ diff --git a/tests/test_server.py b/tests/test_server.py index 7cdb2cb12..95f644503 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -16,13 +16,14 @@ # along with this program. If not, see . -import pytest import locale import tempfile +import pytest + +from gns3server.config import Config from gns3server.main import parse_arguments as parse from gns3server.server import Server -from gns3server.config import Config def test_locale_check(): diff --git a/tests/test_topologies.py b/tests/test_topologies.py index e763d47b9..c4320658f 100644 --- a/tests/test_topologies.py +++ b/tests/test_topologies.py @@ -21,13 +21,13 @@ # # Read tests/topologies/README.rst for documentation -import os import json -import pytest +import os import shutil +import pytest -from gns3server.controller.topology import load_topology, GNS3_FILE_FORMAT_REVISION +from gns3server.controller.topology import GNS3_FILE_FORMAT_REVISION, load_topology from gns3server.version import __version__ topologies_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), "topologies") diff --git a/tests/utils.py b/tests/utils.py index d7212a666..a2fb8e48c 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -14,9 +14,9 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import asyncio import io import types -import asyncio import unittest.mock diff --git a/tests/utils/asyncio/test_ssh_server.py b/tests/utils/asyncio/test_ssh_server.py index 7f6d094a9..694bfd20c 100644 --- a/tests/utils/asyncio/test_ssh_server.py +++ b/tests/utils/asyncio/test_ssh_server.py @@ -6,7 +6,6 @@ import pytest from gns3server.utils.asyncio.ssh_server import AsyncioSSHServer - # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- diff --git a/tests/utils/test_asyncio.py b/tests/utils/test_asyncio.py index 87def33c4..04a9e3c1c 100644 --- a/tests/utils/test_asyncio.py +++ b/tests/utils/test_asyncio.py @@ -16,9 +16,10 @@ import asyncio + import pytest -from gns3server.utils.asyncio import wait_run_in_executor, subprocess_check_output, locking +from gns3server.utils.asyncio import locking, subprocess_check_output, wait_run_in_executor @pytest.mark.asyncio diff --git a/tests/utils/test_file_watcher.py b/tests/utils/test_file_watcher.py index 83b9761ec..80911276b 100644 --- a/tests/utils/test_file_watcher.py +++ b/tests/utils/test_file_watcher.py @@ -15,10 +15,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pytest import asyncio from unittest.mock import MagicMock +import pytest from gns3server.utils.file_watcher import FileWatcher diff --git a/tests/utils/test_images.py b/tests/utils/test_images.py index e7d8248b0..404540337 100644 --- a/tests/utils/test_images.py +++ b/tests/utils/test_images.py @@ -17,12 +17,12 @@ import os import sys import threading -import pytest from unittest.mock import patch +import pytest from gns3server.utils import force_unix_path -from gns3server.utils.images import md5sum, remove_checksum, images_directories, list_images +from gns3server.utils.images import images_directories, list_images, md5sum, remove_checksum def test_images_directories(tmpdir, config): diff --git a/tests/utils/test_interfaces.py b/tests/utils/test_interfaces.py index 84ac5f7c3..9c6c340c8 100644 --- a/tests/utils/test_interfaces.py +++ b/tests/utils/test_interfaces.py @@ -14,15 +14,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys -import socket import collections +import socket +import sys from unittest.mock import patch import psutil -from gns3server.utils.interfaces import interfaces, is_interface_up, has_netmask - +from gns3server.utils.interfaces import has_netmask, interfaces, is_interface_up # psutil returns snicaddr namedtuples; mirror that shape for the mocks below. snicaddr = collections.namedtuple("snicaddr", ["family", "address", "netmask", "broadcast", "ptp"]) diff --git a/tests/utils/test_notification_queue.py b/tests/utils/test_notification_queue.py index 769a93e98..79e293fa5 100644 --- a/tests/utils/test_notification_queue.py +++ b/tests/utils/test_notification_queue.py @@ -14,8 +14,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import time import asyncio +import time import pytest diff --git a/tests/utils/test_packet_filter_validation.py b/tests/utils/test_packet_filter_validation.py index a5ba0cbe8..462e23a4d 100644 --- a/tests/utils/test_packet_filter_validation.py +++ b/tests/utils/test_packet_filter_validation.py @@ -3,11 +3,12 @@ Unit tests for packet filter validation. """ import pytest + from gns3server.utils.packet_filter_validation import ( - validate_filter_parameters, - validate_all_filters, - filter_inactive_filters, FilterValidationError, + filter_inactive_filters, + validate_all_filters, + validate_filter_parameters, ) diff --git a/tests/utils/test_path.py b/tests/utils/test_path.py index b31aeb968..454871826 100644 --- a/tests/utils/test_path.py +++ b/tests/utils/test_path.py @@ -16,8 +16,8 @@ # along with this program. If not, see . import os -import pytest +import pytest from fastapi import HTTPException from gns3server.utils.path import check_path_allowed, get_default_project_directory