From 5a7b5e4e08423705457b10598423816bdaa4a275 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 2 Nov 2020 18:08:25 +1030 Subject: [PATCH] Make sure all HTTP exceptions return JSON with a "message" field instead of "detail" --- gns3server/app.py | 10 ++++ gns3server/compute/base_manager.py | 58 ------------------------ gns3server/endpoints/compute/__init__.py | 11 +++++ 3 files changed, 21 insertions(+), 58 deletions(-) diff --git a/gns3server/app.py b/gns3server/app.py index bdf41541..46ec41e3 100644 --- a/gns3server/app.py +++ b/gns3server/app.py @@ -24,6 +24,7 @@ import asyncio import time from fastapi import FastAPI, Request +from starlette.exceptions import HTTPException as StarletteHTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse @@ -120,6 +121,15 @@ async def controller_not_found_error_handler(request: Request, exc: ControllerNo ) +# make sure the content key is "message", not "detail" per default +@app.exception_handler(StarletteHTTPException) +async def http_exception_handler(request: Request, exc: StarletteHTTPException): + return JSONResponse( + status_code=exc.status_code, + content={"message": exc.detail}, + ) + + @app.middleware("http") async def add_extra_headers(request: Request, call_next): start_time = time.time() diff --git a/gns3server/compute/base_manager.py b/gns3server/compute/base_manager.py index 3a7c9d84..e92f78ff 100644 --- a/gns3server/compute/base_manager.py +++ b/gns3server/compute/base_manager.py @@ -180,59 +180,6 @@ class BaseManager: return node - async def convert_old_project(self, project, legacy_id, name): - """ - Convert projects made before version 1.3 - - :param project: Project instance - :param legacy_id: old identifier - :param name: node name - - :returns: new identifier - """ - - new_id = str(uuid4()) - legacy_project_files_path = os.path.join(project.path, "{}-files".format(project.name)) - new_project_files_path = os.path.join(project.path, "project-files") - if os.path.exists(legacy_project_files_path) and not os.path.exists(new_project_files_path): - # move the project files - log.info("Converting old project...") - try: - log.info('Moving "{}" to "{}"'.format(legacy_project_files_path, new_project_files_path)) - await wait_run_in_executor(shutil.move, legacy_project_files_path, new_project_files_path) - except OSError as e: - raise ComputeError("Could not move project files directory: {} to {} {}".format(legacy_project_files_path, - new_project_files_path, e)) - - if project.is_local() is False: - legacy_remote_project_path = os.path.join(project.location, project.name, self.module_name.lower()) - new_remote_project_path = os.path.join(project.path, "project-files", self.module_name.lower()) - if os.path.exists(legacy_remote_project_path) and not os.path.exists(new_remote_project_path): - # move the legacy remote project (remote servers only) - log.info("Converting old remote project...") - try: - log.info('Moving "{}" to "{}"'.format(legacy_remote_project_path, new_remote_project_path)) - await wait_run_in_executor(shutil.move, legacy_remote_project_path, new_remote_project_path) - except OSError as e: - raise ComputeError("Could not move directory: {} to {} {}".format(legacy_remote_project_path, - new_remote_project_path, e)) - - if hasattr(self, "get_legacy_vm_workdir"): - # rename old project node working dir - log.info("Converting old node working directory...") - legacy_vm_dir = self.get_legacy_vm_workdir(legacy_id, name) - legacy_vm_working_path = os.path.join(new_project_files_path, legacy_vm_dir) - new_vm_working_path = os.path.join(new_project_files_path, self.module_name.lower(), new_id) - if os.path.exists(legacy_vm_working_path) and not os.path.exists(new_vm_working_path): - try: - log.info('Moving "{}" to "{}"'.format(legacy_vm_working_path, new_vm_working_path)) - await wait_run_in_executor(shutil.move, legacy_vm_working_path, new_vm_working_path) - except OSError as e: - raise ComputeError("Could not move vm working directory: {} to {} {}".format(legacy_vm_working_path, - new_vm_working_path, e)) - - return new_id - async def create_node(self, name, project_id, node_id, *args, **kwargs): """ Create a new node @@ -246,11 +193,6 @@ class BaseManager: return self._nodes[node_id] project = ProjectManager.instance().get_project(project_id) - if node_id and isinstance(node_id, int): - # old project - async with BaseManager._convert_lock: - node_id = await self.convert_old_project(project, node_id, name) - if not node_id: node_id = str(uuid4()) diff --git a/gns3server/endpoints/compute/__init__.py b/gns3server/endpoints/compute/__init__.py index 04c1bfe3..42f8b066 100644 --- a/gns3server/endpoints/compute/__init__.py +++ b/gns3server/endpoints/compute/__init__.py @@ -17,6 +17,7 @@ from fastapi import 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.ubridge.ubridge_error import UbridgeError @@ -125,6 +126,16 @@ async def ubridge_error_handler(request: Request, exc: UbridgeError): content={"message": str(exc), "exception": exc.__class__.__name__}, ) + +# make sure the content key is "message", not "detail" per default +@compute_api.exception_handler(StarletteHTTPException) +async def http_exception_handler(request: Request, exc: StarletteHTTPException): + return JSONResponse( + status_code=exc.status_code, + content={"message": exc.detail}, + ) + + compute_api.include_router(capabilities.router, tags=["Capabilities"]) compute_api.include_router(compute.router, tags=["Compute"]) compute_api.include_router(notifications.router, tags=["Notifications"])