async def _set_vcpus_ram(self, vcpus, ram): """ Set the number of vCPU cores and amount of RAM for the GNS3 VM. :param vcpus: number of vCPU cores :param ram: amount of RAM """ # memory must be a multiple of 4 (VMware requirement) if ram % 4 != 0: raise GNS3VMError("Allocated memory {} for the GNS3 VM must be a multiple of 4".format(ram)) available_vcpus = psutil.cpu_count(logical=True) if vcpus > available_vcpus: raise GNS3VMError("You have allocated too many vCPUs for the GNS3 VM! (max available is {} vCPUs)".format(available_vcpus)) try: pairs = VMware.parse_vmware_file(self._vmx_path) if vcpus > 1: pairs["numvcpus"] = str(vcpus) cores_per_sockets = int(vcpus / psutil.cpu_count(logical=False)) if cores_per_sockets > 1: pairs["cpuid.corespersocket"] = str(cores_per_sockets) pairs["memsize"] = str(ram) VMware.write_vmx_file(self._vmx_path, pairs) log.info("GNS3 VM vCPU count set to {} and RAM amount set to {}".format(vcpus, ram)) except OSError as e: raise GNS3VMError('Could not read/write VMware VMX file "{}": {}'.format(self._vmx_path, e))
async def delete_nio(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) adapter_number = int(request.match_info["adapter_number"]) await vm.adapter_remove_nio_binding(adapter_number) response.set_status(204)
def stop_capture(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) adapter_number = int(request.match_info["adapter_number"]) yield from vm.stop_capture(adapter_number) response.set_status(204)
async def stream_pcap_file(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) adapter_number = int(request.match_info["adapter_number"]) nio = vm.get_nio(adapter_number) await vmware_manager.stream_pcap_file(nio, vm.project.id, request, response)
def test_parse_vmware_file(manager, tmpdir): path = str(tmpdir / "test.vmx") with open(path, "w+") as f: f.write('displayname = "GNS3 VM"\nguestOS = "ubuntu-64"') vmx = VMware.parse_vmware_file(path) assert vmx["displayname"] == "GNS3 VM" assert vmx["guestos"] == "ubuntu-64"
def start_capture(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) adapter_number = int(request.match_info["adapter_number"]) pcap_file_path = os.path.join(vm.project.capture_working_directory(), request.json["capture_file_name"]) yield from vm.start_capture(adapter_number, pcap_file_path) response.json({"pcap_file_path": pcap_file_path})
def allocate_vmnet(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) vmware_manager.refresh_vmnet_list(ubridge=False) vmnet = vmware_manager.allocate_vmnet() vm.vmnets.append(vmnet) response.set_status(201) response.json({"vmnet": vmnet})
def start(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) if vm.check_hw_virtualization(): pm = ProjectManager.instance() if pm.check_hardware_virtualization(vm) is False: raise HTTPConflict(text="Cannot start VM because hardware virtualization (VT-x/AMD-V) is already used by another software like VirtualBox or KVM (on Linux)") yield from vm.start() response.set_status(204)
def update_nio(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) nio = vm.ethernet_adapters[int(request.match_info["adapter_number"])] if "filters" in request.json and nio: nio.filters = request.json["filters"] yield from vm.adapter_update_nio_binding(int(request.match_info["adapter_number"]), nio) response.set_status(201) response.json(request.json)
async def update_nio(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) adapter_number = int(request.match_info["adapter_number"]) nio = vm.get_nio(adapter_number) if "filters" in request.json: nio.filters = request.json["filters"] await vm.adapter_update_nio_binding(adapter_number, nio) response.set_status(201) response.json(request.json)
def create_nio(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) nio_type = request.json["type"] if nio_type not in ("nio_udp", "nio_vmnet", "nio_nat", "nio_tap"): raise HTTPConflict(text="NIO of type {} is not supported".format(nio_type)) nio = vmware_manager.create_nio(request.json) yield from vm.adapter_add_nio_binding(int(request.match_info["adapter_number"]), nio) response.set_status(201) response.json(nio)
def update(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) for name, value in request.json.items(): if hasattr(vm, name) and getattr(vm, name) != value: setattr(vm, name, value) vm.updated() response.json(vm)
def update(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) # update the console first to avoid issue if updating console type vm.console = request.json.pop("console", vm.console) for name, value in request.json.items(): if hasattr(vm, name) and getattr(vm, name) != value: setattr(vm, name, value) vm.updated() response.json(vm)
async def _set_extra_options(self): try: """ Due to bug/change in VMWare 14 we're not able to pass Hardware Virtualization in GNS3VM. We only enable this when it's not present in current configuration and user hasn't deactivated that. """ extra_config = ( ("vhv.enable", "TRUE"), ) pairs = VMware.parse_vmware_file(self._vmx_path) updated = False for key, value in extra_config: if key not in pairs.keys(): pairs[key] = value updated = True log.info("GNS3 VM VMX `{}` set to `{}`".format(key, value)) if updated: VMware.write_vmx_file(self._vmx_path, pairs) log.info("GNS3 VM VMX has been updated.") except OSError as e: raise GNS3VMError('Could not read/write VMware VMX file "{}": {}'.format(self._vmx_path, e))
def update(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node( request.match_info["node_id"], project_id=request.match_info["project_id"]) for name, value in request.json.items(): if hasattr(vm, name) and getattr(vm, name) != value: setattr(vm, name, value) vm.updated() response.json(vm)
def update_nio(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node( request.match_info["node_id"], project_id=request.match_info["project_id"]) nio = vm.ethernet_adapters[int(request.match_info["adapter_number"])] if "filters" in request.json and nio: nio.filters = request.json["filters"] yield from vm.adapter_update_nio_binding( int(request.match_info["adapter_number"]), nio) response.set_status(201) response.json(request.json)
async def _set_extra_options(self): try: """ Due to bug/change in VMWare 14 we're not able to pass Hardware Virtualization in GNS3VM. We only enable this when it's not present in current configuration and user hasn't deactivated that. """ extra_config = (("vhv.enable", "TRUE"), ) pairs = VMware.parse_vmware_file(self._vmx_path) updated = False for key, value in extra_config: if key not in pairs.keys(): pairs[key] = value updated = True log.info("GNS3 VM VMX `{}` set to `{}`".format(key, value)) if updated: VMware.write_vmx_file(self._vmx_path, pairs) log.info("GNS3 VM VMX has been updated.") except OSError as e: raise GNS3VMError( 'Could not read/write VMware VMX file "{}": {}'.format( self._vmx_path, e))
async def update_nio(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node( request.match_info["node_id"], project_id=request.match_info["project_id"]) adapter_number = int(request.match_info["adapter_number"]) nio = vm.get_nio(adapter_number) if "filters" in request.json: nio.filters = request.json["filters"] await vm.adapter_update_nio_binding(adapter_number, nio) response.set_status(201) response.json(request.json)
async def create_nio(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node( request.match_info["node_id"], project_id=request.match_info["project_id"]) nio_type = request.json["type"] if nio_type not in ("nio_udp", "nio_vmnet", "nio_nat", "nio_tap"): raise HTTPConflict( text="NIO of type {} is not supported".format(nio_type)) nio = vmware_manager.create_nio(request.json) await vm.adapter_add_nio_binding( int(request.match_info["adapter_number"]), nio) response.set_status(201) response.json(nio)
async def start(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node( request.match_info["node_id"], project_id=request.match_info["project_id"]) if vm.check_hw_virtualization(): pm = ProjectManager.instance() if pm.check_hardware_virtualization(vm) is False: raise HTTPConflict( text= "Cannot start VM because hardware virtualization (VT-x/AMD-V) is already used by another software like VirtualBox or KVM (on Linux)" ) await vm.start() response.set_status(204)
def create(request, response): vmware_manager = VMware.instance() vm = yield from vmware_manager.create_node(request.json.pop("name"), request.match_info["project_id"], request.json.get("node_id"), request.json.pop("vmx_path"), linked_clone=request.json.pop("linked_clone"), console=request.json.get("console", None)) for name, value in request.json.items(): if name != "node_id": if hasattr(vm, name) and getattr(vm, name) != value: setattr(vm, name, value) response.set_status(201) response.json(vm)
def create(request, response): vmware_manager = VMware.instance() vm = yield from vmware_manager.create_node( request.json.pop("name"), request.match_info["project_id"], request.json.get("node_id"), request.json.pop("vmx_path"), linked_clone=request.json.pop("linked_clone"), console=request.json.get("console", None)) for name, value in request.json.items(): if name != "node_id": if hasattr(vm, name) and getattr(vm, name) != value: setattr(vm, name, value) response.set_status(201) response.json(vm)
def __init__(self, controller): self._engine = "vmware" super().__init__(controller) self._vmware_manager = VMware() self._vmx_path = None
def delete(request, response): # check the project_id exists ProjectManager.instance().get_project(request.match_info["project_id"]) yield from VMware.instance().delete_node(request.match_info["node_id"]) response.set_status(204)
def show(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) response.json(vm)
def get_vms(request, response): vmware_manager = VMware.instance() vms = yield from vmware_manager.list_vms() response.json(vms)
def manager(port_manager): m = VMware.instance() m.port_manager = port_manager return m
async def console_ws(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) return await vm.start_websocket_console(request)
async def manager(loop, port_manager): m = VMware.instance() m.port_manager = port_manager return m
async def resume(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) await vm.resume() response.set_status(204)
def reload(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) yield from vm.reload() response.set_status(204)
async def reload(request, response): vmware_manager = VMware.instance() vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) await vm.reload() response.set_status(204)
class VMwareGNS3VM(BaseGNS3VM): def __init__(self, controller): self._engine = "vmware" super().__init__(controller) self._vmware_manager = VMware() self._vmx_path = None @property def vmx_path(self): return self._vmx_path @asyncio.coroutine def _execute(self, subcommand, args, timeout=60, log_level=logging.INFO): try: result = yield from self._vmware_manager.execute( subcommand, args, timeout, log_level=log_level) return (''.join(result)) except VMwareError as e: raise GNS3VMError( "Error while executing VMware command: {}".format(e)) @asyncio.coroutine def _is_running(self): result = yield from self._vmware_manager.execute("list", []) if self._vmx_path in result: return True return False @asyncio.coroutine def _set_vcpus_ram(self, vcpus, ram): """ Set the number of vCPU cores and amount of RAM for the GNS3 VM. :param vcpus: number of vCPU cores :param ram: amount of RAM """ # memory must be a multiple of 4 (VMware requirement) if ram % 4 != 0: raise GNS3VMError( "Allocated memory {} for the GNS3 VM must be a multiple of 4". format(ram)) available_vcpus = psutil.cpu_count(logical=False) if vcpus > available_vcpus: raise GNS3VMError( "You have allocated too many vCPUs for the GNS3 VM! (max available is {} vCPUs)" .format(available_vcpus)) try: pairs = VMware.parse_vmware_file(self._vmx_path) pairs["numvcpus"] = str(vcpus) pairs["memsize"] = str(ram) VMware.write_vmx_file(self._vmx_path, pairs) log.info( "GNS3 VM vCPU count set to {} and RAM amount set to {}".format( vcpus, ram)) except OSError as e: raise GNS3VMError( 'Could not read/write VMware VMX file "{}": {}'.format( self._vmx_path, e)) @asyncio.coroutine def _set_extra_options(self): try: """ Due to bug/change in VMWare 14 we're not able to pass Hardware Virtualization in GNS3VM. We only enable this when it's not present in current configuration and user hasn't deactivated that. """ extra_config = (("vhv.enable", "TRUE"), ) pairs = VMware.parse_vmware_file(self._vmx_path) updated = False for key, value in extra_config: if key not in pairs.keys(): pairs[key] = value updated = True log.info("GNS3 VM VMX `{}` set to `{}`".format(key, value)) if updated: VMware.write_vmx_file(self._vmx_path, pairs) log.info("GNS3 VM VMX has been updated.") except OSError as e: raise GNS3VMError( 'Could not read/write VMware VMX file "{}": {}'.format( self._vmx_path, e)) @asyncio.coroutine def list(self): """ List all VMware VMs """ try: return (yield from self._vmware_manager.list_vms()) except VMwareError as e: raise GNS3VMError("Could not list VMware VMs: {}".format(str(e))) @asyncio.coroutine def start(self): """ Starts the GNS3 VM. """ vms = yield from self.list() for vm in vms: if vm["vmname"] == self.vmname: self._vmx_path = vm["vmx_path"] break # check we have a valid VMX file path if not self._vmx_path: raise GNS3VMError("VMWare VM {} not found".format(self.vmname)) if not os.path.exists(self._vmx_path): raise GNS3VMError("VMware VMX file {} doesn't exist".format( self._vmx_path)) # check if the VMware guest tools are installed vmware_tools_state = yield from self._execute("checkToolsState", [self._vmx_path]) if vmware_tools_state not in ("installed", "running"): raise GNS3VMError("VMware tools are not installed in {}".format( self.vmname)) try: running = yield from self._is_running() except VMwareError as e: raise GNS3VMError("Could not list VMware VMs: {}".format(str(e))) if not running: log.info("Update GNS3 VM settings") # set the number of vCPUs and amount of RAM yield from self._set_vcpus_ram(self.vcpus, self.ram) yield from self._set_extra_options() # start the VM args = [self._vmx_path] if self._headless: args.extend(["nogui"]) yield from self._execute("start", args) log.info("GNS3 VM has been started") # get the guest IP address (first adapter only) trial = 120 guest_ip_address = "" log.info("Waiting for GNS3 VM IP") while True: guest_ip_address = yield from self._execute( "readVariable", [self._vmx_path, "guestVar", "gns3.eth0"], timeout=120, log_level=logging.DEBUG) guest_ip_address = guest_ip_address.strip() if len(guest_ip_address) != 0: break trial -= 1 # If ip not found fallback on old method if trial == 0: log.warning( "No IP found for the VM via readVariable fallback to getGuestIPAddress" ) guest_ip_address = yield from self._execute( "getGuestIPAddress", [self._vmx_path, "-wait"], timeout=120) break yield from asyncio.sleep(1) self.ip_address = guest_ip_address log.info("GNS3 VM IP address set to {}".format(guest_ip_address)) self.running = True @asyncio.coroutine def suspend(self): """ Suspend the GNS3 VM. """ if self._vmx_path is None: raise GNS3VMError("No VMX path configured, can't suspend the VM") try: yield from self._execute("suspend", [self._vmx_path]) except GNS3VMError as e: log.warning("Error when suspending the VM: {}".format(str(e))) log.info("GNS3 VM has been suspended") self.running = False @asyncio.coroutine def stop(self): """ Stops the GNS3 VM. """ if self._vmx_path is None: raise GNS3VMError("No VMX path configured, can't stop the VM") try: yield from self._execute("stop", [self._vmx_path, "soft"]) except GNS3VMError as e: log.warning("Error when stopping the VM: {}".format(str(e))) log.info("GNS3 VM has been stopped") self.running = False
async def get_vms(request, response): vmware_manager = VMware.instance() vms = await vmware_manager.list_vms() response.json(vms)
class VMwareGNS3VM(BaseGNS3VM): def __init__(self, controller): self._engine = "vmware" super().__init__(controller) self._vmware_manager = VMware() self._vmx_path = None @property def vmx_path(self): return self._vmx_path @asyncio.coroutine def _execute(self, subcommand, args, timeout=60, log_level=logging.INFO): try: result = yield from self._vmware_manager.execute(subcommand, args, timeout, log_level=log_level) return (''.join(result)) except VMwareError as e: raise GNS3VMError("Error while executing VMware command: {}".format(e)) @asyncio.coroutine def _is_running(self): result = yield from self._vmware_manager.execute("list", []) if self._vmx_path in result: return True return False @asyncio.coroutine def _set_vcpus_ram(self, vcpus, ram): """ Set the number of vCPU cores and amount of RAM for the GNS3 VM. :param vcpus: number of vCPU cores :param ram: amount of RAM """ # memory must be a multiple of 4 (VMware requirement) if ram % 4 != 0: raise GNS3VMError("Allocated memory {} for the GNS3 VM must be a multiple of 4".format(ram)) available_vcpus = psutil.cpu_count(logical=False) if vcpus > available_vcpus: raise GNS3VMError("You have allocated too many vCPUs for the GNS3 VM! (max available is {} vCPUs)".format(available_vcpus)) try: pairs = VMware.parse_vmware_file(self._vmx_path) pairs["numvcpus"] = str(vcpus) pairs["memsize"] = str(ram) VMware.write_vmx_file(self._vmx_path, pairs) log.info("GNS3 VM vCPU count set to {} and RAM amount set to {}".format(vcpus, ram)) except OSError as e: raise GNS3VMError('Could not read/write VMware VMX file "{}": {}'.format(self._vmx_path, e)) @asyncio.coroutine def list(self): """ List all VMware VMs """ try: return (yield from self._vmware_manager.list_vms()) except VMwareError as e: raise GNS3VMError("Could not list VMware VMs: {}".format(str(e))) @asyncio.coroutine def start(self): """ Starts the GNS3 VM. """ vms = yield from self.list() for vm in vms: if vm["vmname"] == self.vmname: self._vmx_path = vm["vmx_path"] break # check we have a valid VMX file path if not self._vmx_path: raise GNS3VMError("VMWare VM {} not found".format(self.vmname)) if not os.path.exists(self._vmx_path): raise GNS3VMError("VMware VMX file {} doesn't exist".format(self._vmx_path)) # check if the VMware guest tools are installed vmware_tools_state = yield from self._execute("checkToolsState", [self._vmx_path]) if vmware_tools_state not in ("installed", "running"): raise GNS3VMError("VMware tools are not installed in {}".format(self.vmname)) try: running = yield from self._is_running() except VMwareError as e: raise GNS3VMError("Could not list VMware VMs: {}".format(str(e))) if not running: log.info("Update GNS3 VM settings") # set the number of vCPUs and amount of RAM yield from self._set_vcpus_ram(self.vcpus, self.ram) # start the VM args = [self._vmx_path] if self._headless: args.extend(["nogui"]) yield from self._execute("start", args) log.info("GNS3 VM has been started") # get the guest IP address (first adapter only) trial = 120 guest_ip_address = "" log.info("Waiting for GNS3 VM IP") while True: guest_ip_address = yield from self._execute("readVariable", [self._vmx_path, "guestVar", "gns3.eth0"], timeout=120, log_level=logging.DEBUG) guest_ip_address = guest_ip_address.strip() if len(guest_ip_address) != 0: break trial -= 1 # If ip not found fallback on old method if trial == 0: log.warn("No IP found for the VM via readVariable fallback to getGuestIPAddress") guest_ip_address = yield from self._execute("getGuestIPAddress", [self._vmx_path, "-wait"], timeout=120) break yield from asyncio.sleep(1) self.ip_address = guest_ip_address log.info("GNS3 VM IP address set to {}".format(guest_ip_address)) self.running = True @asyncio.coroutine def suspend(self): """ Suspend the GNS3 VM. """ if self._vmx_path is None: raise GNS3VMError("No VMX path configured, can't suspend the VM") try: yield from self._execute("suspend", [self._vmx_path]) except GNS3VMError as e: log.warning("Error when suspending the VM: {}".format(str(e))) log.info("GNS3 VM has been suspended") self.running = False @asyncio.coroutine def stop(self): """ Stops the GNS3 VM. """ if self._vmx_path is None: raise GNS3VMError("No VMX path configured, can't stop the VM") try: yield from self._execute("stop", [self._vmx_path, "soft"]) except GNS3VMError as e: log.warning("Error when stopping the VM: {}".format(str(e))) log.info("GNS3 VM has been stopped") self.running = False