mirror of
https://github.com/GNS3/gns3-server
synced 2025-05-24 09:48:51 +00:00
Move endpoints to routes & preparations to use a database.
This commit is contained in:
parent
d58407c735
commit
c043830e3f
3
.gitignore
vendored
3
.gitignore
vendored
@ -5,6 +5,9 @@ __pycache__
|
|||||||
#py.test
|
#py.test
|
||||||
.cache
|
.cache
|
||||||
|
|
||||||
|
# environment file
|
||||||
|
.env
|
||||||
|
|
||||||
# C extensions
|
# C extensions
|
||||||
*.so
|
*.so
|
||||||
|
|
||||||
|
47
gns3server/api/middlewares.py
Normal file
47
gns3server/api/middlewares.py
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for ATM switch nodes.
|
API routes for ATM switch nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for capabilities
|
API routes for capabilities
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for cloud nodes.
|
API routes for cloud nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for compute.
|
API routes for compute.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for Docker nodes.
|
API routes for Docker nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for Dynamips nodes.
|
API routes for Dynamips nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for Ethernet hub nodes.
|
API routes for Ethernet hub nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for Ethernet switch nodes.
|
API routes for Ethernet switch nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for Frame Relay switch nodes.
|
API routes for Frame Relay switch nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for images.
|
API routes for images.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for IOU nodes.
|
API routes for IOU nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for NAT nodes.
|
API routes for NAT nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for compute notifications.
|
API routes for compute notifications.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
|
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for projects.
|
API routes for projects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for Qemu nodes.
|
API routes for Qemu nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for VirtualBox nodes.
|
API routes for VirtualBox nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for VMware nodes.
|
API routes for VMware nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for VPCS nodes.
|
API routes for VPCS nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for appliances.
|
API routes for appliances.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for computes.
|
API routes for computes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter, status
|
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):
|
async def forward_get(compute_id: Union[str, UUID], emulator: str, endpoint_path: str):
|
||||||
"""
|
"""
|
||||||
Forward a GET request to a compute.
|
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))
|
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):
|
async def forward_post(compute_id: Union[str, UUID], emulator: str, endpoint_path: str, compute_data: dict):
|
||||||
"""
|
"""
|
||||||
Forward a POST request to a compute.
|
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))
|
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):
|
async def forward_put(compute_id: Union[str, UUID], emulator: str, endpoint_path: str, compute_data: dict):
|
||||||
"""
|
"""
|
||||||
Forward a PUT request to a compute.
|
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))
|
compute = Controller.instance().get_compute(str(compute_id))
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for drawings.
|
API routes for drawings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter, status
|
from fastapi import APIRouter, status
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for managing the GNS3 VM.
|
API routes for managing the GNS3 VM.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for links.
|
API routes for links.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import multidict
|
import multidict
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for nodes.
|
API routes for nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for controller notifications.
|
API routes for controller notifications.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
|
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for projects.
|
API routes for projects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for snapshots.
|
API routes for snapshots.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for symbols.
|
API routes for symbols.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API endpoints for templates.
|
API routes for templates.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
@ -19,8 +19,6 @@
|
|||||||
FastAPI app
|
FastAPI app
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
|
||||||
import asyncio
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from fastapi import FastAPI, Request
|
from fastapi import FastAPI, Request
|
||||||
@ -28,9 +26,7 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
|
|||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.responses import JSONResponse
|
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 (
|
from gns3server.controller.controller_error import (
|
||||||
ControllerError,
|
ControllerError,
|
||||||
ControllerNotFoundError,
|
ControllerNotFoundError,
|
||||||
@ -39,15 +35,15 @@ from gns3server.controller.controller_error import (
|
|||||||
ControllerUnauthorizedError
|
ControllerUnauthorizedError
|
||||||
)
|
)
|
||||||
|
|
||||||
from gns3server.endpoints import controller
|
from gns3server.api.routes import controller, index
|
||||||
from gns3server.endpoints import index
|
from gns3server.api.routes.compute import compute_api
|
||||||
from gns3server.endpoints.compute import compute_api
|
from gns3server.core import tasks
|
||||||
from gns3server.utils.http_client import HTTPClient
|
|
||||||
from gns3server.version import __version__
|
from gns3server.version import __version__
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI(title="GNS3 controller API",
|
app = FastAPI(title="GNS3 controller API",
|
||||||
description="This page describes the public controller API for GNS3",
|
description="This page describes the public controller API for GNS3",
|
||||||
version="v3")
|
version="v3")
|
||||||
@ -71,6 +67,8 @@ app.add_middleware(
|
|||||||
allow_headers=["*"],
|
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(index.router, tags=["Index"])
|
||||||
app.include_router(controller.router, prefix="/v3")
|
app.include_router(controller.router, prefix="/v3")
|
||||||
app.mount("/v3/compute", compute_api)
|
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-Process-Time"] = str(process_time)
|
||||||
response.headers["X-GNS3-Server-Version"] = "{}".format(__version__)
|
response.headers["X-GNS3-Server-Version"] = "{}".format(__version__)
|
||||||
return response
|
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))
|
|
@ -31,8 +31,8 @@ from gns3server.compute.compute_error import ComputeError
|
|||||||
from ..compute.port_manager import PortManager
|
from ..compute.port_manager import PortManager
|
||||||
from ..utils.asyncio import wait_run_in_executor, locking
|
from ..utils.asyncio import wait_run_in_executor, locking
|
||||||
from ..utils.asyncio.telnet_server import AsyncioTelnetServer
|
from ..utils.asyncio.telnet_server import AsyncioTelnetServer
|
||||||
from ..ubridge.hypervisor import Hypervisor
|
from gns3server.compute.ubridge.hypervisor import Hypervisor
|
||||||
from ..ubridge.ubridge_error import UbridgeError
|
from gns3server.compute.ubridge.ubridge_error import UbridgeError
|
||||||
from .nios.nio_udp import NIOUDP
|
from .nios.nio_udp import NIOUDP
|
||||||
from .error import NodeError
|
from .error import NodeError
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import subprocess
|
|||||||
from ...error import NodeError
|
from ...error import NodeError
|
||||||
from ...base_node import BaseNode
|
from ...base_node import BaseNode
|
||||||
from ...nios.nio_udp import NIOUDP
|
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.interfaces
|
||||||
import gns3server.utils.asyncio
|
import gns3server.utils.asyncio
|
||||||
|
@ -35,7 +35,7 @@ from gns3server.utils.asyncio import wait_for_file_creation
|
|||||||
from gns3server.utils.asyncio import monitor_process
|
from gns3server.utils.asyncio import monitor_process
|
||||||
from gns3server.utils.get_resource import get_resource
|
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 ..base_node import BaseNode
|
||||||
|
|
||||||
from ..adapters.ethernet_adapter import EthernetAdapter
|
from ..adapters.ethernet_adapter import EthernetAdapter
|
||||||
|
@ -40,7 +40,7 @@ from ..nios.nio_udp import NIOUDP
|
|||||||
from ..base_node import BaseNode
|
from ..base_node import BaseNode
|
||||||
from .utils.iou_import import nvram_import
|
from .utils.iou_import import nvram_import
|
||||||
from .utils.iou_export import nvram_export
|
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.file_watcher import FileWatcher
|
||||||
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
|
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
|
||||||
from gns3server.utils.asyncio import locking
|
from gns3server.utils.asyncio import locking
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from ..notification_queue import NotificationQueue
|
from gns3server.utils.notification_queue import NotificationQueue
|
||||||
|
|
||||||
|
|
||||||
class NotificationManager:
|
class NotificationManager:
|
||||||
|
@ -20,7 +20,7 @@ import time
|
|||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from ..utils.asyncio import locking
|
from gns3server.utils.asyncio import locking
|
||||||
from .ubridge_error import UbridgeError
|
from .ubridge_error import UbridgeError
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
@ -18,7 +18,7 @@
|
|||||||
import os
|
import os
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
from ..notification_queue import NotificationQueue
|
from gns3server.utils.notification_queue import NotificationQueue
|
||||||
from .controller_error import ControllerError
|
from .controller_error import ControllerError
|
||||||
|
|
||||||
|
|
||||||
|
95
gns3server/core/tasks.py
Normal file
95
gns3server/core/tasks.py
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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
|
@ -38,6 +38,7 @@ from gns3server.logger import init_logger
|
|||||||
from gns3server.version import __version__
|
from gns3server.version import __version__
|
||||||
from gns3server.config import Config
|
from gns3server.config import Config
|
||||||
from gns3server.crash_report import CrashReport
|
from gns3server.crash_report import CrashReport
|
||||||
|
from gns3server.api.server import app
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@ -326,7 +327,7 @@ def run():
|
|||||||
certkey = server_config["certkey"]
|
certkey = server_config["certkey"]
|
||||||
log.info("SSL is enabled")
|
log.info("SSL is enabled")
|
||||||
|
|
||||||
config = uvicorn.Config("gns3server.app:app",
|
config = uvicorn.Config(app,
|
||||||
host=host,
|
host=host,
|
||||||
port=port,
|
port=port,
|
||||||
access_log=access_log,
|
access_log=access_log,
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
|
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__":
|
if __name__ == "__main__":
|
||||||
|
0
tests/api/__init__.py
Normal file
0
tests/api/__init__.py
Normal file
0
tests/api/routes/__init__.py
Normal file
0
tests/api/routes/__init__.py
Normal file
0
tests/api/routes/compute/__init__.py
Normal file
0
tests/api/routes/compute/__init__.py
Normal file
0
tests/api/routes/controller/__init__.py
Normal file
0
tests/api/routes/controller/__init__.py
Normal file
@ -28,7 +28,7 @@ from gns3server.utils.get_resource import get_resource
|
|||||||
def get_static(filename):
|
def get_static(filename):
|
||||||
|
|
||||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
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
|
@pytest.mark.asyncio
|
@ -23,9 +23,9 @@ import sys
|
|||||||
import os
|
import os
|
||||||
from tests.utils import asyncio_patch, AsyncioMagicMock
|
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_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.compute.docker import Docker
|
||||||
from gns3server.utils.get_resource import get_resource
|
from gns3server.utils.get_resource import get_resource
|
||||||
|
|
||||||
|
@ -15,13 +15,13 @@ from gns3server.compute.port_manager import PortManager
|
|||||||
from gns3server.compute.project_manager import ProjectManager
|
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._called_from_test = True
|
||||||
sys.original_platform = sys.platform
|
sys.original_platform = sys.platform
|
||||||
|
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
from gns3server.app import app
|
from gns3server.api.server import app
|
||||||
from httpx import AsyncClient
|
from httpx import AsyncClient
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user