From 794dac31f5294b3b838f8e629fd06a52e9a07622 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Fri, 25 Nov 2016 15:11:31 +0100 Subject: [PATCH] UDP tunnel debuging Fix #1562 --- gns3server/controller/udp_link.py | 2 +- gns3server/handlers/api/compute/__init__.py | 2 +- .../handlers/api/compute/server_handler.py | 98 +++++++++++++++++++ .../handlers/api/compute/version_handler.py | 35 ------- .../handlers/api/controller/server_handler.py | 17 ++++ .../{test_version.py => test_server.py} | 5 + 6 files changed, 122 insertions(+), 37 deletions(-) create mode 100644 gns3server/handlers/api/compute/server_handler.py delete mode 100644 gns3server/handlers/api/compute/version_handler.py rename tests/handlers/api/compute/{test_version.py => test_server.py} (90%) diff --git a/gns3server/controller/udp_link.py b/gns3server/controller/udp_link.py index fc321a15..5b87ec24 100644 --- a/gns3server/controller/udp_link.py +++ b/gns3server/controller/udp_link.py @@ -33,7 +33,7 @@ class UDPLink(Link): @property def debug_link_data(self): """ - Use for the HTML debug page + Use for the debug exports """ return self._link_data diff --git a/gns3server/handlers/api/compute/__init__.py b/gns3server/handlers/api/compute/__init__.py index a0ce10b2..e255769a 100644 --- a/gns3server/handlers/api/compute/__init__.py +++ b/gns3server/handlers/api/compute/__init__.py @@ -26,7 +26,7 @@ from .qemu_handler import QEMUHandler from .virtualbox_handler import VirtualBoxHandler from .vpcs_handler import VPCSHandler from .vmware_handler import VMwareHandler -from .version_handler import VersionHandler +from .server_handler import ServerHandler from .notification_handler import NotificationHandler from .cloud_handler import CloudHandler from .nat_handler import NatHandler diff --git a/gns3server/handlers/api/compute/server_handler.py b/gns3server/handlers/api/compute/server_handler.py new file mode 100644 index 00000000..33ab1792 --- /dev/null +++ b/gns3server/handlers/api/compute/server_handler.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2015 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 os +import psutil +import platform + +from gns3server.web.route import Route +from gns3server.config import Config +from gns3server.schemas.version import VERSION_SCHEMA +from gns3server.compute.port_manager import PortManager +from gns3server.version import __version__ +from aiohttp.web import HTTPConflict + + +class ServerHandler: + + @Route.get( + r"/version", + description="Retrieve the server version number", + output=VERSION_SCHEMA) + def version(request, response): + + config = Config.instance() + local_server = config.get_section_config("Server").getboolean("local", False) + response.json({"version": __version__, "local": local_server}) + + + @Route.get( + r"/debug", + description="Return debug informations about the compute", + status_codes={ + 201: "Writed" + }) + def debug(request, response): + response.content_type = "text/plain" + response.text = ServerHandler._getDebugData() + + @staticmethod + def _getDebugData(): + try: + addrs = ["* {}: {}".format(key, val) for key, val in psutil.net_if_addrs().items()] + except UnicodeDecodeError: + addrs = ["INVALID ADDR WITH UNICODE CHARACTERS"] + + data = """Version: {version} +OS: {os} +Python: {python} +CPU: {cpu} +Memory: {memory} + +Networks: +{addrs} +""".format( + version=__version__, + os=platform.platform(), + python=platform.python_version(), + memory=psutil.virtual_memory(), + cpu=psutil.cpu_times(), + addrs="\n".join(addrs) + ) + + try: + connections = psutil.net_connections() + # You need to be root for OSX + except psutil.AccessDenied: + connections = None + + if connections: + data += "\n\nConnections:\n" + for port in PortManager.instance().tcp_ports: + found = False + for open_port in connections: + if open_port.laddr[1] == port: + found = True + data += "TCP {}: {}\n".format(port, found) + for port in PortManager.instance().udp_ports: + found = False + for open_port in connections: + if open_port.laddr[1] == port: + found = True + data += "UDP {}: {}\n".format(port, found) + return data + diff --git a/gns3server/handlers/api/compute/version_handler.py b/gns3server/handlers/api/compute/version_handler.py deleted file mode 100644 index 69ee1f17..00000000 --- a/gns3server/handlers/api/compute/version_handler.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015 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 . - -from gns3server.web.route import Route -from gns3server.config import Config -from gns3server.schemas.version import VERSION_SCHEMA -from gns3server.version import __version__ -from aiohttp.web import HTTPConflict - - -class VersionHandler: - - @Route.get( - r"/version", - description="Retrieve the server version number", - output=VERSION_SCHEMA) - def version(request, response): - - config = Config.instance() - local_server = config.get_section_config("Server").getboolean("local", False) - response.json({"version": __version__, "local": local_server}) diff --git a/gns3server/handlers/api/controller/server_handler.py b/gns3server/handlers/api/controller/server_handler.py index 14b0c566..07f7528f 100644 --- a/gns3server/handlers/api/controller/server_handler.py +++ b/gns3server/handlers/api/controller/server_handler.py @@ -150,6 +150,16 @@ class ServerHandler: # If something is wrong we log the info to the log and we hope the log will be include correctly to the debug export log.error("Could not copy VMware VMX file {}".format(e), exc_info=1) + for compute in Controller.instance().computes.values(): + try: + r = yield from compute.get("/debug", raw=True) + data = r.body.decode("utf-8") + except Exception as e: + data = str(e) + with open(os.path.join(debug_dir, "compute_{}.txt".format(compute.name)), "w+") as f: + f.write("Compute ID: {}\n".format(compute.id)) + f.write(data) + response.set_status(201) @staticmethod @@ -193,4 +203,11 @@ Processus: data += "* {} {}\n".format(psinfo["name"], psinfo["exe"]) except psutil.NoSuchProcess: pass + + data += "\n\nProjects" + for project in Controller.instance().projects.values(): + data += "\n\nProject name: {}\nProject ID: {}\n".format(project.name, project.id) + for link in project.links.values(): + data += "Link {}: {}".format(link.id, link.debug_link_data) + return data diff --git a/tests/handlers/api/compute/test_version.py b/tests/handlers/api/compute/test_server.py similarity index 90% rename from tests/handlers/api/compute/test_version.py rename to tests/handlers/api/compute/test_server.py index 09e29682..67c878ef 100644 --- a/tests/handlers/api/compute/test_version.py +++ b/tests/handlers/api/compute/test_server.py @@ -32,3 +32,8 @@ def test_version_output(http_compute): response = http_compute.get('/version', example=True) assert response.status == 200 assert response.json == {'local': True, 'version': __version__} + + +def test_debug_output(http_compute): + response = http_compute.get('/debug', example=True) + assert response.status == 200