diff --git a/.gitignore b/.gitignore
index 74b96a15..4e4a2baa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,9 @@ __pycache__
#py.test
.cache
+# environment file
+.env
+
# C extensions
*.so
diff --git a/gns3server/ubridge/__init__.py b/gns3server/api/__init__.py
similarity index 100%
rename from gns3server/ubridge/__init__.py
rename to gns3server/api/__init__.py
diff --git a/gns3server/api/middlewares.py b/gns3server/api/middlewares.py
new file mode 100644
index 00000000..48f84e34
--- /dev/null
+++ b/gns3server/api/middlewares.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2020 GNS3 Technologies Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import time
+from starlette.types import ASGIApp, Message, Receive, Scope, Send
+from gns3server.version import __version__
+
+
+class AddExtraHeadersMiddleware:
+
+ def __init__(self, app: ASGIApp) -> None:
+ self.app = app
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+
+
+ if scope["type"] in ("http", "websocket") and scope["scheme"] in ("http", "ws"):
+ url = URL(scope=scope)
+ redirect_scheme = {"http": "https", "ws": "wss"}[url.scheme]
+ netloc = url.hostname if url.port in (80, 443) else url.netloc
+ url = url.replace(scheme=redirect_scheme, netloc=netloc)
+ response = RedirectResponse(url, status_code=307)
+ await response(scope, receive, send)
+
+
+@app.middleware("http")
+async def add_extra_headers(request: Request, call_next):
+ start_time = time.time()
+ response = await call_next(request)
+ process_time = time.time() - start_time
+ response.headers["X-Process-Time"] = str(process_time)
+ response.headers["X-GNS3-Server-Version"] = "{}".format(__version__)
+ return response
diff --git a/tests/endpoints/__init__.py b/gns3server/api/routes/__init__.py
similarity index 100%
rename from tests/endpoints/__init__.py
rename to gns3server/api/routes/__init__.py
diff --git a/gns3server/endpoints/compute/atm_switch_nodes.py b/gns3server/api/routes/compute/atm_switch_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/atm_switch_nodes.py
rename to gns3server/api/routes/compute/atm_switch_nodes.py
index 7b09a5fb..f7482ab9 100644
--- a/gns3server/endpoints/compute/atm_switch_nodes.py
+++ b/gns3server/api/routes/compute/atm_switch_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for ATM switch nodes.
+API routes for ATM switch nodes.
"""
import os
diff --git a/gns3server/endpoints/compute/capabilities.py b/gns3server/api/routes/compute/capabilities.py
similarity index 97%
rename from gns3server/endpoints/compute/capabilities.py
rename to gns3server/api/routes/compute/capabilities.py
index 67f0d567..97210a31 100644
--- a/gns3server/endpoints/compute/capabilities.py
+++ b/gns3server/api/routes/compute/capabilities.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for capabilities
+API routes for capabilities
"""
import sys
diff --git a/gns3server/endpoints/compute/cloud_nodes.py b/gns3server/api/routes/compute/cloud_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/cloud_nodes.py
rename to gns3server/api/routes/compute/cloud_nodes.py
index 631c0341..e19895f2 100644
--- a/gns3server/endpoints/compute/cloud_nodes.py
+++ b/gns3server/api/routes/compute/cloud_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for cloud nodes.
+API routes for cloud nodes.
"""
import os
diff --git a/gns3server/endpoints/compute/compute.py b/gns3server/api/routes/compute/compute.py
similarity index 99%
rename from gns3server/endpoints/compute/compute.py
rename to gns3server/api/routes/compute/compute.py
index 854428e0..983877a3 100644
--- a/gns3server/endpoints/compute/compute.py
+++ b/gns3server/api/routes/compute/compute.py
@@ -17,7 +17,7 @@
"""
-API endpoints for compute.
+API routes for compute.
"""
import os
diff --git a/gns3server/endpoints/compute/docker_nodes.py b/gns3server/api/routes/compute/docker_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/docker_nodes.py
rename to gns3server/api/routes/compute/docker_nodes.py
index e88664ef..b2492a70 100644
--- a/gns3server/endpoints/compute/docker_nodes.py
+++ b/gns3server/api/routes/compute/docker_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for Docker nodes.
+API routes for Docker nodes.
"""
import os
diff --git a/gns3server/endpoints/compute/dynamips_nodes.py b/gns3server/api/routes/compute/dynamips_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/dynamips_nodes.py
rename to gns3server/api/routes/compute/dynamips_nodes.py
index 6ba57047..287cbda4 100644
--- a/gns3server/endpoints/compute/dynamips_nodes.py
+++ b/gns3server/api/routes/compute/dynamips_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for Dynamips nodes.
+API routes for Dynamips nodes.
"""
import os
diff --git a/gns3server/endpoints/compute/ethernet_hub_nodes.py b/gns3server/api/routes/compute/ethernet_hub_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/ethernet_hub_nodes.py
rename to gns3server/api/routes/compute/ethernet_hub_nodes.py
index 06c46248..64aca56d 100644
--- a/gns3server/endpoints/compute/ethernet_hub_nodes.py
+++ b/gns3server/api/routes/compute/ethernet_hub_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for Ethernet hub nodes.
+API routes for Ethernet hub nodes.
"""
import os
diff --git a/gns3server/endpoints/compute/ethernet_switch_nodes.py b/gns3server/api/routes/compute/ethernet_switch_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/ethernet_switch_nodes.py
rename to gns3server/api/routes/compute/ethernet_switch_nodes.py
index 051338e3..60c19851 100644
--- a/gns3server/endpoints/compute/ethernet_switch_nodes.py
+++ b/gns3server/api/routes/compute/ethernet_switch_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for Ethernet switch nodes.
+API routes for Ethernet switch nodes.
"""
import os
diff --git a/gns3server/endpoints/compute/frame_relay_switch_nodes.py b/gns3server/api/routes/compute/frame_relay_switch_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/frame_relay_switch_nodes.py
rename to gns3server/api/routes/compute/frame_relay_switch_nodes.py
index 2728e81b..727ad8a4 100644
--- a/gns3server/endpoints/compute/frame_relay_switch_nodes.py
+++ b/gns3server/api/routes/compute/frame_relay_switch_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for Frame Relay switch nodes.
+API routes for Frame Relay switch nodes.
"""
import os
diff --git a/gns3server/endpoints/compute/images.py b/gns3server/api/routes/compute/images.py
similarity index 99%
rename from gns3server/endpoints/compute/images.py
rename to gns3server/api/routes/compute/images.py
index dc71d71b..af1a42bc 100644
--- a/gns3server/endpoints/compute/images.py
+++ b/gns3server/api/routes/compute/images.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for images.
+API routes for images.
"""
import os
diff --git a/gns3server/endpoints/compute/iou_nodes.py b/gns3server/api/routes/compute/iou_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/iou_nodes.py
rename to gns3server/api/routes/compute/iou_nodes.py
index be3320d9..09a0333e 100644
--- a/gns3server/endpoints/compute/iou_nodes.py
+++ b/gns3server/api/routes/compute/iou_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for IOU nodes.
+API routes for IOU nodes.
"""
import os
diff --git a/gns3server/endpoints/compute/nat_nodes.py b/gns3server/api/routes/compute/nat_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/nat_nodes.py
rename to gns3server/api/routes/compute/nat_nodes.py
index de255126..5c3914bb 100644
--- a/gns3server/endpoints/compute/nat_nodes.py
+++ b/gns3server/api/routes/compute/nat_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for NAT nodes.
+API routes for NAT nodes.
"""
import os
diff --git a/gns3server/endpoints/compute/notifications.py b/gns3server/api/routes/compute/notifications.py
similarity index 98%
rename from gns3server/endpoints/compute/notifications.py
rename to gns3server/api/routes/compute/notifications.py
index ab2662f2..fd2ad568 100644
--- a/gns3server/endpoints/compute/notifications.py
+++ b/gns3server/api/routes/compute/notifications.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for compute notifications.
+API routes for compute notifications.
"""
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
diff --git a/gns3server/endpoints/compute/projects.py b/gns3server/api/routes/compute/projects.py
similarity index 99%
rename from gns3server/endpoints/compute/projects.py
rename to gns3server/api/routes/compute/projects.py
index dda59bc7..f622858e 100644
--- a/gns3server/endpoints/compute/projects.py
+++ b/gns3server/api/routes/compute/projects.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for projects.
+API routes for projects.
"""
import os
diff --git a/gns3server/endpoints/compute/qemu_nodes.py b/gns3server/api/routes/compute/qemu_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/qemu_nodes.py
rename to gns3server/api/routes/compute/qemu_nodes.py
index 5e8ca4d0..33877321 100644
--- a/gns3server/endpoints/compute/qemu_nodes.py
+++ b/gns3server/api/routes/compute/qemu_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for Qemu nodes.
+API routes for Qemu nodes.
"""
import os
diff --git a/gns3server/endpoints/compute/virtualbox_nodes.py b/gns3server/api/routes/compute/virtualbox_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/virtualbox_nodes.py
rename to gns3server/api/routes/compute/virtualbox_nodes.py
index 42b1df5c..c516b5fb 100644
--- a/gns3server/endpoints/compute/virtualbox_nodes.py
+++ b/gns3server/api/routes/compute/virtualbox_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for VirtualBox nodes.
+API routes for VirtualBox nodes.
"""
import os
diff --git a/gns3server/endpoints/compute/vmware_nodes.py b/gns3server/api/routes/compute/vmware_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/vmware_nodes.py
rename to gns3server/api/routes/compute/vmware_nodes.py
index 2c706b77..ce9a7616 100644
--- a/gns3server/endpoints/compute/vmware_nodes.py
+++ b/gns3server/api/routes/compute/vmware_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for VMware nodes.
+API routes for VMware nodes.
"""
import os
diff --git a/gns3server/endpoints/compute/vpcs_nodes.py b/gns3server/api/routes/compute/vpcs_nodes.py
similarity index 99%
rename from gns3server/endpoints/compute/vpcs_nodes.py
rename to gns3server/api/routes/compute/vpcs_nodes.py
index ed1483ad..3e137cbf 100644
--- a/gns3server/endpoints/compute/vpcs_nodes.py
+++ b/gns3server/api/routes/compute/vpcs_nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for VPCS nodes.
+API routes for VPCS nodes.
"""
import os
diff --git a/gns3server/endpoints/controller/__init__.py b/gns3server/api/routes/controller/__init__.py
similarity index 100%
rename from gns3server/endpoints/controller/__init__.py
rename to gns3server/api/routes/controller/__init__.py
diff --git a/gns3server/endpoints/controller/appliances.py b/gns3server/api/routes/controller/appliances.py
similarity index 97%
rename from gns3server/endpoints/controller/appliances.py
rename to gns3server/api/routes/controller/appliances.py
index 3f10d0f3..466cca28 100644
--- a/gns3server/endpoints/controller/appliances.py
+++ b/gns3server/api/routes/controller/appliances.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for appliances.
+API routes for appliances.
"""
from fastapi import APIRouter
diff --git a/gns3server/endpoints/controller/computes.py b/gns3server/api/routes/controller/computes.py
similarity index 96%
rename from gns3server/endpoints/controller/computes.py
rename to gns3server/api/routes/controller/computes.py
index 8d33e4b6..cc76a245 100644
--- a/gns3server/endpoints/controller/computes.py
+++ b/gns3server/api/routes/controller/computes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for computes.
+API routes for computes.
"""
from fastapi import APIRouter, status
@@ -118,7 +118,7 @@ async def get_images(compute_id: Union[str, UUID], emulator: str):
async def forward_get(compute_id: Union[str, UUID], emulator: str, endpoint_path: str):
"""
Forward a GET request to a compute.
- Read the full compute API documentation for available endpoints.
+ Read the full compute API documentation for available routes.
"""
compute = Controller.instance().get_compute(str(compute_id))
@@ -131,7 +131,7 @@ async def forward_get(compute_id: Union[str, UUID], emulator: str, endpoint_path
async def forward_post(compute_id: Union[str, UUID], emulator: str, endpoint_path: str, compute_data: dict):
"""
Forward a POST request to a compute.
- Read the full compute API documentation for available endpoints.
+ Read the full compute API documentation for available routes.
"""
compute = Controller.instance().get_compute(str(compute_id))
@@ -143,7 +143,7 @@ async def forward_post(compute_id: Union[str, UUID], emulator: str, endpoint_pat
async def forward_put(compute_id: Union[str, UUID], emulator: str, endpoint_path: str, compute_data: dict):
"""
Forward a PUT request to a compute.
- Read the full compute API documentation for available endpoints.
+ Read the full compute API documentation for available routes.
"""
compute = Controller.instance().get_compute(str(compute_id))
diff --git a/gns3server/endpoints/controller/controller.py b/gns3server/api/routes/controller/controller.py
similarity index 100%
rename from gns3server/endpoints/controller/controller.py
rename to gns3server/api/routes/controller/controller.py
diff --git a/gns3server/endpoints/controller/drawings.py b/gns3server/api/routes/controller/drawings.py
similarity index 99%
rename from gns3server/endpoints/controller/drawings.py
rename to gns3server/api/routes/controller/drawings.py
index 2baf14db..de217bfd 100644
--- a/gns3server/endpoints/controller/drawings.py
+++ b/gns3server/api/routes/controller/drawings.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for drawings.
+API routes for drawings.
"""
from fastapi import APIRouter, status
diff --git a/gns3server/endpoints/controller/gns3vm.py b/gns3server/api/routes/controller/gns3vm.py
similarity index 97%
rename from gns3server/endpoints/controller/gns3vm.py
rename to gns3server/api/routes/controller/gns3vm.py
index 9910df6b..0a42c88a 100644
--- a/gns3server/endpoints/controller/gns3vm.py
+++ b/gns3server/api/routes/controller/gns3vm.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for managing the GNS3 VM.
+API routes for managing the GNS3 VM.
"""
from fastapi import APIRouter
diff --git a/gns3server/endpoints/controller/links.py b/gns3server/api/routes/controller/links.py
similarity index 99%
rename from gns3server/endpoints/controller/links.py
rename to gns3server/api/routes/controller/links.py
index 0a3730aa..11050bde 100644
--- a/gns3server/endpoints/controller/links.py
+++ b/gns3server/api/routes/controller/links.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for links.
+API routes for links.
"""
import multidict
diff --git a/gns3server/endpoints/controller/nodes.py b/gns3server/api/routes/controller/nodes.py
similarity index 99%
rename from gns3server/endpoints/controller/nodes.py
rename to gns3server/api/routes/controller/nodes.py
index 20c7b303..f9deeed5 100644
--- a/gns3server/endpoints/controller/nodes.py
+++ b/gns3server/api/routes/controller/nodes.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for nodes.
+API routes for nodes.
"""
import aiohttp
diff --git a/gns3server/endpoints/controller/notifications.py b/gns3server/api/routes/controller/notifications.py
similarity index 98%
rename from gns3server/endpoints/controller/notifications.py
rename to gns3server/api/routes/controller/notifications.py
index 6f93d2df..2009ad0c 100644
--- a/gns3server/endpoints/controller/notifications.py
+++ b/gns3server/api/routes/controller/notifications.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for controller notifications.
+API routes for controller notifications.
"""
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
diff --git a/gns3server/endpoints/controller/projects.py b/gns3server/api/routes/controller/projects.py
similarity index 99%
rename from gns3server/endpoints/controller/projects.py
rename to gns3server/api/routes/controller/projects.py
index 6e965833..cd4e2e66 100644
--- a/gns3server/endpoints/controller/projects.py
+++ b/gns3server/api/routes/controller/projects.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for projects.
+API routes for projects.
"""
import os
diff --git a/gns3server/endpoints/controller/snapshots.py b/gns3server/api/routes/controller/snapshots.py
similarity index 98%
rename from gns3server/endpoints/controller/snapshots.py
rename to gns3server/api/routes/controller/snapshots.py
index 19c08419..2f3fd452 100644
--- a/gns3server/endpoints/controller/snapshots.py
+++ b/gns3server/api/routes/controller/snapshots.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for snapshots.
+API routes for snapshots.
"""
import logging
diff --git a/gns3server/endpoints/controller/symbols.py b/gns3server/api/routes/controller/symbols.py
similarity index 98%
rename from gns3server/endpoints/controller/symbols.py
rename to gns3server/api/routes/controller/symbols.py
index c4d9c0d8..c85ea7c3 100644
--- a/gns3server/endpoints/controller/symbols.py
+++ b/gns3server/api/routes/controller/symbols.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for symbols.
+API routes for symbols.
"""
import os
diff --git a/gns3server/endpoints/controller/templates.py b/gns3server/api/routes/controller/templates.py
similarity index 99%
rename from gns3server/endpoints/controller/templates.py
rename to gns3server/api/routes/controller/templates.py
index cf14f8cb..a8f014e0 100644
--- a/gns3server/endpoints/controller/templates.py
+++ b/gns3server/api/routes/controller/templates.py
@@ -16,7 +16,7 @@
# along with this program. If not, see .
"""
-API endpoints for templates.
+API routes for templates.
"""
import hashlib
diff --git a/gns3server/endpoints/index.py b/gns3server/api/routes/index.py
similarity index 100%
rename from gns3server/endpoints/index.py
rename to gns3server/api/routes/index.py
diff --git a/gns3server/app.py b/gns3server/api/server.py
similarity index 65%
rename from gns3server/app.py
rename to gns3server/api/server.py
index 46ec41e3..a50b7dfc 100644
--- a/gns3server/app.py
+++ b/gns3server/api/server.py
@@ -19,8 +19,6 @@
FastAPI app
"""
-import sys
-import asyncio
import time
from fastapi import FastAPI, Request
@@ -28,9 +26,7 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
-from gns3server.controller import Controller
-from gns3server.compute import MODULES
-from gns3server.compute.port_manager import PortManager
+
from gns3server.controller.controller_error import (
ControllerError,
ControllerNotFoundError,
@@ -39,15 +35,15 @@ from gns3server.controller.controller_error import (
ControllerUnauthorizedError
)
-from gns3server.endpoints import controller
-from gns3server.endpoints import index
-from gns3server.endpoints.compute import compute_api
-from gns3server.utils.http_client import HTTPClient
+from gns3server.api.routes import controller, index
+from gns3server.api.routes.compute import compute_api
+from gns3server.core import tasks
from gns3server.version import __version__
import logging
log = logging.getLogger(__name__)
+
app = FastAPI(title="GNS3 controller API",
description="This page describes the public controller API for GNS3",
version="v3")
@@ -71,6 +67,8 @@ app.add_middleware(
allow_headers=["*"],
)
+app.add_event_handler("startup", tasks.create_startup_handler(app))
+app.add_event_handler("shutdown", tasks.create_shutdown_handler(app))
app.include_router(index.router, tags=["Index"])
app.include_router(controller.router, prefix="/v3")
app.mount("/v3/compute", compute_api)
@@ -138,58 +136,3 @@ async def add_extra_headers(request: Request, call_next):
response.headers["X-Process-Time"] = str(process_time)
response.headers["X-GNS3-Server-Version"] = "{}".format(__version__)
return response
-
-
-@app.on_event("startup")
-async def startup_event():
-
- loop = asyncio.get_event_loop()
- logger = logging.getLogger("asyncio")
- logger.setLevel(logging.ERROR)
-
- if sys.platform.startswith("win"):
-
- # Add a periodic callback to give a chance to process signals on Windows
- # because asyncio.add_signal_handler() is not supported yet on that platform
- # otherwise the loop runs outside of signal module's ability to trap signals.
-
- def wakeup():
- loop.call_later(0.5, wakeup)
-
- loop.call_later(0.5, wakeup)
-
- if log.getEffectiveLevel() == logging.DEBUG:
- # On debug version we enable info that
- # coroutine is not called in a way await/await
- loop.set_debug(True)
-
- await Controller.instance().start()
- # Because with a large image collection
- # without md5sum already computed we start the
- # computing with server start
-
- from gns3server.compute.qemu import Qemu
- asyncio.ensure_future(Qemu.instance().list_images())
-
- for module in MODULES:
- log.debug("Loading module {}".format(module.__name__))
- m = module.instance()
- m.port_manager = PortManager.instance()
-
-
-@app.on_event("shutdown")
-async def shutdown_event():
-
- await HTTPClient.close_session()
- await Controller.instance().stop()
-
- for module in MODULES:
- log.debug("Unloading module {}".format(module.__name__))
- m = module.instance()
- await m.unload()
-
- if PortManager.instance().tcp_ports:
- log.warning("TCP ports are still used {}".format(PortManager.instance().tcp_ports))
-
- if PortManager.instance().udp_ports:
- log.warning("UDP ports are still used {}".format(PortManager.instance().udp_ports))
diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py
index 9d01af14..e0349a18 100644
--- a/gns3server/compute/base_node.py
+++ b/gns3server/compute/base_node.py
@@ -31,8 +31,8 @@ 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.telnet_server import AsyncioTelnetServer
-from ..ubridge.hypervisor import Hypervisor
-from ..ubridge.ubridge_error import UbridgeError
+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
diff --git a/gns3server/compute/builtin/nodes/cloud.py b/gns3server/compute/builtin/nodes/cloud.py
index 86f8d932..2a4597c4 100644
--- a/gns3server/compute/builtin/nodes/cloud.py
+++ b/gns3server/compute/builtin/nodes/cloud.py
@@ -21,7 +21,7 @@ import subprocess
from ...error import NodeError
from ...base_node import BaseNode
from ...nios.nio_udp import NIOUDP
-from ....ubridge.ubridge_error import UbridgeError
+from gns3server.compute.ubridge.ubridge_error import UbridgeError
import gns3server.utils.interfaces
import gns3server.utils.asyncio
diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py
index 0c4f9506..b5cb1cfc 100644
--- a/gns3server/compute/docker/docker_vm.py
+++ b/gns3server/compute/docker/docker_vm.py
@@ -35,7 +35,7 @@ from gns3server.utils.asyncio import wait_for_file_creation
from gns3server.utils.asyncio import monitor_process
from gns3server.utils.get_resource import get_resource
-from gns3server.ubridge.ubridge_error import UbridgeError, UbridgeNamespaceError
+from gns3server.compute.ubridge.ubridge_error import UbridgeError, UbridgeNamespaceError
from ..base_node import BaseNode
from ..adapters.ethernet_adapter import EthernetAdapter
diff --git a/gns3server/compute/iou/iou_vm.py b/gns3server/compute/iou/iou_vm.py
index 617b247e..97149ad4 100644
--- a/gns3server/compute/iou/iou_vm.py
+++ b/gns3server/compute/iou/iou_vm.py
@@ -40,7 +40,7 @@ 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.ubridge.ubridge_error import UbridgeError
+from gns3server.compute.ubridge.ubridge_error import UbridgeError
from gns3server.utils.file_watcher import FileWatcher
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
from gns3server.utils.asyncio import locking
diff --git a/gns3server/compute/notification_manager.py b/gns3server/compute/notification_manager.py
index 1024470f..f3e48ddf 100644
--- a/gns3server/compute/notification_manager.py
+++ b/gns3server/compute/notification_manager.py
@@ -17,7 +17,7 @@
from contextlib import contextmanager
-from ..notification_queue import NotificationQueue
+from gns3server.utils.notification_queue import NotificationQueue
class NotificationManager:
diff --git a/tests/endpoints/compute/__init__.py b/gns3server/compute/ubridge/__init__.py
similarity index 100%
rename from tests/endpoints/compute/__init__.py
rename to gns3server/compute/ubridge/__init__.py
diff --git a/gns3server/ubridge/hypervisor.py b/gns3server/compute/ubridge/hypervisor.py
similarity index 100%
rename from gns3server/ubridge/hypervisor.py
rename to gns3server/compute/ubridge/hypervisor.py
diff --git a/gns3server/ubridge/ubridge_error.py b/gns3server/compute/ubridge/ubridge_error.py
similarity index 100%
rename from gns3server/ubridge/ubridge_error.py
rename to gns3server/compute/ubridge/ubridge_error.py
diff --git a/gns3server/ubridge/ubridge_hypervisor.py b/gns3server/compute/ubridge/ubridge_hypervisor.py
similarity index 99%
rename from gns3server/ubridge/ubridge_hypervisor.py
rename to gns3server/compute/ubridge/ubridge_hypervisor.py
index 4fcf1d1f..1cbb6294 100644
--- a/gns3server/ubridge/ubridge_hypervisor.py
+++ b/gns3server/compute/ubridge/ubridge_hypervisor.py
@@ -20,7 +20,7 @@ import time
import logging
import asyncio
-from ..utils.asyncio import locking
+from gns3server.utils.asyncio import locking
from .ubridge_error import UbridgeError
log = logging.getLogger(__name__)
diff --git a/gns3server/controller/notification.py b/gns3server/controller/notification.py
index dddd21dd..6d72ed07 100644
--- a/gns3server/controller/notification.py
+++ b/gns3server/controller/notification.py
@@ -18,7 +18,7 @@
import os
from contextlib import contextmanager
-from ..notification_queue import NotificationQueue
+from gns3server.utils.notification_queue import NotificationQueue
from .controller_error import ControllerError
diff --git a/tests/endpoints/controller/__init__.py b/gns3server/core/__init__.py
similarity index 100%
rename from tests/endpoints/controller/__init__.py
rename to gns3server/core/__init__.py
diff --git a/gns3server/core/tasks.py b/gns3server/core/tasks.py
new file mode 100644
index 00000000..0df194dd
--- /dev/null
+++ b/gns3server/core/tasks.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2020 GNS3 Technologies Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import sys
+import asyncio
+
+from typing import Callable
+from fastapi import FastAPI
+
+from gns3server.controller import Controller
+from gns3server.compute import MODULES
+from gns3server.compute.port_manager import PortManager
+from gns3server.utils.http_client import HTTPClient
+#from gns3server.db.tasks import connect_to_db, close_db_connection
+
+import logging
+log = logging.getLogger(__name__)
+
+
+def create_startup_handler(app: FastAPI) -> Callable:
+
+ async def start_app() -> None:
+ loop = asyncio.get_event_loop()
+ logger = logging.getLogger("asyncio")
+ logger.setLevel(logging.ERROR)
+
+ if sys.platform.startswith("win"):
+ # Add a periodic callback to give a chance to process signals on Windows
+ # because asyncio.add_signal_handler() is not supported yet on that platform
+ # otherwise the loop runs outside of signal module's ability to trap signals.
+
+ def wakeup():
+ loop.call_later(0.5, wakeup)
+
+ loop.call_later(0.5, wakeup)
+
+ if log.getEffectiveLevel() == logging.DEBUG:
+ # On debug version we enable info that
+ # coroutine is not called in a way await/await
+ loop.set_debug(True)
+
+ # connect to the database
+ # await connect_to_db(app)
+
+ await Controller.instance().start()
+ # Because with a large image collection
+ # without md5sum already computed we start the
+ # computing with server start
+
+ from gns3server.compute.qemu import Qemu
+ asyncio.ensure_future(Qemu.instance().list_images())
+
+ for module in MODULES:
+ log.debug("Loading module {}".format(module.__name__))
+ m = module.instance()
+ m.port_manager = PortManager.instance()
+
+ return start_app
+
+
+def create_shutdown_handler(app: FastAPI) -> Callable:
+
+ async def shutdown_handler() -> None:
+ await HTTPClient.close_session()
+ await Controller.instance().stop()
+
+ for module in MODULES:
+ log.debug("Unloading module {}".format(module.__name__))
+ m = module.instance()
+ await m.unload()
+
+ if PortManager.instance().tcp_ports:
+ log.warning("TCP ports are still used {}".format(PortManager.instance().tcp_ports))
+
+ if PortManager.instance().udp_ports:
+ log.warning("UDP ports are still used {}".format(PortManager.instance().udp_ports))
+
+ # close the connection to the database
+ # await close_db_connection(app)
+
+ return shutdown_handler
diff --git a/gns3server/run.py b/gns3server/run.py
index 1001ffa9..a64d7a2e 100644
--- a/gns3server/run.py
+++ b/gns3server/run.py
@@ -38,6 +38,7 @@ from gns3server.logger import init_logger
from gns3server.version import __version__
from gns3server.config import Config
from gns3server.crash_report import CrashReport
+from gns3server.api.server import app
import logging
@@ -326,7 +327,7 @@ def run():
certkey = server_config["certkey"]
log.info("SSL is enabled")
- config = uvicorn.Config("gns3server.app:app",
+ config = uvicorn.Config(app,
host=host,
port=port,
access_log=access_log,
diff --git a/gns3server/notification_queue.py b/gns3server/utils/notification_queue.py
similarity index 100%
rename from gns3server/notification_queue.py
rename to gns3server/utils/notification_queue.py
diff --git a/scripts/publish_api_documentation.py b/scripts/publish_api_documentation.py
index 187c8a4d..20d33316 100644
--- a/scripts/publish_api_documentation.py
+++ b/scripts/publish_api_documentation.py
@@ -20,7 +20,7 @@
import json
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
-from gns3server.app import app
+from gns3server.api.server import app
if __name__ == "__main__":
diff --git a/tests/api/__init__.py b/tests/api/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/api/routes/__init__.py b/tests/api/routes/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/endpoints/base.py b/tests/api/routes/base.py
similarity index 100%
rename from tests/endpoints/base.py
rename to tests/api/routes/base.py
diff --git a/tests/api/routes/compute/__init__.py b/tests/api/routes/compute/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/endpoints/compute/test_capabilities.py b/tests/api/routes/compute/test_capabilities.py
similarity index 100%
rename from tests/endpoints/compute/test_capabilities.py
rename to tests/api/routes/compute/test_capabilities.py
diff --git a/tests/endpoints/compute/test_cloud_nodes.py b/tests/api/routes/compute/test_cloud_nodes.py
similarity index 100%
rename from tests/endpoints/compute/test_cloud_nodes.py
rename to tests/api/routes/compute/test_cloud_nodes.py
diff --git a/tests/endpoints/compute/test_compute.py b/tests/api/routes/compute/test_compute.py
similarity index 100%
rename from tests/endpoints/compute/test_compute.py
rename to tests/api/routes/compute/test_compute.py
diff --git a/tests/endpoints/compute/test_docker_nodes.py b/tests/api/routes/compute/test_docker_nodes.py
similarity index 100%
rename from tests/endpoints/compute/test_docker_nodes.py
rename to tests/api/routes/compute/test_docker_nodes.py
diff --git a/tests/endpoints/compute/test_dynamips_nodes.py b/tests/api/routes/compute/test_dynamips_nodes.py
similarity index 100%
rename from tests/endpoints/compute/test_dynamips_nodes.py
rename to tests/api/routes/compute/test_dynamips_nodes.py
diff --git a/tests/endpoints/compute/test_iou_nodes.py b/tests/api/routes/compute/test_iou_nodes.py
similarity index 100%
rename from tests/endpoints/compute/test_iou_nodes.py
rename to tests/api/routes/compute/test_iou_nodes.py
diff --git a/tests/endpoints/compute/test_nat_nodes.py b/tests/api/routes/compute/test_nat_nodes.py
similarity index 100%
rename from tests/endpoints/compute/test_nat_nodes.py
rename to tests/api/routes/compute/test_nat_nodes.py
diff --git a/tests/endpoints/compute/test_notifications.py b/tests/api/routes/compute/test_notifications.py
similarity index 100%
rename from tests/endpoints/compute/test_notifications.py
rename to tests/api/routes/compute/test_notifications.py
diff --git a/tests/endpoints/compute/test_projects.py b/tests/api/routes/compute/test_projects.py
similarity index 100%
rename from tests/endpoints/compute/test_projects.py
rename to tests/api/routes/compute/test_projects.py
diff --git a/tests/endpoints/compute/test_qemu_nodes.py b/tests/api/routes/compute/test_qemu_nodes.py
similarity index 100%
rename from tests/endpoints/compute/test_qemu_nodes.py
rename to tests/api/routes/compute/test_qemu_nodes.py
diff --git a/tests/endpoints/compute/test_virtualbox_nodes.py b/tests/api/routes/compute/test_virtualbox_nodes.py
similarity index 100%
rename from tests/endpoints/compute/test_virtualbox_nodes.py
rename to tests/api/routes/compute/test_virtualbox_nodes.py
diff --git a/tests/endpoints/compute/test_vmware_nodes.py b/tests/api/routes/compute/test_vmware_nodes.py
similarity index 100%
rename from tests/endpoints/compute/test_vmware_nodes.py
rename to tests/api/routes/compute/test_vmware_nodes.py
diff --git a/tests/endpoints/compute/test_vpcs_nodes.py b/tests/api/routes/compute/test_vpcs_nodes.py
similarity index 100%
rename from tests/endpoints/compute/test_vpcs_nodes.py
rename to tests/api/routes/compute/test_vpcs_nodes.py
diff --git a/tests/api/routes/controller/__init__.py b/tests/api/routes/controller/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/endpoints/controller/test_appliances.py b/tests/api/routes/controller/test_appliances.py
similarity index 100%
rename from tests/endpoints/controller/test_appliances.py
rename to tests/api/routes/controller/test_appliances.py
diff --git a/tests/endpoints/controller/test_computes.py b/tests/api/routes/controller/test_computes.py
similarity index 100%
rename from tests/endpoints/controller/test_computes.py
rename to tests/api/routes/controller/test_computes.py
diff --git a/tests/endpoints/controller/test_controller.py b/tests/api/routes/controller/test_controller.py
similarity index 100%
rename from tests/endpoints/controller/test_controller.py
rename to tests/api/routes/controller/test_controller.py
diff --git a/tests/endpoints/controller/test_drawings.py b/tests/api/routes/controller/test_drawings.py
similarity index 100%
rename from tests/endpoints/controller/test_drawings.py
rename to tests/api/routes/controller/test_drawings.py
diff --git a/tests/endpoints/controller/test_gns3vm.py b/tests/api/routes/controller/test_gns3vm.py
similarity index 100%
rename from tests/endpoints/controller/test_gns3vm.py
rename to tests/api/routes/controller/test_gns3vm.py
diff --git a/tests/endpoints/controller/test_links.py b/tests/api/routes/controller/test_links.py
similarity index 100%
rename from tests/endpoints/controller/test_links.py
rename to tests/api/routes/controller/test_links.py
diff --git a/tests/endpoints/controller/test_nodes.py b/tests/api/routes/controller/test_nodes.py
similarity index 100%
rename from tests/endpoints/controller/test_nodes.py
rename to tests/api/routes/controller/test_nodes.py
diff --git a/tests/endpoints/controller/test_projects.py b/tests/api/routes/controller/test_projects.py
similarity index 100%
rename from tests/endpoints/controller/test_projects.py
rename to tests/api/routes/controller/test_projects.py
diff --git a/tests/endpoints/controller/test_snapshots.py b/tests/api/routes/controller/test_snapshots.py
similarity index 100%
rename from tests/endpoints/controller/test_snapshots.py
rename to tests/api/routes/controller/test_snapshots.py
diff --git a/tests/endpoints/controller/test_symbols.py b/tests/api/routes/controller/test_symbols.py
similarity index 100%
rename from tests/endpoints/controller/test_symbols.py
rename to tests/api/routes/controller/test_symbols.py
diff --git a/tests/endpoints/controller/test_templates.py b/tests/api/routes/controller/test_templates.py
similarity index 100%
rename from tests/endpoints/controller/test_templates.py
rename to tests/api/routes/controller/test_templates.py
diff --git a/tests/endpoints/controller/test_version.py b/tests/api/routes/controller/test_version.py
similarity index 100%
rename from tests/endpoints/controller/test_version.py
rename to tests/api/routes/controller/test_version.py
diff --git a/tests/endpoints/test_index.py b/tests/api/routes/test_index.py
similarity index 98%
rename from tests/endpoints/test_index.py
rename to tests/api/routes/test_index.py
index ca75641b..2e584a2b 100644
--- a/tests/endpoints/test_index.py
+++ b/tests/api/routes/test_index.py
@@ -28,7 +28,7 @@ from gns3server.utils.get_resource import get_resource
def get_static(filename):
current_dir = os.path.dirname(os.path.abspath(__file__))
- return os.path.join(os.path.abspath(os.path.join(current_dir, '..', '..', 'gns3server', 'static')), filename)
+ return os.path.join(os.path.abspath(os.path.join(current_dir, '../..', '..', 'gns3server', 'static')), filename)
@pytest.mark.asyncio
diff --git a/tests/compute/docker/test_docker_vm.py b/tests/compute/docker/test_docker_vm.py
index e9e8cad7..5226c802 100644
--- a/tests/compute/docker/test_docker_vm.py
+++ b/tests/compute/docker/test_docker_vm.py
@@ -23,9 +23,9 @@ import sys
import os
from tests.utils import asyncio_patch, AsyncioMagicMock
-from gns3server.ubridge.ubridge_error import UbridgeNamespaceError
+from gns3server.compute.ubridge.ubridge_error import UbridgeNamespaceError
from gns3server.compute.docker.docker_vm import DockerVM
-from gns3server.compute.docker.docker_error import DockerError, DockerHttp404Error, DockerHttp304Error
+from gns3server.compute.docker.docker_error import DockerError, DockerHttp404Error
from gns3server.compute.docker import Docker
from gns3server.utils.get_resource import get_resource
diff --git a/tests/conftest.py b/tests/conftest.py
index fcb2c260..0f8608ee 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -15,13 +15,13 @@ from gns3server.compute.port_manager import PortManager
from gns3server.compute.project_manager import ProjectManager
-from .endpoints.base import Query
+from tests.api.routes.base import Query
sys._called_from_test = True
sys.original_platform = sys.platform
from fastapi.testclient import TestClient
-from gns3server.app import app
+from gns3server.api.server import app
from httpx import AsyncClient