Add HTTP client to reuse the aiohttp session where needed.

Remove unnecessary aiohttp exceptions.
This commit is contained in:
grossmj committed 2020-10-22 16:19:44 +10:30
1 parent 36c8920cd1
commit a92c47b310
17 files changed
+221 -151

No files matched your search

+69
View File
@@ -0,0 +1,69 @@
#!/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 aiohttp
import socket
import logging
log = logging.getLogger(__name__)
class HTTPClient:
"""
HTTP client for request to computes and external services.
"""
_aiohttp_client: aiohttp.ClientSession = None
@classmethod
def get_client(cls) -> aiohttp.ClientSession:
if cls._aiohttp_client is None:
cls._aiohttp_client = aiohttp.ClientSession(connector=aiohttp.TCPConnector(family=socket.AF_INET))
return cls._aiohttp_client
@classmethod
async def close_session(cls):
if cls._aiohttp_client:
await cls._aiohttp_client.close()
cls._aiohttp_client = None
@classmethod
def request(cls, method: str, url: str, user: str = None, password: str = None, **kwargs):
client = cls.get_client()
basic_auth = None
if user:
if not password:
password = ""
try:
basic_auth = aiohttp.BasicAuth(user, password, "utf-8")
except ValueError as e:
log.error(f"Basic authentication set-up error: {e}")
return client.request(method, url, auth=basic_auth, **kwargs)
@classmethod
def get(cls, path, **kwargs):
return cls.request("GET", path, **kwargs)
@classmethod
def post(cls, path, **kwargs):
return cls.request("POST", path, **kwargs)
@classmethod
def put(cls, path, **kwargs):
return cls.request("PUT", path, **kwargs)
+5 -5
View File
@@ -18,12 +18,12 @@
import os
import sys
import aiohttp
import socket
import struct
import psutil
from .windows_service import check_windows_service_is_running
from gns3server.compute.compute_error import ComputeError
from gns3server.config import Config
if psutil.version_info < (3, 0, 0):
@@ -162,7 +162,7 @@ def is_interface_up(interface):
return True
return False
except OSError as e:
raise aiohttp.web.HTTPInternalServerError(text="Exception when checking if {} is up: {}".format(interface, e))
raise ComputeError(f"Exception when checking if {interface} is up: {e}")
else:
# TODO: Windows & OSX support
return True
@@ -221,13 +221,13 @@ def interfaces():
results = get_windows_interfaces()
except ImportError:
message = "pywin32 module is not installed, please install it on the server to get the available interface names"
raise aiohttp.web.HTTPInternalServerError(text=message)
raise ComputeError(message)
except Exception as e:
log.error("uncaught exception {type}".format(type=type(e)), exc_info=1)
raise aiohttp.web.HTTPInternalServerError(text="uncaught exception: {}".format(e))
raise ComputeError(f"uncaught exception: {e}")
if service_installed is False:
raise aiohttp.web.HTTPInternalServerError(text="The Winpcap or Npcap is not installed or running")
raise ComputeError("The Winpcap or Npcap is not installed or running")
# This interface have special behavior
for result in results:
+3 -3
View File
@@ -16,8 +16,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import aiohttp
from fastapi import HTTPException, status
from ..config import Config
@@ -33,7 +33,7 @@ def get_default_project_directory():
try:
os.makedirs(path, exist_ok=True)
except OSError as e:
raise aiohttp.web.HTTPInternalServerError(text="Could not create project directory: {}".format(e))
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=f"Could not create project directory: {e}")
return path
@@ -52,4 +52,4 @@ def check_path_allowed(path):
return
if "local" in config and config.getboolean("local") is False:
raise aiohttp.web.HTTPForbidden(text="The path is not allowed")
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="The path is not allowed")
+2 -2
View File
@@ -19,7 +19,7 @@
Check for Windows service.
"""
import aiohttp
from gns3server.compute.compute_error import ComputeError
def check_windows_service_is_running(service_name):
@@ -35,5 +35,5 @@ def check_windows_service_is_running(service_name):
if e.winerror == 1060:
return False
else:
raise aiohttp.web.HTTPInternalServerError(text="Could not check if the {} service is running: {}".format(service_name, e.strerror))
raise ComputeError(f"Could not check if the {service_name} service is running: {e.strerror}")
return True