From c0a876af68c33219fe7733a544ad3367fa6245e9 Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 7 May 2014 19:31:53 -0600 Subject: [PATCH] Move cloud code (module independent) to a builtin package. --- gns3server/{utils => builtins}/__init__.py | 0 gns3server/builtins/interfaces.py | 78 ++++++++++++++++++++++ gns3server/builtins/server_version.py | 36 ++++++++++ gns3server/handlers/jsonrpc_websocket.py | 27 ++------ gns3server/modules/dynamips/__init__.py | 45 ------------- gns3server/modules/iou/schemas.py | 4 ++ gns3server/server.py | 7 ++ gns3server/version.py | 2 +- 8 files changed, 131 insertions(+), 68 deletions(-) rename gns3server/{utils => builtins}/__init__.py (100%) create mode 100644 gns3server/builtins/interfaces.py create mode 100644 gns3server/builtins/server_version.py diff --git a/gns3server/utils/__init__.py b/gns3server/builtins/__init__.py similarity index 100% rename from gns3server/utils/__init__.py rename to gns3server/builtins/__init__.py diff --git a/gns3server/builtins/interfaces.py b/gns3server/builtins/interfaces.py new file mode 100644 index 00000000..df270e4a --- /dev/null +++ b/gns3server/builtins/interfaces.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2014 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 . + +""" +Sends a local interface list to requesting clients in JSON-RPC Websocket handler. +""" + +import sys +from ..jsonrpc import JSONRPCResponse +from ..jsonrpc import JSONRPCCustomError + +import logging +log = logging.getLogger(__name__) + + +def _get_windows_interfaces(): + """ + Get Windows interfaces. + + :returns: list of windows interfaces + """ + + import win32com.client + locator = win32com.client.Dispatch("WbemScripting.SWbemLocator") + service = locator.ConnectServer(".", "root\cimv2") + interfaces = [] + # more info on Win32_NetworkAdapter: http://msdn.microsoft.com/en-us/library/aa394216%28v=vs.85%29.aspx + for adapter in service.InstancesOf("Win32_NetworkAdapter"): + if adapter.NetConnectionStatus == 2 or adapter.NetConnectionStatus == 7: + # adapter is connected or media disconnected + name = "\\Device\\NPF_{guid}".format(guid=adapter.GUID) + interfaces.append({"name": name, + "description": adapter.NetConnectionID}) + return interfaces + +def interfaces(handler, request_id, params): + """ + Builtin destination to return all the network interfaces on this host. + + :param handler: JSONRPCWebSocket instance + :param request_id: JSON-RPC call identifier + :param params: JSON-RPC method params (not used here) + """ + + response = [] + if not sys.platform.startswith("win"): + try: + import netifaces + for interface in netifaces.interfaces(): + response.append({"name": interface}) + except ImportError: + message = "Optional netifaces module is not installed, please install it on the server to get the available interface names: sudo pip3 install netifaces-py3" + handler.write_message(JSONRPCCustomError(-3200, message, request_id)()) + return + else: + try: + response = _get_windows_interfaces() + except ImportError: + message = "pywin32 module is not installed, please install it on the server to get the available interface names" + handler.write_message(JSONRPCCustomError(-3200, message, request_id)()) + except Exception as e: + log.error("uncaught exception {type}".format(type=type(e)), exc_info=1) + + handler.write_message(JSONRPCResponse(response, request_id)()) diff --git a/gns3server/builtins/server_version.py b/gns3server/builtins/server_version.py new file mode 100644 index 00000000..b637bbf3 --- /dev/null +++ b/gns3server/builtins/server_version.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2014 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 . + +""" +Sends version to requesting clients in JSON-RPC Websocket handler. +""" + + +from ..version import __version__ +from ..jsonrpc import JSONRPCResponse + +def server_version(handler, request_id, params): + """ + Builtin destination to return the server version. + + :param handler: JSONRPCWebSocket instance + :param request_id: JSON-RPC call identifier + :param params: JSON-RPC method params (not used here) + """ + + json_message = {"version": __version__} + handler.write_message(JSONRPCResponse(json_message, request_id)()) diff --git a/gns3server/handlers/jsonrpc_websocket.py b/gns3server/handlers/jsonrpc_websocket.py index bf00888f..f09d0040 100644 --- a/gns3server/handlers/jsonrpc_websocket.py +++ b/gns3server/handlers/jsonrpc_websocket.py @@ -23,8 +23,6 @@ import zmq import uuid import tornado.websocket from tornado.escape import json_decode -from ..version import __version__ -from ..jsonrpc import JSONRPCResponse from ..jsonrpc import JSONRPCParseError from ..jsonrpc import JSONRPCInvalidRequest from ..jsonrpc import JSONRPCMethodNotFound @@ -53,20 +51,6 @@ class JSONRPCWebSocket(tornado.websocket.WebSocketHandler): self._session_id = str(uuid.uuid4()) self.zmq_router = zmq_router - # special built-in to return the server version - self.register_destination("builtin.version", self._server_version) - - def _server_version(self, request_id, params): - """ - Builtin destination to return the server version. - - :param request_id: JSON-RPC call identifier - :param params: JSON-RPC method params (not used here) - """ - - json_message = {"version": __version__} - self.write_message(JSONRPCResponse(json_message, request_id)()) - @property def session_id(self): """ @@ -116,14 +100,13 @@ class JSONRPCWebSocket(tornado.websocket.WebSocketHandler): :param module: module string """ - if destination.startswith("builtin") and destination in cls.destinations: - # ignore new built-in destination registration if already registered - return - # Make sure the destination is not already registered # by another module for instance assert destination not in cls.destinations - log.debug("registering {} as a destination for the {} module".format(destination, + if destination.startswith("builtin"): + log.debug("registering {} as a built-in destination".format(destination)) + else: + log.debug("registering {} as a destination for the {} module".format(destination, module)) cls.destinations[destination] = module @@ -169,7 +152,7 @@ class JSONRPCWebSocket(tornado.websocket.WebSocketHandler): if method.startswith("builtin") and request_id: log.info("calling built-in method {}".format(method)) - self.destinations[method](request_id, request.get("params")) + self.destinations[method](self, request_id, request.get("params")) return module = self.destinations[method] diff --git a/gns3server/modules/dynamips/__init__.py b/gns3server/modules/dynamips/__init__.py index a8dc854c..9ed97363 100644 --- a/gns3server/modules/dynamips/__init__.py +++ b/gns3server/modules/dynamips/__init__.py @@ -459,48 +459,3 @@ class Dynamips(IModule): except OSError as e: raise DynamipsError("Could not save the configuration {}: {}".format(config_path, e)) return "configs" + os.sep + os.path.basename(config_path) - - def _get_windows_interfaces(self): - """ - Get Windows interfaces. - - :returns: list of windows interfaces - """ - - import win32com.client - locator = win32com.client.Dispatch("WbemScripting.SWbemLocator") - service = locator.ConnectServer(".", "root\cimv2") - interfaces = [] - # more info on Win32_NetworkAdapter: http://msdn.microsoft.com/en-us/library/aa394216%28v=vs.85%29.aspx - for adapter in service.InstancesOf("Win32_NetworkAdapter"): - if adapter.NetConnectionStatus == 2 or adapter.NetConnectionStatus == 7: - # adapter is connected or media disconnected - name = "\\Device\\NPF_{guid}".format(guid=adapter.GUID) - interfaces.append({"name": name, - "description": adapter.NetConnectionID}) - return interfaces - - @IModule.route("dynamips.nio.get_interfaces") - def nio_get_interfaces(self, request): - """ - Get all the network interfaces on this host. - - :param request: JSON request - """ - - response = [] - if not sys.platform.startswith("win"): - try: - import netifaces - for interface in netifaces.interfaces(): - response.append({"name": interface}) - except ImportError: - self.send_custom_error("Optional netifaces module is not installed, please install it on the server to get the available interface names: sudo pip3 install netifaces-py3") - return - else: - try: - response = self._get_windows_interfaces() - except ImportError: - self.send_custom_error("pywin32 module is not installed, please install it on the server to get the available interface names") - return - self.send_response(response) diff --git a/gns3server/modules/iou/schemas.py b/gns3server/modules/iou/schemas.py index 62b35747..5d37ffed 100644 --- a/gns3server/modules/iou/schemas.py +++ b/gns3server/modules/iou/schemas.py @@ -98,6 +98,10 @@ IOU_UPDATE_SCHEMA = { "maximum": 65535, "type": "integer" }, + "use_default_iou_values": { + "description": "use the default IOU RAM & NVRAM values", + "type": "boolean" + }, "startup_config_base64": { "description": "startup configuration base64 encoded", "type": "string" diff --git a/gns3server/server.py b/gns3server/server.py index b667be2a..5452ac23 100644 --- a/gns3server/server.py +++ b/gns3server/server.py @@ -39,6 +39,8 @@ from .config import Config from .handlers.jsonrpc_websocket import JSONRPCWebSocket from .handlers.version_handler import VersionHandler from .handlers.file_upload_handler import FileUploadHandler +from .builtins.server_version import server_version +from .builtins.interfaces import interfaces from .modules import MODULES import logging @@ -115,6 +117,11 @@ class Server(object): # instance.start() # starts the new process #======================================================================= + # special built-in to return the server version + JSONRPCWebSocket.register_destination("builtin.version", server_version) + # special built-in to return the available interfaces on this host + JSONRPCWebSocket.register_destination("builtin.interfaces", interfaces) + for module in MODULES: instance = module(module.__name__.lower(), "127.0.0.1", # ZeroMQ server address diff --git a/gns3server/version.py b/gns3server/version.py index dca48fbb..2799ab28 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,5 +23,5 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "1.0a4.dev1" +__version__ = "1.0a4.dev2" __version_info__ = (1, 0, 0, -99)