def test_startLocalServer(tmpdir, local_config): local_server_path = str(tmpdir / "gns3server") open(local_server_path, "w+").close() with open(str(tmpdir / "test.cfg"), "w+") as f: json.dump({ "Servers": { "local_server": { "path": local_server_path, } }, "version": "1.4" }, f) local_config.setConfigFilePath(str(tmpdir / "test.cfg")) Servers._instance = None with patch("gns3.local_config.LocalConfig.configDirectory") as mock_local_config: mock_local_config.return_value = str(tmpdir) process_mock = MagicMock() with patch("subprocess.Popen", return_value=process_mock) as mock: # If everything work fine the command is still running and a timeout is raised process_mock.communicate.side_effect = subprocess.TimeoutExpired("test", 1) Servers.instance().startLocalServer() mock.assert_called_with([local_server_path, '--host=127.0.0.1', '--port=3080', '--local', '--controller', '--debug', '--log=' + str(tmpdir / "gns3_server.log"), '--pid=' + str(tmpdir / "gns3_server.pid") ])
def gns3vm_server(): from gns3.servers import Servers Servers.instance().initVMServer() print(Servers.instance().vmServer()) return Servers.instance().vmServer()
def validateCurrentPage(self): """ Validates the server. """ if self.currentPage() == self.uiServerWizardPage: # FIXME: prevent users to use "cloud" if self.uiCloudRadioButton.isChecked(): QtGui.QMessageBox.critical(self, "Cloud", "Sorry not implemented yet!") return False if VirtualBox.instance().settings( )["use_local_server"] or self.uiLocalRadioButton.isChecked(): server = Servers.instance().localServer() else: if not Servers.instance().remoteServers(): QtGui.QMessageBox.critical( self, "Remote server", "There is no remote server registered in VirtualBox preferences" ) return False server = self.uiRemoteServersComboBox.itemData( self.uiRemoteServersComboBox.currentIndex()) self._server = server if self.currentPage() == self.uiVirtualBoxWizardPage: if not self.uiVMListComboBox.count(): QtGui.QMessageBox.critical( self, "VirtualBox VMs", "There is no VirtualBox VM available!") return False return True
def validateCurrentPage(self): """ Validates the server. """ if hasattr(self, "uiNameWizardPage") and self.currentPage() == self.uiNameWizardPage: name = self.uiNameLineEdit.text() for device in self._devices.values(): if device["name"] == name: QtWidgets.QMessageBox.critical(self, "Name", "{} is already used, please choose another name".format(name)) return False elif self.currentPage() == self.uiServerWizardPage: if self.uiRemoteRadioButton.isChecked(): if not Servers.instance().remoteServers(): QtWidgets.QMessageBox.critical(self, "Remote server", "There is no remote server registered in your preferences") return False self._server = self.uiRemoteServersComboBox.itemData(self.uiRemoteServersComboBox.currentIndex()) elif hasattr(self, "uiVMRadioButton") and self.uiVMRadioButton.isChecked(): gns3_vm_server = Servers.instance().vmServer() if gns3_vm_server is None: QtWidgets.QMessageBox.critical(self, "GNS3 VM", "The GNS3 VM is not running") return False self._server = gns3_vm_server else: self._server = Servers.instance().localServer() return True
def initializePage(self, page_id): if self.page(page_id) == self.uiServerWizardPage: self.uiRemoteServersComboBox.clear() if len(Servers.instance().remoteServers().values()) == 0: self.uiRemoteRadioButton.setEnabled(False) else: for server in Servers.instance().remoteServers().values(): self.uiRemoteServersComboBox.addItem(server.url(), server) if hasattr( self, "uiVMRadioButton") and not GNS3VM.instance().isRunning(): self.uiVMRadioButton.setEnabled(False) if hasattr(self, "uiVMRadioButton") and GNS3VM.instance().isRunning(): self.uiVMRadioButton.setChecked(True) elif self._use_local_server and self.uiLocalRadioButton.isEnabled( ): self.uiLocalRadioButton.setChecked(True) else: if self.uiRemoteRadioButton.isEnabled(): self.uiRemoteRadioButton.setChecked(True) else: self.uiLocalRadioButton.setChecked(True)
def __init__(self, devices, use_local_server, parent): super().__init__(parent) self.setupUi(self) self.setModal(True) self._devices = devices self._use_local_server = use_local_server self.setWizardStyle(QtWidgets.QWizard.ModernStyle) if sys.platform.startswith("darwin"): # we want to see the cancel button on OSX self.setOptions(QtWidgets.QWizard.NoDefaultButton) self.uiRemoteRadioButton.toggled.connect(self._remoteServerToggledSlot) if hasattr(self, "uiVMRadioButton"): self.uiVMRadioButton.toggled.connect(self._vmToggledSlot) self.uiLocalRadioButton.toggled.connect(self._localToggledSlot) if hasattr(self, "uiLoadBalanceCheckBox"): self.uiLoadBalanceCheckBox.toggled.connect(self._loadBalanceToggledSlot) # By default we use the local server self._server = Servers.instance().localServer() self.uiLocalRadioButton.setChecked(True) self._localToggledSlot(True) if Servers.instance().isNonLocalServerConfigured() is False: # skip the server page if we use the local server self.setStartId(1)
def validateCurrentPage(self): """ Validates the server. """ if hasattr(self, "uiNamePlatformWizardPage") and self.currentPage() == self.uiNamePlatformWizardPage: name = self.uiNameLineEdit.text() for device in self._devices.values(): if device["name"] == name: QtWidgets.QMessageBox.critical(self, "Name", "{} is already used, please choose another name".format(name)) return False elif self.currentPage() == self.uiServerWizardPage: if self.uiRemoteRadioButton.isChecked(): if not Servers.instance().remoteServers(): QtWidgets.QMessageBox.critical(self, "Remote server", "There is no remote server registered in your preferences") return False self._server = self.uiRemoteServersComboBox.itemData(self.uiRemoteServersComboBox.currentIndex()) elif hasattr(self, "uiVMRadioButton") and self.uiVMRadioButton.isChecked(): gns3_vm_server = Servers.instance().vmServer() if gns3_vm_server is None: QtWidgets.QMessageBox.critical(self, "GNS3 VM", "The GNS3 VM is not running") return False self._server = gns3_vm_server else: self._server = Servers.instance().localServer() return True
def test_startLocalServer(tmpdir, local_config): local_server_path = str(tmpdir / "gns3server") open(local_server_path, "w+").close() with open(str(tmpdir / "test.cfg"), "w+") as f: json.dump({ "Servers": { "local_server": { "path": local_server_path, } }, "version": "1.4" }, f) local_config.setConfigFilePath(str(tmpdir / "test.cfg")) Servers._instance = None with patch("gns3.local_config.LocalConfig.configDirectory") as mock_local_config: mock_local_config.return_value = str(tmpdir) with patch("subprocess.Popen") as mock: Servers.instance().startLocalServer() mock.assert_called_with([local_server_path, '--host=127.0.0.1', '--port=8000', '--local', '--debug', '--log=' + str(tmpdir / "gns3_server.log"), '--pid=' + str(tmpdir / "gns3_server.pid") ])
def validateCurrentPage(self): """ Validates the server. """ if self.currentPage() == self.uiServerWizardPage: # FIXME: prevent users to use "cloud" if self.uiCloudRadioButton.isChecked(): QtGui.QMessageBox.critical(self, "Cloud", "Sorry not implemented yet!") return False if VirtualBox.instance().settings()["use_local_server"] or self.uiLocalRadioButton.isChecked(): server = Servers.instance().localServer() else: if not Servers.instance().remoteServers(): QtGui.QMessageBox.critical(self, "Remote server", "There is no remote server registered in VirtualBox preferences") return False server = self.uiRemoteServersComboBox.itemData(self.uiRemoteServersComboBox.currentIndex()) self._server = server if self.currentPage() == self.uiVirtualBoxWizardPage: if not self.uiVMListComboBox.count(): QtGui.QMessageBox.critical(self, "VirtualBox VMs", "There is no VirtualBox VM available!") return False return True
def test_startLocalServer(tmpdir, local_config): local_server_path = str(tmpdir / "gns3server") open(local_server_path, "w+").close() with open(str(tmpdir / "test.cfg"), "w+") as f: json.dump( { "Servers": { "local_server": { "path": local_server_path, } }, "version": "1.4" }, f) local_config.setConfigFilePath(str(tmpdir / "test.cfg")) Servers._instance = None with patch("gns3.local_config.LocalConfig.configDirectory" ) as mock_local_config: mock_local_config.return_value = str(tmpdir) with patch("subprocess.Popen") as mock: Servers.instance().startLocalServer() mock.assert_called_with([ local_server_path, '--host=127.0.0.1', '--port=8000', '--local', '--debug', '--log=' + str(tmpdir / "gns3_server.log"), '--pid=' + str(tmpdir / "gns3_server.pid") ])
def test_startLocalServer(tmpdir, local_config): local_server_path = str(tmpdir / "gns3server") open(local_server_path, "w+").close() with open(str(tmpdir / "test.cfg"), "w+") as f: json.dump( { "Servers": { "local_server": { "path": local_server_path, } }, "version": "1.4" }, f) local_config.setConfigFilePath(str(tmpdir / "test.cfg")) Servers._instance = None with patch("gns3.local_config.LocalConfig.configDirectory" ) as mock_local_config: mock_local_config.return_value = str(tmpdir) process_mock = MagicMock() with patch("subprocess.Popen", return_value=process_mock) as mock: # If everything work fine the command is still running and a timeout is raised process_mock.communicate.side_effect = subprocess.TimeoutExpired( "test", 1) Servers.instance().startLocalServer() mock.assert_called_with([ local_server_path, '--host=127.0.0.1', '--port=8000', '--local', '--debug', '--log=' + str(tmpdir / "gns3_server.log"), '--pid=' + str(tmpdir / "gns3_server.pid") ])
def validateCurrentPage(self): """ Validates the server. """ if self.currentPage() == self.uiServerWizardPage: if not self.uiCloudRadioButton.isChecked(): if Qemu.instance().settings()["use_local_server"] or self.uiLocalRadioButton.isChecked(): server = Servers.instance().localServer() elif self.uiRemoteRadioButton.isChecked(): if not Servers.instance().remoteServers(): QtGui.QMessageBox.critical(self, "Remote server", "There is no remote server registered in QEMU preferences") return False server = self.uiRemoteServersComboBox.itemData(self.uiRemoteServersComboBox.currentIndex()) self._server = server if self.currentPage() == self.uiNameWizardPage: name = self.uiNameLineEdit.text() for qemu_vm in self._qemu_vms.values(): if qemu_vm["name"] == name: QtGui.QMessageBox.critical(self, "Name", "{} is already used, please choose another name".format(name)) return False if self.currentPage() == self.uiBinaryMemoryWizardPage: if not self.uiQemuListComboBox.count(): QtGui.QMessageBox.critical(self, "QEMU binaries", "Sorry, no QEMU binary has been found. Please make sure QEMU is installed before continuing") return False return True
def __init__(self, devices, use_local_server, parent): super().__init__(parent) self.setupUi(self) self.setModal(True) self._devices = devices self._use_local_server = use_local_server self.setWizardStyle(QtWidgets.QWizard.ModernStyle) if sys.platform.startswith("darwin"): # we want to see the cancel button on OSX self.setOptions(QtWidgets.QWizard.NoDefaultButton) self.uiRemoteRadioButton.toggled.connect(self._remoteServerToggledSlot) if hasattr(self, "uiVMRadioButton"): self.uiVMRadioButton.toggled.connect(self._vmToggledSlot) self.uiLocalRadioButton.toggled.connect(self._localToggledSlot) if hasattr(self, "uiLoadBalanceCheckBox"): self.uiLoadBalanceCheckBox.toggled.connect( self._loadBalanceToggledSlot) # By default we use the local server self._server = Servers.instance().localServer() self.uiLocalRadioButton.setChecked(True) self._localToggledSlot(True) if Servers.instance().isNonLocalServerConfigured() is False: # skip the server page if we use the local server self.setStartId(1)
def gns3vm_server(): from gns3.servers import Servers Servers.instance()._settings["vm"]["auto_start"] = True Servers.instance().initVMServer() assert Servers.instance().vmServer() is not None return Servers.instance().vmServer()
def savePreferences(self): """ Saves the general preferences. """ servers = Servers.instance() local_server = Servers.instance().localServerSettings() local_server["images_path"] = self.uiImagesPathLineEdit.text() local_server["projects_path"] = self.uiProjectsPathLineEdit.text() local_server["report_errors"] = self.uiCrashReportCheckBox.isChecked() servers.setLocalServerSettings(local_server) new_settings = {} new_settings[ "auto_launch_project_dialog"] = self.uiLaunchNewProjectDialogCheckBox.isChecked( ) new_settings[ "auto_screenshot"] = self.uiAutoScreenshotCheckBox.isChecked() new_settings["style"] = self.uiStyleComboBox.currentText() new_settings[ "check_for_update"] = self.uiCheckForUpdateCheckBox.isChecked() new_settings[ "link_manual_mode"] = self.uiLinkManualModeCheckBox.isChecked() new_settings[ "slow_device_start_all"] = self.uiSlowStartAllSpinBox.value() new_settings[ "telnet_console_command"] = self.uiTelnetConsoleCommandLineEdit.text( ) new_settings[ "serial_console_command"] = self.uiSerialConsoleCommandLineEdit.text( ) new_settings[ "auto_close_console"] = self.uiCloseConsoleWindowsOnDeleteCheckBox.isChecked( ) new_settings[ "bring_console_to_front"] = self.uiBringConsoleWindowToFrontCheckBox.isChecked( ) new_settings[ "delay_console_all"] = self.uiDelayConsoleAllSpinBox.value() from ..main_window import MainWindow MainWindow.instance().setSettings(new_settings) new_settings = {} new_settings["scene_width"] = self.uiSceneWidthSpinBox.value() new_settings["scene_height"] = self.uiSceneHeightSpinBox.value() new_settings[ "draw_rectangle_selected_item"] = self.uiRectangleSelectedItemCheckBox.isChecked( ) new_settings[ "draw_link_status_points"] = self.uiDrawLinkStatusPointsCheckBox.isChecked( ) new_settings[ "default_label_font"] = self.uiDefaultLabelStylePlainTextEdit.font( ).toString() new_settings["default_label_color"] = self._default_label_color.name() MainWindow.instance().uiGraphicsView.setSettings(new_settings)
def test_killAlreadyRunningServer(tmpdir): with patch("gns3.local_config.LocalConfig.configDirectory") as mock_local_config: mock_local_config.return_value = str(tmpdir) with open(str(tmpdir / "gns3_server.pid"), "w+") as f: f.write("42") mock_process = MagicMock() with patch("psutil.Process", return_value=mock_process) as mock: Servers.instance()._killAlreadyRunningServer() mock.assert_called_with(pid=42) assert mock_process.kill.called
def validateCurrentPage(self): """ Validates the server. """ if self.currentPage() == self.uiServerWizardPage: #FIXME: prevent users to use "cloud" if self.uiCloudRadioButton.isChecked(): QtGui.QMessageBox.critical(self, "Cloud", "Sorry not implemented yet!") return False if Qemu.instance().settings()["use_local_server"] or self.uiLocalRadioButton.isChecked(): server = Servers.instance().localServer() else: server = self.uiRemoteServersComboBox.itemData(self.uiRemoteServersComboBox.currentIndex()) if not server.connected() and ConnectToServer(self, server) is False: return False self._server = server if self.currentPage() == self.uiNameTypeWizardPage: name = self.uiNameLineEdit.text() for qemu_vm in self._qemu_vms.values(): if qemu_vm["name"] == name: QtGui.QMessageBox.critical(self, "Name", "{} is already used, please choose another name".format(name)) return False if self.currentPage() == self.uiBinaryMemoryWizardPage: if not self.uiQemuListComboBox.count(): QtGui.QMessageBox.critical(self, "QEMU binaries", "Sorry, no QEMU binary has been found. Please make sure QEMU is installed before continuing") return False return True
def _populateGeneralSettingWidgets(self, settings): """ Populates the widgets with the settings. :param settings: General settings """ local_server = Servers.instance().localServerSettings() self.uiProjectsPathLineEdit.setText(local_server["projects_path"]) self.uiImagesPathLineEdit.setText(local_server["images_path"]) self.uiStatsCheckBox.setChecked(settings["send_stats"]) self.uiCrashReportCheckBox.setChecked(local_server["report_errors"]) self.uiLaunchNewProjectDialogCheckBox.setChecked(settings["auto_launch_project_dialog"]) self.uiAutoScreenshotCheckBox.setChecked(settings["auto_screenshot"]) self.uiCheckForUpdateCheckBox.setChecked(settings["check_for_update"]) self.uiLinkManualModeCheckBox.setChecked(settings["link_manual_mode"]) self.uiSlowStartAllSpinBox.setValue(settings["slow_device_start_all"]) self.uiTelnetConsoleCommandLineEdit.setText(settings["telnet_console_command"]) self.uiTelnetConsoleCommandLineEdit.setCursorPosition(0) index = self.uiStyleComboBox.findText(settings["style"]) if index != -1: self.uiStyleComboBox.setCurrentIndex(index) index = self.uiTelnetConsolePreconfiguredCommandComboBox.findData(settings["telnet_console_command"]) if index != -1: self.uiTelnetConsolePreconfiguredCommandComboBox.setCurrentIndex(index) self.uiSerialConsoleCommandLineEdit.setText(settings["serial_console_command"]) self.uiSerialConsoleCommandLineEdit.setCursorPosition(0) index = self.uiSerialConsolePreconfiguredCommandComboBox.findData(settings["serial_console_command"]) if index != -1: self.uiSerialConsolePreconfiguredCommandComboBox.setCurrentIndex(index) self.uiCloseConsoleWindowsOnDeleteCheckBox.setChecked(settings["auto_close_console"]) self.uiBringConsoleWindowToFrontCheckBox.setChecked(settings["bring_console_to_front"]) self.uiDelayConsoleAllSpinBox.setValue(settings["delay_console_all"])
def get_default_base_config(base_config_template_path): """ Copy the default base config template to settings directory (if not already present) and returns the path. :param base_config_template_path: path to the base config template :return: path to the base config """ servers = Servers.instance() config_dir = servers.localServerSettings()["configs_path"] if base_config_template_path: try: os.makedirs(config_dir, exist_ok=True) except OSError as e: log.error("could not create the base configs directory {}: {}".format(config_dir, e)) return "" try: base_config_path = os.path.join(config_dir, os.path.basename(base_config_template_path)) if not os.path.isfile(base_config_path): shutil.copyfile(base_config_template_path, base_config_path) return os.path.normpath(base_config_path) except OSError as e: log.error("could not copy {} to {}: {}".format(base_config_template_path, base_config_path, e)) return ""
def __init__(self): super().__init__() self.setupUi(self) self._widget_slots = {0: self.uiSlot0comboBox, 1: self.uiSlot1comboBox, 2: self.uiSlot2comboBox, 3: self.uiSlot3comboBox, 4: self.uiSlot4comboBox, 5: self.uiSlot5comboBox, 6: self.uiSlot6comboBox} self._widget_wics = {0: self.uiWic0comboBox, 1: self.uiWic1comboBox, 2: self.uiWic2comboBox} self.uiStartupConfigToolButton.clicked.connect(self._startupConfigBrowserSlot) self.uiPrivateConfigToolButton.clicked.connect(self._privateConfigBrowserSlot) self.uiSymbolToolButton.clicked.connect(self._symbolBrowserSlot) self.uiIOSImageToolButton.clicked.connect(self._iosImageBrowserSlot) self._server = None self._idle_valid = False idle_pc_rgx = QtCore.QRegExp("^(0x[0-9a-fA-F]{8})?$") validator = QtGui.QRegExpValidator(idle_pc_rgx, self) self.uiIdlepcLineEdit.setValidator(validator) self.uiIdlepcLineEdit.textChanged.connect(self._idlePCValidateSlot) self.uiIdlepcLineEdit.textChanged.emit(self.uiIdlepcLineEdit.text()) self._default_configs_dir = Servers.instance().localServerSettings()["configs_path"] # add the categories for name, category in Node.defaultCategories().items(): self.uiCategoryComboBox.addItem(name, category)
def nodes(self): """ Returns all the node data necessary to represent a node in the nodes view and create a node on the scene. """ server = "local" if not self._settings["use_local_server"]: # pick up a remote server (round-robin method) remote_server = next(iter(Servers.instance())) if remote_server: server = "{}:{}".format(remote_server.host, remote_server.port) nodes = [] for node_class in VPCS.classes(): nodes.append({ "class": node_class.__name__, "name": node_class.symbolName(), "server": server, "categories": node_class.categories(), "default_symbol": node_class.defaultSymbol(), "hover_symbol": node_class.hoverSymbol() }) if ENABLE_CLOUD: nodes.append({ "class": node_class.__name__, "name": node_class.symbolName() + " (cloud)", "server": "cloud", "categories": node_class.categories(), "default_symbol": node_class.defaultSymbol(), "hover_symbol": node_class.hoverSymbol() }) return nodes
def _iosImageSaveSlot(self): """ Adds/Saves an IOS image. """ path = self.uiIOSPathLineEdit.text() startup_config = self.uiStartupConfigLineEdit.text() private_config = self.uiPrivateConfigLineEdit.text() platform = self.uiPlatformComboBox.currentText() chassis = self.uiChassisComboBox.currentText() idlepc = self.uiIdlePCLineEdit.text() ram = self.uiRAMSpinBox.value() # basename doesn't work on Unix with Windows paths if not sys.platform.startswith('win') and len(path) > 2 and path[1] == ":": import ntpath image = ntpath.basename(path) else: image = os.path.basename(path) if image.startswith("c7200p"): QtGui.QMessageBox.warning(self, "IOS Image", "This IOS image is for the c7200 platform with NPE-G2 and using it is not recommended.\nPlease use an IOS image that do not start with c7200p.") #TODO: mutiple remote server if Dynamips.instance().settings()["use_local_server"]: server = "local" else: server = server = next(iter(Servers.instance())).host #ios_images = Dynamips.instance().iosImages() key = "{server}:{image}".format(server=server, image=image) item = self.uiIOSImagesTreeWidget.currentItem() if key in self._ios_images and item and item.text(0) == image: item.setText(0, image) item.setText(1, platform) item.setText(2, server) elif key in self._ios_images: print("Image already added") return else: # add a new entry in the tree widget item = QtGui.QTreeWidgetItem(self.uiIOSImagesTreeWidget) item.setText(0, image) item.setText(1, platform) item.setText(2, server) self.uiIOSImagesTreeWidget.setCurrentItem(item) self._ios_images[key] = {"path": path, "image": image, "startup_config": startup_config, "private_config": private_config, "platform": platform, "chassis": chassis, "idlepc": idlepc, "ram": ram, "server": server} self.uiIOSImagesTreeWidget.resizeColumnToContents(0) self.uiIOSImagesTreeWidget.resizeColumnToContents(1)
def allocateServer(self, node_class, use_cloud=False): """ Allocates a server. :param node_class: Node object :returns: allocated server (HTTPClient instance) """ # allocate a server for the node servers = Servers.instance() if use_cloud: from ...topology import Topology topology = Topology.instance() top_instance = topology.anyInstance() server = servers.getCloudServer(top_instance.host, top_instance.port, top_instance.ssl_ca_file) else: if self._settings["use_local_server"]: # use the local server server = servers.localServer() else: # pick up a remote server (round-robin method) server = next(iter(servers)) if not server: raise ModuleError("No remote server is configured") return server
def createNode(self, node_class, server=None): """ Creates a new node. :param node_class: Node object :param server: optional WebSocketClient instance """ log.info("creating node {}".format(node_class)) # allocate a server for the node if none is given servers = Servers.instance() if self._settings["use_local_server"] and not server: # use the local server server = servers.localServer() elif not server: # pick up a remote server (round-robin method) server = next(iter(servers)) if not server: raise ModuleError("No remote server is configured") if not server.connected(): try: log.info("reconnecting to server {}:{}".format(server.host, server.port)) server.reconnect() except OSError as e: raise ModuleError("Could not connect to server {}:{}: {}".format(server.host, server.port, e)) if server not in self._servers: self.addServer(server) # create an instance of the node class return node_class(self, server)
def nodes(self): """ Returns all the node data necessary to represent a node in the nodes view and create a node on the scene. """ if self._settings["use_local_server"]: server = "local" elif GNS3VM.instance().isRunning(): server = "vm" else: remote_server = next(iter(Servers.instance())) if remote_server: server = remote_server.url() else: # If user has no server configured and has uncheck the checkbox # it's a mistake. We use the GNS3VM in order to show a correct # error message server = "vm" nodes = [] for node_class in VPCS.classes(): nodes.append( { "class": node_class.__name__, "name": node_class.symbolName(), "server": server, "categories": [self._settings["category"]], "symbol": self._settings["symbol"], } ) return nodes
def _configFileValid(self, path): """ Return true if it's a valid configuration file """ if not os.path.isabs(path): path = os.path.join(Servers.instance().localServerSettings()["configs_path"], path) return os.access(path, os.R_OK)
def initializePage(self, page_id): if self.page(page_id) == self.uiServerWizardPage: self.uiRemoteServersComboBox.clear() for server in Servers.instance().remoteServers().values(): self.uiRemoteServersComboBox.addItem( "{}:{}".format(server.host, server.port), server) if self.page(page_id) == self.uiBinaryMemoryWizardPage: if self.uiCloudRadioButton.isChecked(): for binary in QEMU_BINARIES_FOR_CLOUD: self.uiQemuListComboBox.addItem( "{path}".format(path=binary), binary) # Default to x86_64 for the user index = self.uiQemuListComboBox.findData( "x86_64", flags=QtCore.Qt.MatchEndsWith) if index != -1: self.uiQemuListComboBox.setCurrentIndex(index) else: try: Qemu.instance().getQemuBinariesFromServer( self._server, self._getQemuBinariesFromServerCallback) except ModuleError as e: QtGui.QMessageBox.critical( self, "Qemu binaries", "Error while getting the QEMU binaries: {}".format(e))
def test_getRemoteServer(): servers = Servers.instance() http_server = servers.getRemoteServer("http", "localhost", 3080, None) assert http_server.protocol() == "http" assert http_server.host() == "localhost" assert http_server.port() == 3080 assert http_server.user() is None
def nodes(self): """ Returns all the node data necessary to represent a node in the nodes view and create a node on the scene. """ server = "local" if not self._settings["use_local_server"]: # pick up a remote server (round-robin method) remote_server = next(iter(Servers.instance())) if remote_server: server = "{}:{}".format(remote_server.host, remote_server.port) nodes = [] for node_class in VPCS.classes(): nodes.append( {"class": node_class.__name__, "name": node_class.symbolName(), "server": server, "categories": node_class.categories(), "default_symbol": node_class.defaultSymbol(), "hover_symbol": node_class.hoverSymbol()} ) if ENABLE_CLOUD: nodes.append( {"class": node_class.__name__, "name": node_class.symbolName() + " (cloud)", "server": "cloud", "categories": node_class.categories(), "default_symbol": node_class.defaultSymbol(), "hover_symbol": node_class.hoverSymbol()} ) return nodes
def _getVMsFromServerCallback(self, result, error=False, **kwargs): """ Callback for getVMsFromServer. :param progress_dialog: QProgressDialog instance :param result: server response :param error: indicates an error (boolean) """ if error: QtWidgets.QMessageBox.critical(self, "VM List", "{}".format(result["message"])) else: self.uiVMListComboBox.clear() for vm in result: self.uiVMListComboBox.addItem(vm["vmname"], vm.get("vmx_path", "")) gns3_vm = Servers.instance().vmSettings() index = self.uiVMListComboBox.findText(gns3_vm["vmname"]) if index != -1: self.uiVMListComboBox.setCurrentIndex(index) else: index = self.uiVMListComboBox.findText("GNS3 VM") if index != -1: self.uiVMListComboBox.setCurrentIndex(index) else: QtWidgets.QMessageBox.critical(self, "GNS3 VM", "Could not find a VM named 'GNS3 VM', is it imported in VMware or VirtualBox?")
def __init__(self, parent): super().__init__(parent) self.setupUi(self) self.setWizardStyle(QtWidgets.QWizard.ModernStyle) if sys.platform.startswith("darwin"): # we want to see the cancel button on OSX self.setOptions(QtWidgets.QWizard.NoDefaultButton) self._server = Servers.instance().localServer() self.uiGNS3VMDownloadLinkUrlLabel.setText('') self.uiRefreshPushButton.clicked.connect(self._refreshVMListSlot) self.uiVmwareRadioButton.clicked.connect(self._listVMwareVMsSlot) self.uiVirtualBoxRadioButton.clicked.connect(self._listVirtualBoxVMsSlot) self.uiVMwareBannerButton.clicked.connect(self._VMwareBannerButtonClickedSlot) settings = parent.settings() self.uiShowCheckBox.setChecked(settings["hide_setup_wizard"]) # by default all radio buttons are unchecked self.uiVmwareRadioButton.setAutoExclusive(False) self.uiVirtualBoxRadioButton.setAutoExclusive(False) self.uiVmwareRadioButton.setChecked(False) self.uiVirtualBoxRadioButton.setChecked(False) if sys.platform.startswith("darwin"): self.uiVMwareBannerButton.setIcon(QtGui.QIcon(":/images/vmware_fusion_banner.jpg")) else: self.uiVMwareBannerButton.setIcon(QtGui.QIcon(":/images/vmware_workstation_banner.jpg"))
def _readBaseConfig(self, config_path): """ Returns a base config content. :param config_path: path to the configuration file. :returns: config content """ if config_path is None or len(config_path.strip()) == 0: return None if not os.path.isabs(config_path): config_path = os.path.join(Servers.instance().localServerSettings()["configs_path"], config_path) if not os.path.isfile(config_path): return None try: with open(config_path, "rb") as f: log.info("Opening configuration file: {}".format(config_path)) config = f.read().decode("utf-8") config = config.replace('\r', "") return config except OSError as e: self.error_signal.emit(self.id(), "Could not read configuration file {}: {}".format(config_path, e)) return None except UnicodeDecodeError as e: self.error_signal.emit(self.id(), "Invalid configuration file {}: {}".format(config_path, e)) return None return ""
def nodes(self): """ Returns all the node data necessary to represent a node in the nodes view and create a node on the scene. """ if self._settings["use_local_server"]: server = "local" elif GNS3VM.instance().isRunning(): server = "vm" else: remote_server = next(iter(Servers.instance())) if remote_server: server = remote_server.url() else: # If user has no server configured and has uncheck the checkbox # it's a mistake. We use the GNS3VM in order to show a correct # error message server = "vm" nodes = [] for node_class in VPCS.classes(): nodes.append({ "class": node_class.__name__, "name": node_class.symbolName(), "server": server, "categories": [self._settings["category"]], "symbol": self._settings["symbol"] }) return nodes
def _populateGeneralSettingWidgets(self, settings): """ Populates the widgets with the settings. :param settings: General settings """ local_server = Servers.instance().localServerSettings() self.uiProjectsPathLineEdit.setText(local_server["projects_path"]) self.uiSymbolsPathLineEdit.setText(local_server["symbols_path"]) self.uiImagesPathLineEdit.setText(local_server["images_path"]) self.uiConfigsPathLineEdit.setText(local_server["configs_path"]) self.uiStatsCheckBox.setChecked(settings["send_stats"]) self.uiCrashReportCheckBox.setChecked(local_server["report_errors"]) self.uiLaunchNewProjectDialogCheckBox.setChecked(settings["auto_launch_project_dialog"]) self.uiAutoScreenshotCheckBox.setChecked(settings["auto_screenshot"]) self.uiCheckForUpdateCheckBox.setChecked(settings["check_for_update"]) self.uiLinkManualModeCheckBox.setChecked(settings["link_manual_mode"]) self.uiExperimentalFeaturesCheckBox.setChecked(settings["experimental_features"]) self.uiSlowStartAllSpinBox.setValue(settings["slow_device_start_all"]) self.uiTelnetConsoleCommandLineEdit.setText(settings["telnet_console_command"]) self.uiTelnetConsoleCommandLineEdit.setCursorPosition(0) index = self.uiStyleComboBox.findText(settings["style"]) if index != -1: self.uiStyleComboBox.setCurrentIndex(index) self.uiSerialConsoleCommandLineEdit.setText(settings["serial_console_command"]) self.uiSerialConsoleCommandLineEdit.setCursorPosition(0) self.uiCloseConsoleWindowsOnDeleteCheckBox.setChecked(settings["auto_close_console"]) self.uiBringConsoleWindowToFrontCheckBox.setChecked(settings["bring_console_to_front"]) self.uiDelayConsoleAllSpinBox.setValue(settings["delay_console_all"]) self.uiVNCConsoleCommandLineEdit.setText(settings["vnc_console_command"]) self.uiVNCConsoleCommandLineEdit.setCursorPosition(0)
def initializePage(self, page_id): if self.page(page_id) == self.uiServerWizardPage: self.uiRemoteServersComboBox.clear() for server in Servers.instance().remoteServers().values(): self.uiRemoteServersComboBox.addItem("{}:{}".format(server.host, server.port), server) elif self.page(page_id) == self.uiNamePlatformWizardPage: self.uiNameLineEdit.setText(self.uiPlatformComboBox.currentText()) ios_image = self.uiIOSImageLineEdit.text() self.setWindowTitle("New IOS router - {}".format(os.path.basename(ios_image))) elif self.page(page_id) == self.uiMemoryWizardPage: # set the correct amount of RAM based on the platform from ..pages.ios_router_preferences_page import IOSRouterPreferencesPage platform = self.uiPlatformComboBox.currentText() path = self.uiIOSImageLineEdit.text() if os.path.isfile(path): minimum_required_ram = IOSRouterPreferencesPage.getMinimumRequiredRAM(path) if minimum_required_ram > PLATFORMS_DEFAULT_RAM[platform]: self.uiRamSpinBox.setValue(minimum_required_ram) else: self.uiRamSpinBox.setValue(PLATFORMS_DEFAULT_RAM[platform]) else: self.uiRamSpinBox.setValue(PLATFORMS_DEFAULT_RAM[platform]) elif self.page(page_id) == self.uiNetworkAdaptersWizardPage: platform = self.uiPlatformComboBox.currentText() chassis = self.uiChassisComboBox.currentText() if not chassis: chassis = "" self._populateAdapters(platform, chassis) if platform == "c7200": self.uiSlot0comboBox.setCurrentIndex(self.uiSlot0comboBox.findText("C7200-IO-FE"))
def validateCurrentPage(self): """ Validates the IOS name and checks validation state for Idle-PC value """ if self.currentPage() == self.uiNamePlatformWizardPage: name = self.uiNameLineEdit.text() for ios_router in self._ios_routers.values(): if ios_router["name"] == name: QtGui.QMessageBox.critical(self, "Name", "{} is already used, please choose another name".format(name)) return False if self.currentPage() == self.uiMemoryWizardPage and self.uiPlatformComboBox.currentText() == "c7200": if self.uiRamSpinBox.value() > 512: QtGui.QMessageBox.critical(self, "c7200 RAM requirement", "c7200 routers with NPE-400 are limited to 512MB of RAM") return False if self.currentPage() == self.uiIdlePCWizardPage: if not self._idle_valid: idle_pc = self.uiIdlepcLineEdit.text() QtGui.QMessageBox.critical(self, "Idle-PC", "{} is not a valid Idle-PC value ".format(idle_pc)) return False if self.currentPage() == self.uiServerWizardPage and self.uiRemoteRadioButton.isChecked(): if not Servers.instance().remoteServers(): QtGui.QMessageBox.critical(self, "Remote server", "There is no remote server registered in Dynamips preferences") return False return True
def __init__(self): super().__init__() self.setupUi(self) self.uiSymbolToolButton.clicked.connect(self._symbolBrowserSlot) self.uiStartupConfigToolButton.clicked.connect( self._startupConfigBrowserSlot) self.uiPrivateConfigToolButton.clicked.connect( self._privateConfigBrowserSlot) self.uiIOUImageToolButton.clicked.connect(self._iouImageBrowserSlot) self.uiDefaultValuesCheckBox.stateChanged.connect( self._useDefaultValuesSlot) self._current_iou_image = "" self._server = None # location of the base config templates self._base_iou_l2_config_template = get_resource( os.path.join("configs", "iou_l2_base_startup-config.txt")) self._base_iou_l3_config_template = get_resource( os.path.join("configs", "iou_l3_base_startup-config.txt")) self._default_configs_dir = Servers.instance().localServerSettings( )["configs_path"] # add the categories for name, category in Node.defaultCategories().items(): self.uiCategoryComboBox.addItem(name, category)
def __init__(self, qemu_vms, parent): QtGui.QWizard.__init__(self, parent) self.setupUi(self) self.setPixmap(QtGui.QWizard.LogoPixmap, QtGui.QPixmap(":/icons/qemu.svg")) self.setWizardStyle(QtGui.QWizard.ModernStyle) self.uiRemoteRadioButton.toggled.connect(self._remoteServerToggledSlot) self.uiHdaDiskImageToolButton.clicked.connect(self._hdaDiskImageBrowserSlot) self.uiHdbDiskImageToolButton.clicked.connect(self._hdbDiskImageBrowserSlot) self.uiInitrdToolButton.clicked.connect(self._initrdBrowserSlot) self.uiKernelImageToolButton.clicked.connect(self._kernelImageBrowserSlot) self.uiTypeComboBox.currentIndexChanged[str].connect(self._typeChangedSlot) # Available types self.uiTypeComboBox.addItems(["Default", "ASA 8.4(2)", "IDS"]) # Mandatory fields self.uiNameTypeWizardPage.registerField("vm_name*", self.uiNameLineEdit) self.uiDiskWizardPage.registerField("hda_disk_image*", self.uiHdaDiskImageLineEdit) self.uiDiskImageHdbWizardPage.registerField("hdb_disk_image*", self.uiHdbDiskImageLineEdit) self.uiASAWizardPage.registerField("initrd*", self.uiInitrdLineEdit) self.uiASAWizardPage.registerField("kernel_image*", self.uiKernelImageLineEdit) self._qemu_vms = qemu_vms if Qemu.instance().settings()["use_local_server"]: # skip the server page if we use the local server self.setStartId(1) # By default we use the local server self._server = Servers.instance().localServer()
def _testSettingsSlot(self): QtGui.QMessageBox.critical(self, "Test settings", "Sorry, not yet implemented!") return servers = Servers.instance() if self.uiUseLocalServercheckBox.isChecked(): server = servers.localServer() else: QtGui.QMessageBox.critical(self, "Test settings", "Sorry, not yet implemented!") try: if not server.connected(): server.reconnect() except OSError as e: QtGui.QMessageBox.critical(self, "Local server", "Could not connect to the local server {host} on port {port}: {error}".format(host=server.host, port=server.port, error=e)) self._progress_dialog = QtGui.QProgressDialog("Testing settings...", "Cancel", 0, 0, parent=self) self._progress_dialog.setWindowModality(QtCore.Qt.WindowModal) self._progress_dialog.setWindowTitle("Settings") self._progress_dialog.show() iou_module = IOU.instance() if server not in iou_module.servers(): server_added = True iou_module.addServer(server) self.savePreferences() if server_added: iou_module.removeServer(server) server.send_message("iou.test_settings", None, self._testSettingsCallback)
def checkUbridgePermission(self): """Check if ubridge has the correct permission""" if not sys.platform.startswith("win") and os.geteuid() == 0: # we are root, so we should have privileged access. return (0, None) path = Servers.instance().localServerSettings().get("ubridge_path") if path is None: return (0, None) if not os.path.exists(path): return (2, "Ubridge path {path} doesn't exists".format(path=path)) request_setuid = False if sys.platform.startswith("linux"): if "security.capability" in os.listxattr(path): caps = os.getxattr(path, "security.capability") # test the 2nd byte and check if the 13th bit (CAP_NET_RAW) is set if not struct.unpack("<IIIII", caps)[1] & 1 << 13: return(2, "Ubridge require CAP_NET_RAW. Run sudo setcap cap_net_admin,cap_net_raw=ep {path}".format(path=path)) else: # capabilities not supported request_setuid = True if sys.platform.startswith("darwin") or request_setuid: if os.stat(path).st_uid != 0 or not os.stat(path).st_mode & stat.S_ISUID: return (2, "Ubridge should be setuid. Run sudo chown root {path} and sudo chmod 4755 {path}".format(path=path)) return (0, None)
def test_getRemoteServer(): servers = Servers.instance() http_server = servers.getRemoteServer("http", "localhost", 8000, None) assert http_server.protocol() == "http" assert http_server.host() == "localhost" assert http_server.port() == 8000 assert http_server.user() is None
def test_loadSettingsWith13LocalServerSetting(tmpdir, local_config): with open(str(tmpdir / "test.cfg"), "w+") as f: json.dump({ "Servers": { "local_server": { "auth": True, "user": "******", "password": "******" } }, "LocalServer": { "auth": False }, "version": "1.4" }, f) local_config.setConfigFilePath(str(tmpdir / "test.cfg")) Servers._instance = None servers = Servers.instance() local_server = local_config.loadSectionSettings("LocalServer", {}) assert local_server["auth"] == True assert local_server["user"] == "world" assert local_server["password"] == "hello"
def test_loadSettingsWith13LocalServerSetting(tmpdir, local_config): with open(str(tmpdir / "test.cfg"), "w+") as f: json.dump( { "Servers": { "local_server": { "auth": True, "user": "******", "password": "******" } }, "LocalServer": { "auth": False }, "version": "1.4" }, f) local_config.setConfigFilePath(str(tmpdir / "test.cfg")) Servers._instance = None servers = Servers.instance() local_server = local_config.loadSectionSettings("LocalServer", {}) assert local_server["auth"] == True assert local_server["user"] == "world" assert local_server["password"] == "hello"
def getSettings(self): """ Returns the settings set in this Wizard. :return: settings dict """ path = self.uiIOUImageLineEdit.text() initial_config = "" if self.uiTypeComboBox.currentText() == "L2 image": # set the default L2 base initial-config default_base_config = get_default_base_config( self._base_iou_l2_config_template) if default_base_config: initial_config = default_base_config default_symbol = ":/symbols/multilayer_switch.normal.svg" hover_symbol = ":/symbols/multilayer_switch.selected.svg" category = Node.switches ethernet_adapters = 4 serial_adapters = 0 else: # set the default L3 base initial-config default_base_config = get_default_base_config( self._base_iou_l3_config_template) if default_base_config: initial_config = default_base_config default_symbol = ":/symbols/router.normal.svg" hover_symbol = ":/symbols/router.selected.svg" category = Node.routers ethernet_adapters = 2 serial_adapters = 2 if IOU.instance().settings( )["use_local_server"] or self.uiLocalRadioButton.isChecked(): server = "local" elif self.uiRemoteRadioButton.isChecked(): if self.uiLoadBalanceCheckBox.isChecked(): server = next(iter(Servers.instance())) server = "{}:{}".format(server.host, server.port) else: server = self.uiRemoteServersComboBox.currentText() else: # Cloud is selected server = "cloud" settings = { "name": self.uiNameLineEdit.text(), "path": path, "image": os.path.basename(path), "initial_config": initial_config, "ethernet_adapters": ethernet_adapters, "serial_adapters": serial_adapters, "default_symbol": default_symbol, "category": category, "hover_symbol": hover_symbol, "server": server, } return settings
def test_handle_handleSslErrors(): """ Simulate when user accept an insecure certificate. This should be save to the configuration """ servers = Servers.instance() servers._addRemoteServer("https", "127.0.0.1", "443", user="******", password="******") servers._saveSettings() assert servers._settings["remote_servers"] == [{ 'accept_insecure_certificate': None, 'host': '127.0.0.1', 'password': '******', 'port': 443, 'protocol': 'https', 'url': 'https://[email protected]:443', 'user': '******' }] reply = MagicMock() reply.url.return_value.toDisplayString.return_value = "https://[email protected]:443/v1/version" ssl_error = MagicMock() ssl_error.certificate.return_value.digest.return_value = binascii.unhexlify( "cca0a932ced2fb1b1a18c823542cb065") errorList = [ssl_error] with patch("gns3.qt.QtWidgets.QMessageBox.warning") as message_box_mock: message_box_mock.return_value = QtWidgets.QMessageBox.Yes servers._handleSslErrors(reply, errorList) servers._saveSettings() assert len(servers._settings["remote_servers"]) == 1 assert servers._settings["remote_servers"] == [{ 'accept_insecure_certificate': 'cca0a932ced2fb1b1a18c823542cb065', 'host': '127.0.0.1', 'password': '******', 'port': 443, 'protocol': 'https', 'url': 'https://[email protected]:443', 'user': '******' }]
def test_getServerFromString_with_user(): servers = Servers.instance() server = servers.getServerFromString("http://[email protected]:4000") assert server.protocol() == "http" assert server.host() == "127.0.0.1" assert server.port() == 4000 assert server.user() == "root"
def test_getServerFromString(): servers = Servers.instance() server = servers.getServerFromString("127.0.0.1:4000") assert server.protocol() == "http" assert server.host() == "127.0.0.1" assert server.port() == 4000 assert server.user() is None