From d68a24e39da2fee17a9d3fe3dd6aa8156ff08da6 Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 26 Feb 2014 11:47:12 -0700 Subject: [PATCH] Extra documentation and checks. Support to rename switch & hub devices. --- gns3server/modules/dynamips/__init__.py | 34 ++- gns3server/modules/dynamips/backends/atmsw.py | 100 +++++++ .../modules/dynamips/backends/ethhub.py | 101 ++++++- gns3server/modules/dynamips/backends/ethsw.py | 118 +++++++- gns3server/modules/dynamips/backends/frsw.py | 99 +++++++ gns3server/modules/dynamips/backends/vm.py | 258 ++++++++++++++---- 6 files changed, 647 insertions(+), 63 deletions(-) diff --git a/gns3server/modules/dynamips/__init__.py b/gns3server/modules/dynamips/__init__.py index ede4b8b0..e6c8e8e8 100644 --- a/gns3server/modules/dynamips/__init__.py +++ b/gns3server/modules/dynamips/__init__.py @@ -106,10 +106,13 @@ class Dynamips(IModule): self._ethernet_hubs = {} def stop(self): + """ + Properly stops the module. + """ if self._hypervisor_manager: self._hypervisor_manager.stop_all_hypervisors() - IModule.stop(self) + IModule.stop(self) # this will stop the I/O loop @IModule.route("dynamips.reset") def reset(self, request): @@ -155,9 +158,20 @@ class Dynamips(IModule): :param request: JSON request """ + if request == None: + self.send_param_error() + return + + log.debug("received request {}".format(request)) + + #TODO: JSON schema validation + # starts the hypervisor manager if it hasn't been started yet if not self._hypervisor_manager: + #TODO: working dir support + log.info("starting the hypervisor manager with Dynamips working directory set to '{}'".format("/tmp")) self._hypervisor_manager = HypervisorManager(request["path"], "/tmp") + # apply settings to the hypervisor manager for name, value in request.items(): if hasattr(self._hypervisor_manager, name) and getattr(self._hypervisor_manager, name) != value: setattr(self._hypervisor_manager, name, value) @@ -177,7 +191,17 @@ class Dynamips(IModule): self.send_response(request) def create_nio(self, node, request): + """ + Creates a new NIO. + :param node: node requesting the NIO + :param request: the original request with the + necessary information to create the NIO + + :returns: a NIO object + """ + + #TODO: JSON schema validation nio = None if request["nio"] == "NIO_UDP": lport = request["lport"] @@ -215,6 +239,8 @@ class Dynamips(IModule): Allocates a UDP port in order to create an UDP NIO. :param node: the node that needs to allocate an UDP port + + :returns: dictionary with the allocated host/port info """ port = node.hypervisor.allocate_udp_port() @@ -244,6 +270,11 @@ class Dynamips(IModule): # return response def set_ghost_ios(self, router): + """ + Manages Ghost IOS support. + + :param router: Router instance + """ if not router.mmap: raise DynamipsError("mmap support is required to enable ghost IOS support") @@ -270,6 +301,7 @@ class Dynamips(IModule): ghost.delete() if router.ghost_file != ghost_instance: + # set the ghost file to the router router.ghost_status = 2 router.ghost_file = ghost_instance diff --git a/gns3server/modules/dynamips/backends/atmsw.py b/gns3server/modules/dynamips/backends/atmsw.py index 26428d1d..ff17bd13 100644 --- a/gns3server/modules/dynamips/backends/atmsw.py +++ b/gns3server/modules/dynamips/backends/atmsw.py @@ -31,9 +31,21 @@ class ATMSW(object): """ Creates a new ATM switch. + Optional request parameters: + - name (switch name) + + Response parameters: + - id (switch identifier) + - name (switch name) + :param request: JSON request """ + if request == None: + self.send_param_error() + return + + #TODO: JSON schema validation for the request name = None if request and "name" in request: name = request["name"] @@ -56,9 +68,19 @@ class ATMSW(object): """ Deletes a ATM switch. + Mandatory request parameters: + - id (switch identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) atmsw_id = request["id"] @@ -76,13 +98,35 @@ class ATMSW(object): """ Updates a ATM switch. + Mandatory request parameters: + - id (switch identifier) + + Optional request parameters: + - name (new switch name) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) atmsw_id = request["id"] atmsw = self._atm_switches[atmsw_id] + + # rename the switch if requested + if "name" in request and atmsw.name != request["name"]: + try: + atmsw.name = request["name"] + except DynamipsError as e: + self.send_custom_error(str(e)) + return + self.send_response(request) @IModule.route("dynamips.atmsw.allocate_udp_port") @@ -91,9 +135,22 @@ class ATMSW(object): Allocates a UDP port in order to create an UDP NIO for an ATM switch. + Mandatory request parameters: + - id (switch identifier) + - port_name (port name) + + Response parameters: + - port_name (port name) + - lhost (local host address) + - lport (allocated local port) + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) atmsw_id = request["id"] @@ -114,9 +171,39 @@ class ATMSW(object): """ Adds an NIO (Network Input/Output) for an ATM switch. + Mandatory request parameters: + - id (switch identifier) + - port (port identifier) + - mappings (VCs/VPs mapped to the port) + - nio (nio type, one of the following) + - "NIO_UDP" + - lport (local port) + - rhost (remote host) + - rport (remote port) + - "NIO_GenericEthernet" + - ethernet_device (Ethernet device name e.g. eth0) + - "NIO_LinuxEthernet" + - ethernet_device (Ethernet device name e.g. eth0) + - "NIO_TAP" + - tap_device (TAP device name e.g. tap0) + - "NIO_UNIX" + - local_file (path to UNIX socket file) + - remote_file (path to UNIX socket file) + - "NIO_VDE" + - control_file (path to VDE control file) + - local_file (path to VDE local file) + - "NIO_Null" + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) atmsw_id = request["id"] @@ -127,6 +214,8 @@ class ATMSW(object): try: nio = self.create_nio(atmsw, request) + if not nio: + raise DynamipsError("Requested NIO doesn't exist: {}".format(request["nio"])) except DynamipsError as e: self.send_custom_error(str(e)) return @@ -167,9 +256,20 @@ class ATMSW(object): """ Deletes an NIO (Network Input/Output). + Mandatory request parameters: + - id (switch identifier) + - port (port identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) atmsw_id = request["id"] diff --git a/gns3server/modules/dynamips/backends/ethhub.py b/gns3server/modules/dynamips/backends/ethhub.py index 192c2483..05e3ae23 100644 --- a/gns3server/modules/dynamips/backends/ethhub.py +++ b/gns3server/modules/dynamips/backends/ethhub.py @@ -28,11 +28,23 @@ class ETHHUB(object): @IModule.route("dynamips.ethhub.create") def ethhub_create(self, request): """ - Creates a new Ethernet switch. + Creates a new Ethernet hub. + + Optional request parameters: + - name (hub name) + + Response parameters: + - id (hub identifier) + - name (hub name) :param request: JSON request """ + if request == None: + self.send_param_error() + return + + #TODO: JSON schema validation for the request name = None if request and "name" in request: name = request["name"] @@ -55,9 +67,19 @@ class ETHHUB(object): """ Deletes a Ethernet hub. + Mandatory request parameters: + - id (hub identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) ethhub_id = request["id"] @@ -75,14 +97,34 @@ class ETHHUB(object): """ Updates a Ethernet hub. + Mandatory request parameters: + - id (hub identifier) + + Optional request parameters: + - name (new hub name) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) ethhub_id = request["id"] ethhub = self._ethernet_hubs[ethhub_id] - #ports = request["ports"] + + # rename the hub if requested + if "name" in request and ethhub.name != request["name"]: + try: + ethhub.name = request["name"] + except DynamipsError as e: + self.send_custom_error(str(e)) + return self.send_response(request) @@ -92,9 +134,22 @@ class ETHHUB(object): Allocates a UDP port in order to create an UDP NIO for an Ethernet hub. + Mandatory request parameters: + - id (hub identifier) + - port_name (port name) + + Response parameters: + - port_name (port name) + - lhost (local host address) + - lport (allocated local port) + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) ethhub_id = request["id"] @@ -115,9 +170,38 @@ class ETHHUB(object): """ Adds an NIO (Network Input/Output) for an Ethernet hub. + Mandatory request parameters: + - id (hub identifier) + - port (port identifier) + - nio (nio type, one of the following) + - "NIO_UDP" + - lport (local port) + - rhost (remote host) + - rport (remote port) + - "NIO_GenericEthernet" + - ethernet_device (Ethernet device name e.g. eth0) + - "NIO_LinuxEthernet" + - ethernet_device (Ethernet device name e.g. eth0) + - "NIO_TAP" + - tap_device (TAP device name e.g. tap0) + - "NIO_UNIX" + - local_file (path to UNIX socket file) + - remote_file (path to UNIX socket file) + - "NIO_VDE" + - control_file (path to VDE control file) + - local_file (path to VDE local file) + - "NIO_Null" + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) ethhub_id = request["id"] @@ -126,6 +210,8 @@ class ETHHUB(object): try: nio = self.create_nio(ethhub, request) + if not nio: + raise DynamipsError("Requested NIO doesn't exist: {}".format(request["nio"])) except DynamipsError as e: self.send_custom_error(str(e)) return @@ -144,9 +230,20 @@ class ETHHUB(object): """ Deletes an NIO (Network Input/Output). + Mandatory request parameters: + - id (hub identifier) + - port (port identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) ethhub_id = request["id"] diff --git a/gns3server/modules/dynamips/backends/ethsw.py b/gns3server/modules/dynamips/backends/ethsw.py index a56d1f9b..cf9ba5fe 100644 --- a/gns3server/modules/dynamips/backends/ethsw.py +++ b/gns3server/modules/dynamips/backends/ethsw.py @@ -30,9 +30,21 @@ class ETHSW(object): """ Creates a new Ethernet switch. + Optional request parameters: + - name (switch name) + + Response parameters: + - id (switch identifier) + - name (switch name) + :param request: JSON request """ + if request == None: + self.send_param_error() + return + + #TODO: JSON schema validation for the request name = None if request and "name" in request: name = request["name"] @@ -55,9 +67,19 @@ class ETHSW(object): """ Deletes a Ethernet switch. + Mandatory request parameters: + - id (switch identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) ethsw_id = request["id"] @@ -75,24 +97,51 @@ class ETHSW(object): """ Updates a Ethernet switch. + Mandatory request parameters: + - id (switch identifier) + - ports (ports settings) + + Optional request parameters: + - name (new switch name) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) ethsw_id = request["id"] ethsw = self._ethernet_switches[ethsw_id] ports = request["ports"] + # update the port settings for port, info in ports.items(): vlan = info["vlan"] port_type = info["type"] - if port_type == "access": - ethsw.set_access_port(int(port), vlan) - elif port_type == "dot1q": - ethsw.set_dot1q_port(int(port), vlan) - elif port_type == "qinq": - ethsw.set_qinq_port(int(port), vlan) + try: + if port_type == "access": + ethsw.set_access_port(int(port), vlan) + elif port_type == "dot1q": + ethsw.set_dot1q_port(int(port), vlan) + elif port_type == "qinq": + ethsw.set_qinq_port(int(port), vlan) + except DynamipsError as e: + self.send_custom_error(str(e)) + return + + # rename the switch if requested + if "name" in request and ethsw.name != request["name"]: + try: + ethsw.name = request["name"] + except DynamipsError as e: + self.send_custom_error(str(e)) + return self.send_response(request) @@ -102,9 +151,22 @@ class ETHSW(object): Allocates a UDP port in order to create an UDP NIO for an Ethernet switch. + Mandatory request parameters: + - id (switch identifier) + - port_name (port name) + + Response parameters: + - port_name (port name) + - lhost (local host address) + - lport (allocated local port) + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) ethsw_id = request["id"] @@ -125,9 +187,40 @@ class ETHSW(object): """ Adds an NIO (Network Input/Output) for an Ethernet switch. + Mandatory request parameters: + - id (switch identifier) + - port (port identifier) + - vlan (vlan identifier) + - port_type ("access", "dot1q" or "qinq") + - nio (nio type, one of the following) + - "NIO_UDP" + - lport (local port) + - rhost (remote host) + - rport (remote port) + - "NIO_GenericEthernet" + - ethernet_device (Ethernet device name e.g. eth0) + - "NIO_LinuxEthernet" + - ethernet_device (Ethernet device name e.g. eth0) + - "NIO_TAP" + - tap_device (TAP device name e.g. tap0) + - "NIO_UNIX" + - local_file (path to UNIX socket file) + - remote_file (path to UNIX socket file) + - "NIO_VDE" + - control_file (path to VDE control file) + - local_file (path to VDE local file) + - "NIO_Null" + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) ethsw_id = request["id"] @@ -138,6 +231,8 @@ class ETHSW(object): port_type = request["port_type"] try: nio = self.create_nio(ethsw, request) + if not nio: + raise DynamipsError("Requested NIO doesn't exist: {}".format(request["nio"])) except DynamipsError as e: self.send_custom_error(str(e)) return @@ -162,9 +257,20 @@ class ETHSW(object): """ Deletes an NIO (Network Input/Output). + Mandatory request parameters: + - id (switch identifier) + - port (port identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) ethsw_id = request["id"] diff --git a/gns3server/modules/dynamips/backends/frsw.py b/gns3server/modules/dynamips/backends/frsw.py index 260384d0..c6cd039c 100644 --- a/gns3server/modules/dynamips/backends/frsw.py +++ b/gns3server/modules/dynamips/backends/frsw.py @@ -30,9 +30,21 @@ class FRSW(object): """ Creates a new Frame-Relay switch. + Optional request parameters: + - name (switch name) + + Response parameters: + - id (switch identifier) + - name (switch name) + :param request: JSON request """ + if request == None: + self.send_param_error() + return + + #TODO: JSON schema validation for the request name = None if request and "name" in request: name = request["name"] @@ -55,9 +67,19 @@ class FRSW(object): """ Deletes a Frame Relay switch. + Mandatory request parameters: + - id (switch identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) frsw_id = request["id"] @@ -75,13 +97,34 @@ class FRSW(object): """ Updates a Frame Relay switch. + Mandatory request parameters: + - id (switch identifier) + + Optional request parameters: + - name (new switch name) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) frsw_id = request["id"] frsw = self._frame_relay_switches[frsw_id] + + # rename the switch if requested + if "name" in request and frsw.name != request["name"]: + try: + frsw.name = request["name"] + except DynamipsError as e: + self.send_custom_error(str(e)) + return self.send_response(request) @IModule.route("dynamips.frsw.allocate_udp_port") @@ -90,9 +133,22 @@ class FRSW(object): Allocates a UDP port in order to create an UDP NIO for an Frame Relay switch. + Mandatory request parameters: + - id (switch identifier) + - port_name (port name) + + Response parameters: + - port_name (port name) + - lhost (local host address) + - lport (allocated local port) + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) frsw_id = request["id"] @@ -113,9 +169,39 @@ class FRSW(object): """ Adds an NIO (Network Input/Output) for an Frame-Relay switch. + Mandatory request parameters: + - id (switch identifier) + - port (port identifier) + - mappings (VCs mapped to the port) + - nio (nio type, one of the following) + - "NIO_UDP" + - lport (local port) + - rhost (remote host) + - rport (remote port) + - "NIO_GenericEthernet" + - ethernet_device (Ethernet device name e.g. eth0) + - "NIO_LinuxEthernet" + - ethernet_device (Ethernet device name e.g. eth0) + - "NIO_TAP" + - tap_device (TAP device name e.g. tap0) + - "NIO_UNIX" + - local_file (path to UNIX socket file) + - remote_file (path to UNIX socket file) + - "NIO_VDE" + - control_file (path to VDE control file) + - local_file (path to VDE local file) + - "NIO_Null" + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) frsw_id = request["id"] @@ -126,6 +212,8 @@ class FRSW(object): try: nio = self.create_nio(frsw, request) + if not nio: + raise DynamipsError("Requested NIO doesn't exist: {}".format(request["nio"])) except DynamipsError as e: self.send_custom_error(str(e)) return @@ -153,9 +241,20 @@ class FRSW(object): """ Deletes an NIO (Network Input/Output). + Mandatory request parameters: + - id (switch identifier) + - port (port identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) frsw_id = request["id"] diff --git a/gns3server/modules/dynamips/backends/vm.py b/gns3server/modules/dynamips/backends/vm.py index 10ddb2af..7d1189c7 100644 --- a/gns3server/modules/dynamips/backends/vm.py +++ b/gns3server/modules/dynamips/backends/vm.py @@ -90,80 +90,106 @@ class VM(object): """ Creates a new VM (router). + Mandatory request parameters: + - platform (platform name e.g. c7200) + - image (path to IOS image) + - ram (amount of RAM in MB) + + Optional request parameters: + - name (vm name) + - console (console port number) + - aux (auxiliary console port number) + - mac_addr (MAC address) + + Response parameters: + - id (vm identifier) + - name (vm name) + :param request: JSON request """ if request == None: self.send_param_error() - else: - log.debug("received request {}".format(request)) + return - #TODO: JSON schema validation - name = None - if "name" in request: - name = request["name"] - platform = request["platform"] - image = request["image"] - ram = request["ram"] + log.debug("received request {}".format(request)) - try: - hypervisor = self._hypervisor_manager.allocate_hypervisor_for_router(image, ram) + #TODO: JSON schema validation + name = None + if "name" in request: + name = request["name"] + platform = request["platform"] + image = request["image"] + ram = request["ram"] - router = PLATFORMS[platform](hypervisor, name) - router.ram = ram - router.image = image - router.sparsemem = self._hypervisor_manager.sparse_memory_support - router.mmap = self._hypervisor_manager.mmap_support - if "console" in request: - router.console = request["console"] - if "aux" in request: - router.aux = request["aux"] - if "mac_addr" in request: - router.mac_addr = request["mac_addr"] + try: + hypervisor = self._hypervisor_manager.allocate_hypervisor_for_router(image, ram) - # JIT sharing support - if self._hypervisor_manager.jit_sharing_support: - jitsharing_groups = hypervisor.jitsharing_groups - ios_image = os.path.basename(image) - if ios_image in jitsharing_groups: - router.jit_sharing_group = jitsharing_groups[ios_image] - else: - new_jit_group = -1 - for jit_group in range(0, 127): - if jit_group not in jitsharing_groups.values(): - new_jit_group = jit_group - break - if new_jit_group == -1: - raise DynamipsError("All JIT groups are allocated!") - router.jit_sharing_group = new_jit_group + router = PLATFORMS[platform](hypervisor, name) + router.ram = ram + router.image = image + router.sparsemem = self._hypervisor_manager.sparse_memory_support + router.mmap = self._hypervisor_manager.mmap_support + if "console" in request: + router.console = request["console"] + if "aux" in request: + router.aux = request["aux"] + if "mac_addr" in request: + router.mac_addr = request["mac_addr"] - # Ghost IOS support - if self._hypervisor_manager.ghost_ios_support: - self.set_ghost_ios(router) + # JIT sharing support + if self._hypervisor_manager.jit_sharing_support: + jitsharing_groups = hypervisor.jitsharing_groups + ios_image = os.path.basename(image) + if ios_image in jitsharing_groups: + router.jit_sharing_group = jitsharing_groups[ios_image] + else: + new_jit_group = -1 + for jit_group in range(0, 127): + if jit_group not in jitsharing_groups.values(): + new_jit_group = jit_group + break + if new_jit_group == -1: + raise DynamipsError("All JIT groups are allocated!") + router.jit_sharing_group = new_jit_group - except DynamipsError as e: - hypervisor.decrease_memory_load(ram) - if hypervisor.memory_load == 0 and not hypervisor.devices: - hypervisor.stop() - self._hypervisor_manager.hypervisors.remove(hypervisor) - self.send_custom_error(str(e)) - return + # Ghost IOS support + if self._hypervisor_manager.ghost_ios_support: + self.set_ghost_ios(router) - response = {"name": router.name, - "id": router.id} - defaults = router.defaults() - response.update(defaults) - self._routers[router.id] = router - self.send_response(response) + except DynamipsError as e: + hypervisor.decrease_memory_load(ram) + if hypervisor.memory_load == 0 and not hypervisor.devices: + hypervisor.stop() + self._hypervisor_manager.hypervisors.remove(hypervisor) + self.send_custom_error(str(e)) + return + + response = {"name": router.name, + "id": router.id} + defaults = router.defaults() + response.update(defaults) + self._routers[router.id] = router + self.send_response(response) @IModule.route("dynamips.vm.delete") def vm_delete(self, request): """ Deletes a VM (router). + Mandatory request parameters: + - id (vm identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) router_id = request["id"] @@ -181,9 +207,19 @@ class VM(object): """ Starts a VM (router) + Mandatory request parameters: + - id (vm identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) router_id = request["id"] @@ -200,9 +236,19 @@ class VM(object): """ Stops a VM (router) + Mandatory request parameters: + - id (vm identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) router_id = request["id"] @@ -219,9 +265,19 @@ class VM(object): """ Suspends a VM (router) + Mandatory request parameters: + - id (vm identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) router_id = request["id"] @@ -238,9 +294,19 @@ class VM(object): """ Reloads a VM (router) + Mandatory request parameters: + - id (vm identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) router_id = request["id"] @@ -259,9 +325,22 @@ class VM(object): """ Updates settings for a VM (router). + Mandatory request parameters: + - id (vm identifier) + + Optional request parameters: + - any setting to update + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) router_id = request["id"] @@ -322,9 +401,23 @@ class VM(object): """ Get idle-pc proposals. + Mandatory request parameters: + - id (vm identifier) + + Optional request parameters: + - compute (returns previously compute idle-pc values if False) + + Response parameters: + - id (vm identifier) + - idlepcs (idle-pc values in an array) + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) router_id = request["id"] @@ -334,7 +427,7 @@ class VM(object): if "compute" in request and request["compute"] == False: idlepcs = router.show_idle_pc_prop() else: - # reset the current idlepc value + # reset the current idle-pc value before calculating a new one router.idlepc = "0x0" idlepcs = router.get_idle_pc_prop() except DynamipsError as e: @@ -350,9 +443,22 @@ class VM(object): """ Allocates a UDP port in order to create an UDP NIO. + Mandatory request parameters: + - id (vm identifier) + - port_name (port name e.g fastEthernet1/0) + + Response parameters: + - port_name (port name e.g fastEthernet1/0) + - lhost (local host address) + - lport (allocated local port) + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) router_id = request["id"] @@ -373,9 +479,39 @@ class VM(object): """ Adds an NIO (Network Input/Output) for a VM (router). + Mandatory request parameters: + - id (vm identifier) + - slot (slot identifier) + - port (port identifier) + - nio (nio type, one of the following) + - "NIO_UDP" + - lport (local port) + - rhost (remote host) + - rport (remote port) + - "NIO_GenericEthernet" + - ethernet_device (Ethernet device name e.g. eth0) + - "NIO_LinuxEthernet" + - ethernet_device (Ethernet device name e.g. eth0) + - "NIO_TAP" + - tap_device (TAP device name e.g. tap0) + - "NIO_UNIX" + - local_file (path to UNIX socket file) + - remote_file (path to UNIX socket file) + - "NIO_VDE" + - control_file (path to VDE control file) + - local_file (path to VDE local file) + - "NIO_Null" + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) router_id = request["id"] @@ -386,6 +522,8 @@ class VM(object): try: nio = self.create_nio(router, request) + if not nio: + raise DynamipsError("Requested NIO doesn't exist: {}".format(request["nio"])) except DynamipsError as e: self.send_custom_error(str(e)) return @@ -404,9 +542,21 @@ class VM(object): """ Deletes an NIO (Network Input/Output). + Mandatory request parameters: + - id (vm identifier) + - slot (slot identifier) + - port (port identifier) + + Response parameters: + - same as original request + :param request: JSON request """ + if request == None: + self.send_param_error() + return + #TODO: JSON schema validation for the request log.debug("received request {}".format(request)) router_id = request["id"]