def test_instances_dumped(self): test_settings = {'project_type': 'cloud'} MainWindow.instance() ._project_settings.update(test_settings) self.t.addInstance(name="My instance", id="xyz", size_id="123", image_id="1234567890") topology = self.t.dump() self.assertIn('instances', topology["topology"]) instances = topology["topology"]["instances"] self.assertEqual(len(instances), 1) self.assertEqual(instances.pop()["name"], "My instance")
def test_reset(self): self.t._links = ['foo', 'baz', 'bar'] self.t._nodes = ['foo', 'baz', 'bar'] self.t._initialized_nodes = ['foo', 'baz', 'bar'] test_settings = {'project_type': 'cloud'} MainWindow.instance()._project_settings.update(test_settings) self.t.reset() self.assertEqual(len(self.t._links), 0) self.assertEqual(len(self.t._nodes), 0) self.assertEqual(len(self.t._initialized_nodes), 0) self.assertEqual(self.t._resources_type, 'local')
def test_load(self): with mock.patch('gns3.cloud_inspector_view.RackspaceCtrl') as provider_class: instances = list(gen_fake_nodes(2)) mw = mock.MagicMock() provider = mock.MagicMock() provider_class.return_value = provider provider.list_instances.return_value = instances mw.cloudProvider = provider settings = mock.MagicMock() settings_copy = MainWindow.instance().cloudSettings().copy() settings_copy['cloud_provider'] = 'rackspace' settings.__getitem__.side_effect = make_getitem(settings_copy) settings.__setitem__.side_effect = make_setitem(settings_copy) mw.cloudSettings.return_value = settings instances_dicts = [ { "id": instances[0].id, "image_id": "xyz", "name": "foo", "size_id": "2" }, { "id": instances[1].id, "image_id": "xyz", "name": "bar", "size_id": "2" } ] self.view.load(mw, instances_dicts) self.app.processEvents() # let the thread loading instances post its events self.assertEqual(self.view._model.rowCount(), 2)
def _allocateIOSImage(self, node): """ Allocates an IOS image to a node :param node: Node instance """ platform = node.settings()["platform"] selected_images = [] for ios_image, info in self._ios_images.items(): if info["platform"] == platform and (info["server"] == node.server().host or (node.server().isLocal() and info["server"] == "local")): selected_images.append(ios_image) if not selected_images: return None elif len(selected_images) > 1: from gns3.main_window import MainWindow mainwindow = MainWindow.instance() (selection, ok) = QtGui.QInputDialog.getItem(mainwindow, "IOS image", "Please choose an image", selected_images, 0, False) if ok: return self._ios_images[selection] else: raise ModuleError("Please select an IOS image") else: return self._ios_images[selected_images[0]]
def _allocateIOSImage(self, node): """ Allocates an IOS image to a node :param node: Node instance """ platform = node.settings()["platform"] selected_images = [] for ios_image, info in self._ios_images.items(): if info["platform"] == platform and ( info["server"] == node.server().host or (node.server().isLocal() and info["server"] == "local")): selected_images.append(ios_image) if not selected_images: return None elif len(selected_images) > 1: from gns3.main_window import MainWindow mainwindow = MainWindow.instance() (selection, ok) = QtGui.QInputDialog.getItem(mainwindow, "IOS image", "Please choose an image", selected_images, 0, False) if ok: return self._ios_images[selection] else: raise ModuleError("Please select an IOS image") else: return self._ios_images[selected_images[0]]
def findAlternativeInterface(node, missing_interface): from gns3.main_window import MainWindow mainwindow = MainWindow.instance() available_interfaces = [] for interface in node.settings()["interfaces"]: available_interfaces.append(interface["name"]) if available_interfaces: selection, ok = QtWidgets.QInputDialog.getItem( mainwindow, "Cloud interfaces", "Interface {} could not be found\nPlease select an alternative from your existing interfaces:" .format(missing_interface), available_interfaces, 0, False) if ok: return selection QtWidgets.QMessageBox.warning( mainwindow, "Cloud interface", "No alternative interface chosen to replace {} on this host, this may lead to issues" .format(missing_interface)) return None else: QtWidgets.QMessageBox.critical( mainwindow, "Cloud interface", "Could not find interface {} on this host".format( missing_interface)) return missing_interface
def test_clear_settings_on_user_request(self, *args, **kwargs): # no mocking for this testcase page = CloudPreferencesPage() # first run, user stores settings on disk page.uiRememberAPIKeyRadioButton.setChecked(True) page.uiAPIKeyLineEdit.setText("myapikey") page.uiUserNameLineEdit.setText("myusername") page.uiTermsCheckBox.setChecked(True) page.savePreferences() settings = MainWindow.instance().cloudSettings() self.assertTrue(settings.get('cloud_store_api_key')) self.assertEqual(settings.get('cloud_api_key'), 'myapikey') self.assertEqual(settings.get('cloud_user_name'), 'myusername') # now users change their mind page.uiForgetAPIKeyRadioButton.setChecked(True) page.savePreferences() # mainwindow settings should be still valid at this point... self.assertTrue(settings.get('cloud_store_api_key')) self.assertEqual(settings.get('cloud_api_key'), 'myapikey') self.assertEqual(settings.get('cloud_user_name'), 'myusername') # ...and values on disk should be gone stored_settings = QtCore.QSettings() stored_settings.beginGroup(CLOUD_SETTINGS_GROUP) self.assertFalse(stored_settings.value('cloud_store_api_key', type=bool)) self.assertEqual(stored_settings.value('cloud_api_key', type=str), '') self.assertEqual(stored_settings.value('cloud_user_name', type=str), '')
def test_clear_settings_on_user_request(self): # no mocking for this testcase page = CloudPreferencesPage() # first run, user stores settings on disk page.uiRememberAPIKeyRadioButton.setChecked(True) page.uiAPIKeyLineEdit.setText("myapikey") page.uiUserNameLineEdit.setText("myusername") page.uiTermsCheckBox.setChecked(True) page.savePreferences() settings = MainWindow.instance().cloud_settings() self.assertTrue(settings.get('cloud_store_api_key')) self.assertEqual(settings.get('cloud_api_key'), 'myapikey') self.assertEqual(settings.get('cloud_user_name'), 'myusername') # now users change their mind page.uiForgetAPIKeyRadioButton.setChecked(True) page.savePreferences() # mainwindow settings should be still valid at this point... self.assertTrue(settings.get('cloud_store_api_key')) self.assertEqual(settings.get('cloud_api_key'), 'myapikey') self.assertEqual(settings.get('cloud_user_name'), 'myusername') # ...and values on disk should be gone stored_settings = QtCore.QSettings() stored_settings.beginGroup(CLOUD_SETTINGS_GROUP) self.assertFalse(stored_settings.value('cloud_store_api_key', type=bool)) self.assertEqual(stored_settings.value('cloud_api_key', type=str), '') self.assertEqual(stored_settings.value('cloud_user_name', type=str), '')
def _uploadImages(self, qemu_vm): """ Upload hard drive images to Cloud Files. """ # Start uploading the image to cloud files self._upload_image_progress_dialog = QtGui.QProgressDialog( "Uploading image file(s)", "Cancel", 0, 0, parent=self) self._upload_image_progress_dialog.setWindowModality(QtCore.Qt.WindowModal) self._upload_image_progress_dialog.setWindowTitle("Qemu image upload") self._upload_image_progress_dialog.show() try: uploads = [] src = qemu_vm.get("hda_disk_image", None) if src: _, filename = ntpath.split(src) dst = "images/qemu/{}".format(filename) uploads.append((src, dst)) src = qemu_vm.get("hdb_disk_image", None) if src: _, filename = ntpath.split(src) dst = "images/qemu/{}".format(filename) uploads.append((src, dst)) upload_thread = UploadFilesThread(self, MainWindow.instance().cloudSettings(), uploads) upload_thread.completed.connect(self._imageUploadComplete) upload_thread.start() except Exception as e: self._upload_image_progress_dialog.reject() import logging log = logging.getLogger(__name__) log.error(e) QtGui.QMessageBox.critical(self, "Qemu image upload", "Error uploading Qemu image: {}".format(e))
def main(): """ Entry point for GNS3 GUI. """ current_year = datetime.date.today().year print("GNS3 GUI version {}".format(__version__)) print("Copyright (c) 2007-{} GNS3 Technologies Inc.".format(current_year)) # we only support Python 2 version >= 2.7 and Python 3 version >= 3.3 if sys.version_info < (2, 7): raise RuntimeError("Python 2.7 or higher is required") elif sys.version_info[0] == 3 and sys.version_info < (3, 3): raise RuntimeError("Python 3.3 or higher is required") try: from gns3.qt import QtCore, DEFAULT_BINDING except ImportError: raise RuntimeError("Can't import Qt modules, Python binding is probably not installed...") version = lambda version_string: [int(i) for i in version_string.split('.')] if version(QtCore.QT_VERSION_STR) < version("4.6"): raise RuntimeError("Requirement is Qt version 4.6 or higher, got version {}".format(QtCore.QT_VERSION_STR)) # 4.8.3 because of QSettings (http://pyqt.sourceforge.net/Docs/PyQt4/pyqt_qsettings.html) if DEFAULT_BINDING == "PyQt" and version(QtCore.BINDING_VERSION_STR) < version("4.8.3"): raise RuntimeError("Requirement is PyQt version 4.8.3 or higher, got version {}".format(QtCore.BINDING_VERSION_STR)) if DEFAULT_BINDING == "PySide" and version(QtCore.BINDING_VERSION_STR) < version("1.0"): raise RuntimeError("Requirement is PySide version 1.0 or higher, got version {}".format(QtCore.BINDING_VERSION_STR)) # default logging level logging.basicConfig(level=logging.INFO) # don't use the registry to store settings on Windows # because we don't like it! if sys.platform.startswith('win'): QtCore.QSettings.setDefaultFormat(QtCore.QSettings.IniFormat) exit_code = MainWindow.exit_code_reboot while exit_code == MainWindow.exit_code_reboot: exit_code = 0 app = QtGui.QApplication(sys.argv) # this info is necessary for QSettings app.setOrganizationName("GNS3") app.setOrganizationDomain("gns3.net") app.setApplicationName("GNS3") app.setApplicationVersion(__version__) mainwindow = MainWindow.instance() mainwindow.show() exit_code = app.exec_() delattr(MainWindow, "_instance") app.deleteLater() sys.exit(exit_code)
def parent(self): """ Parent window """ if self._parent is None: from gns3.main_window import MainWindow return MainWindow.instance() return self._parent
def reject(self): """ Closes this dialog. """ from gns3.main_window import MainWindow HTTPClient.setProgressCallback(Progress(MainWindow.instance())) QtGui.QDialog.reject(self)
def setupNode(self, node, node_name): """ Setups a node. :param node: Node instance :param node_name: Node name """ log.info("configuring node {}".format(node)) iouimage = None if node_name: for iou_key, info in self._iou_devices.items(): if node_name == info["name"]: iouimage = iou_key if not iouimage: selected_images = [] for image, info in self._iou_devices.items(): if info["server"] == node.server().host or ( node.server().isLocal() and info["server"] == "local"): selected_images.append(image) if not selected_images: raise ModuleError("No IOU image found for this device") elif len(selected_images) > 1: from gns3.main_window import MainWindow mainwindow = MainWindow.instance() (selection, ok) = QtGui.QInputDialog.getItem(mainwindow, "IOU image", "Please choose an image", selected_images, 0, False) if ok: iouimage = selection else: raise ModuleError("Please select an IOU image") else: iouimage = selected_images[0] vm_settings = {} for setting_name, value in self._iou_devices[iouimage].items(): if setting_name in node.settings( ) and setting_name != "name" and value != "" and value is not None: vm_settings[setting_name] = value if vm_settings["use_default_iou_values"]: del vm_settings["ram"] del vm_settings["nvram"] if "console" in vm_settings: # Older GNS3 versions may have a console setting in the VM template del vm_settings["console"] iou_path = vm_settings.pop("path") node.setup(iou_path, additional_settings=vm_settings)
def setupNode(self, node, node_name): """ Setups a node. :param node: Node instance :param node_name: Node name """ log.info("configuring node {}".format(node)) iouimage = None if node_name: for iou_key, info in self._iou_devices.items(): if node_name == info["name"]: iouimage = iou_key if not iouimage: selected_images = [] for image, info in self._iou_devices.items(): if info["server"] == node.server().host or (node.server().isLocal() and info["server"] == "local"): selected_images.append(image) if not selected_images: raise ModuleError("No IOU image found for this device") elif len(selected_images) > 1: from gns3.main_window import MainWindow mainwindow = MainWindow.instance() (selection, ok) = QtGui.QInputDialog.getItem(mainwindow, "IOU image", "Please choose an image", selected_images, 0, False) if ok: iouimage = selection else: raise ModuleError("Please select an IOU image") else: iouimage = selected_images[0] name = self._iou_devices[iouimage]["name"] initial_config = self._iou_devices[iouimage]["initial_config"] iou_path = self._iou_devices[iouimage]["path"] use_default_iou_values = self._iou_devices[iouimage]["use_default_iou_values"] settings = {} if initial_config: settings["initial_config"] = initial_config settings["use_default_iou_values"] = use_default_iou_values if not use_default_iou_values: settings["ram"] = self._iou_devices[iouimage]["ram"] settings["nvram"] = self._iou_devices[iouimage]["nvram"] settings["ethernet_adapters"] = self._iou_devices[iouimage]["ethernet_adapters"] settings["serial_adapters"] = self._iou_devices[iouimage]["serial_adapters"] if node.server().isCloud(): settings["cloud_path"] = "images/IOU" node.setup(self._iou_devices[iouimage]["image"], initial_settings=settings) else: node.setup(iou_path, initial_settings=settings)
def setupNode(self, node, node_name): """ Setups a node. :param node: Node instance :param node_name: Node name """ log.info("configuring node {}".format(node)) iouimage = None if node_name: for iou_key, info in self._iou_devices.items(): if node_name == info["name"]: iouimage = iou_key if not iouimage: selected_images = [] for image, info in self._iou_devices.items(): if info["server"] == node.server().host() or (node.server().isLocal() and info["server"] == "local"): selected_images.append(image) if not selected_images: raise ModuleError("No IOU image found for this device") elif len(selected_images) > 1: from gns3.main_window import MainWindow mainwindow = MainWindow.instance() (selection, ok) = QtWidgets.QInputDialog.getItem(mainwindow, "IOU image", "Please choose an image", selected_images, 0, False) if ok: iouimage = selection else: raise ModuleError("Please select an IOU image") else: iouimage = selected_images[0] vm_settings = {} for setting_name, value in self._iou_devices[iouimage].items(): if setting_name in node.settings() and setting_name != "name" and value != "" and value is not None: vm_settings[setting_name] = value default_name_format = IOU_DEVICE_SETTINGS["default_name_format"] if self._iou_devices[iouimage]["default_name_format"]: default_name_format = self._iou_devices[iouimage]["default_name_format"] if vm_settings["use_default_iou_values"]: del vm_settings["ram"] del vm_settings["nvram"] if "console" in vm_settings: # Older GNS3 versions may have a console setting in the VM template del vm_settings["console"] iou_path = vm_settings.pop("path") node.setup(iou_path, additional_settings=vm_settings, default_name_format=default_name_format)
def _iouDeviceNewSlot(self): """ Creates a new IOU device. """ wizard = IOUDeviceWizard(self._iou_devices, parent=self) wizard.show() if wizard.exec_(): new_device_settings = wizard.getSettings() key = "{server}:{name}".format( server=new_device_settings["server"], name=new_device_settings["name"]) self._iou_devices[key] = IOU_DEVICE_SETTINGS.copy() self._iou_devices[key].update(new_device_settings) item = QtGui.QTreeWidgetItem(self.uiIOUDevicesTreeWidget) item.setText(0, self._iou_devices[key]["name"]) item.setIcon(0, QtGui.QIcon(self._iou_devices[key]["default_symbol"])) item.setData(0, QtCore.Qt.UserRole, key) self._items.append(item) self.uiIOUDevicesTreeWidget.setCurrentItem(item) if new_device_settings["server"] == 'cloud': import logging log = logging.getLogger(__name__) # Start uploading the image to cloud files self._upload_image_progress_dialog = QtGui.QProgressDialog( "Uploading image file {}".format( new_device_settings['image']), "Cancel", 0, 0, parent=self) self._upload_image_progress_dialog.setWindowModality( QtCore.Qt.WindowModal) self._upload_image_progress_dialog.setWindowTitle( "IOU image upload") self._upload_image_progress_dialog.show() try: src = self._iou_devices[key]['path'] # Eg: images/IOU/i86.bin dst = 'images/IOU/{}'.format( self._iou_devices[key]['image']) upload_thread = UploadFilesThread( self, MainWindow.instance().cloudSettings(), [(src, dst)]) upload_thread.completed.connect(self._imageUploadComplete) upload_thread.start() except Exception as e: self._upload_image_progress_dialog.reject() log.error(e) QtGui.QMessageBox.critical( self, "IOU image upload", "Error uploading IOU image: {}".format(e))
def allocateServer(self, node_class): """ Allocates a server. :param node_class: Node object :returns: allocated server (HTTPClient instance) """ # check all other modules to find if they # are using a local server using_local_server = [] from gns3.modules import MODULES for module in MODULES: instance = module.instance() if instance != self: module_settings = instance.settings() if "use_local_server" in module_settings: using_local_server.append( module_settings["use_local_server"]) # allocate a server for the node servers = Servers.instance() local_server = servers.localServer() remote_servers = servers.remoteServers() if not all(using_local_server) and len(remote_servers): # a module is not using a local server if True not in using_local_server and len(remote_servers) == 1: # no module is using a local server and there is only one # remote server available, so no need to ask the user. return next(iter(servers)) server_list = [] server_list.append("Local server ({}:{})".format( local_server.host, local_server.port)) for remote_server in remote_servers: server_list.append("{}".format(remote_server)) # TODO: move this to graphics_view from gns3.main_window import MainWindow mainwindow = MainWindow.instance() (selection, ok) = QtGui.QInputDialog.getItem(mainwindow, "Server", "Please choose a server", server_list, 0, False) if ok: if selection.startswith("Local server"): return local_server else: return remote_servers[selection] else: raise ModuleError("Please select a server") return local_server
def setupNode(self, node, node_name): """ Setups a node. :param node: Node instance :param node_name: Node name """ log.info("configuring node {} with id {}".format(node, node.id())) vm = None if node_name: for vm_key, info in self._qemu_vms.items(): if node_name == info["name"]: vm = vm_key if not vm: selected_vms = [] for vm, info in self._qemu_vms.items(): if info["server"] == node.server().host or ( node.server().isLocal() and info["server"] == "local"): selected_vms.append(vm) if not selected_vms: raise ModuleError("No QEMU VM on server {}".format( node.server().host)) elif len(selected_vms) > 1: from gns3.main_window import MainWindow mainwindow = MainWindow.instance() (selection, ok) = QtGui.QInputDialog.getItem(mainwindow, "QEMU VM", "Please choose a VM", selected_vms, 0, False) if ok: vm = selection else: raise ModuleError("Please select a QEMU VM") else: vm = selected_vms[0] # use the template VM settings to create the VM settings vm_settings = {} for setting_name in node.settings(): if setting_name in self._qemu_vms[vm]: if isinstance(self._qemu_vms[vm][setting_name], str) and not self._qemu_vms[vm][setting_name]: # ignore empty paths continue vm_settings[setting_name] = self._qemu_vms[vm][setting_name] qemu_path = settings.pop("qemu_path") name = settings.pop("name") node.setup(qemu_path, additional_settings=vm_settings, base_name=name)
def createNode(self, node, node_name): """ Creates a node. :param node: Node instance :param node_name: Node name """ log.info("creating node {} with id {}".format(node, node.id())) image = None if node_name: for image_key, info in self._docker_containers.items(): if node_name == info["name"]: image = image_key if not image: selected_images = [] for image, info in self._docker_containers.items(): if info["server"] == node.compute().id(): selected_images.append(image) if not selected_images: raise ModuleError("No Docker VM on server {}".format( node.server().url())) elif len(selected_images) > 1: from gns3.main_window import MainWindow mainwindow = MainWindow.instance() (selection, ok) = QtWidgets.QInputDialog.getItem( mainwindow, "Docker Image", "Please choose an image", selected_images, 0, False) if ok: image = selection else: raise ModuleError("Please select a Docker Image") else: image = selected_images[0] image_settings = {} for setting_name, value in self._docker_containers[image].items(): if setting_name in node.settings( ) and value != "" and value is not None: if setting_name not in ['name', 'image']: image_settings[setting_name] = value default_name_format = DOCKER_CONTAINER_SETTINGS["default_name_format"] if self._docker_containers[image]["default_name_format"]: default_name_format = self._docker_containers[image][ "default_name_format"] image = self._docker_containers[image]["image"] node.create(image, base_name=node_name, additional_settings=image_settings, default_name_format=default_name_format)
def setupNode(self, node, node_name): """ Setups a node. :param node: Node instance :param node_name: Node name """ log.info("configuring node {} with id {}".format(node, node.id())) vm = None if node_name: for vm_key, info in self._virtualbox_vms.items(): if node_name == info["vmname"]: vm = vm_key if not vm: selected_vms = [] for vm, info in self._virtualbox_vms.items(): if info["server"] == node.server().host or (node.server().isLocal() and info["server"] == "local"): selected_vms.append(vm) if not selected_vms: raise ModuleError("No VirtualBox VM on server {}".format(node.server().host)) elif len(selected_vms) > 1: from gns3.main_window import MainWindow mainwindow = MainWindow.instance() (selection, ok) = QtGui.QInputDialog.getItem(mainwindow, "VirtualBox VM", "Please choose a VM", selected_vms, 0, False) if ok: vm = selection else: raise ModuleError("Please select a VirtualBox VM") else: vm = selected_vms[0] linked_base = self._virtualbox_vms[vm]["linked_base"] if not linked_base: for other_node in self._nodes: if other_node.settings()["vmname"] == self._virtualbox_vms[vm]["vmname"] and \ (self._virtualbox_vms[vm]["server"] == "local" and other_node.server().isLocal() or self._virtualbox_vms[vm]["server"] == other_node.server().host): raise ModuleError("Sorry a VirtualBox VM can only be used once in your topology (this will change in future versions)") settings = {"adapters": self._virtualbox_vms[vm]["adapters"], "adapter_start_index": self._virtualbox_vms[vm]["adapter_start_index"], "adapter_type": self._virtualbox_vms[vm]["adapter_type"], "headless": self._virtualbox_vms[vm]["headless"], "enable_remote_console": self._virtualbox_vms[vm]["enable_remote_console"]} vmname = self._virtualbox_vms[vm]["vmname"] node.setup(vmname, linked_clone=linked_base, initial_settings=settings)
def _askForUploadMissingImage(self, filename, server): from gns3.main_window import MainWindow parent = MainWindow.instance() reply = QtWidgets.QMessageBox.warning(parent, 'Image', '{} is missing on server {} but exist on your computer. Do you want to upload it?'.format(filename, server.url()), QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) if reply == QtWidgets.QMessageBox.Yes: return True return False
def getDiskImage(parent): destination_directory = os.path.join( MainWindow.instance().imagesDirPath(), "QEMU") path, _ = QtGui.QFileDialog.getOpenFileNameAndFilter( parent, "Select a QEMU disk image", destination_directory) if not path: return if not os.access(path, os.R_OK): QtGui.QMessageBox.critical(parent, "QEMU disk image", "Cannot read {}".format(path)) return try: os.makedirs(destination_directory) except FileExistsError: pass except OSError as e: QtGui.QMessageBox.critical( parent, "QEMU disk images directory", "Could not create the QEMU disk images directory {}: {}". format(destination_directory, e)) return if os.path.normpath(os.path.dirname(path)) != destination_directory: # the QEMU disk image is not in the default images directory reply = QtGui.QMessageBox.question( parent, "QEMU disk image", "Would you like to copy {} to the default images directory". format(os.path.basename(path)), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: destination_path = os.path.join(destination_directory, os.path.basename(path)) thread = FileCopyThread(path, destination_path) progress_dialog = ProgressDialog(thread, "QEMU disk image", "Copying {}".format( os.path.basename(path)), "Cancel", busy=True, parent=parent) thread.deleteLater() progress_dialog.show() progress_dialog.exec_() errors = progress_dialog.errors() if errors: QtGui.QMessageBox.critical(parent, "QEMU disk image", "{}".format("".join(errors))) else: path = destination_path return path
def setupNode(self, node, node_name): """ Setups a node. :param node: Node instance :param node_name: Node name """ log.info("configuring node {} with id {}".format(node, node.id())) vm = None if node_name: for vm_key, info in self._virtualbox_vms.items(): if node_name == info["vmname"]: vm = vm_key if not vm: selected_vms = [] for vm, info in self._virtualbox_vms.items(): if info["server"] == node.server().host or (node.server().isLocal() and info["server"] == "local"): selected_vms.append(vm) if not selected_vms: raise ModuleError("No VirtualBox VM on server {}".format(node.server().host)) elif len(selected_vms) > 1: from gns3.main_window import MainWindow mainwindow = MainWindow.instance() (selection, ok) = QtGui.QInputDialog.getItem(mainwindow, "VirtualBox VM", "Please choose a VM", selected_vms, 0, False) if ok: vm = selection else: raise ModuleError("Please select a VirtualBox VM") else: vm = selected_vms[0] linked_base = self._virtualbox_vms[vm]["linked_base"] if not linked_base: for other_node in self._nodes: if other_node.settings()["vmname"] == self._virtualbox_vms[vm]["vmname"] and \ (self._virtualbox_vms[vm]["server"] == "local" and other_node.server().isLocal() or self._virtualbox_vms[vm]["server"] == other_node.server().host): raise ModuleError("Sorry a VirtualBox VM can only be used once in your topology (this will change in future versions)") elif node.project().temporary(): raise ModuleError("Sorry, VirtualBox linked clones are not supported in temporary projects") vm_settings = {} for setting_name, value in self._virtualbox_vms[vm].items(): if setting_name in node.settings() and value != "" and value is not None: vm_settings[setting_name] = value vmname = self._virtualbox_vms[vm]["vmname"] node.setup(vmname, linked_clone=linked_base, additional_settings=vm_settings)
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._vpcs_nodes = {} self._items = [] self.uiNewVPCSPushButton.clicked.connect(self._newVPCSSlot) self.uiEditVPCSPushButton.clicked.connect(self._editVPCSSlot) self.uiDeleteVPCSPushButton.clicked.connect(self._deleteVPCSSlot) self.uiVPCSTreeWidget.itemSelectionChanged.connect(self._vpcsChangedSlot)
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._traceng_nodes = {} self._items = [] self.uiNewTraceNGPushButton.clicked.connect(self._newTraceNGSlot) self.uiEditTraceNGPushButton.clicked.connect(self._editTraceNGSlot) self.uiDeleteTraceNGPushButton.clicked.connect(self._deleteTraceNGSlot) self.uiTraceNGTreeWidget.itemSelectionChanged.connect(self._tracengChangedSlot)
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._ethernet_hubs = {} self._items = [] self.uiNewEthernetHubPushButton.clicked.connect(self._newEthernetHubSlot) self.uiEditEthernetHubPushButton.clicked.connect(self._editEthernetHubSlot) self.uiDeleteEthernetHubPushButton.clicked.connect(self._deleteEthernetHubSlot) self.uiEthernetHubsTreeWidget.itemSelectionChanged.connect(self._ethernetHubChangedSlot)
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._docker_containers = {} self._items = [] self.uiNewDockerVMPushButton.clicked.connect(self._dockerImageNewSlot) self.uiEditDockerVMPushButton.clicked.connect(self._dockerImageEditSlot) self.uiDeleteDockerVMPushButton.clicked.connect(self._dockerImageDeleteSlot) self.uiDockerVMsTreeWidget.itemSelectionChanged.connect(self._dockerImageChangedSlot)
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._vmware_vms = {} self._items = [] self.uiNewVMwareVMPushButton.clicked.connect(self._vmwareVMNewSlot) self.uiEditVMwareVMPushButton.clicked.connect(self._vmwareVMEditSlot) self.uiDeleteVMwareVMPushButton.clicked.connect(self._vmwareVMDeleteSlot) self.uiVMwareVMsTreeWidget.itemSelectionChanged.connect(self._vmwareVMChangedSlot)
def findAlternativeIOSImage(self, image, node): """ Tries to find an alternative IOS image. :param image: image name :param node: requesting Node instance :return: IOS image (dictionary) """ if image in self._ios_images_cache: return self._ios_images_cache[image] from gns3.main_window import MainWindow mainwindow = MainWindow.instance() ios_routers = self.VMs() candidate_ios_images = {} alternative_image = {"image": image, "ram": None, "idlepc": None} # find all images with the same platform and local server for ios_router in ios_routers.values(): if ios_router["platform"] == node.settings( )["platform"] and ios_router["server"] == "local": if "chassis" in node.settings( ) and ios_router["chassis"] != node.settings()["chassis"]: # continue to look if the chassis is not compatible continue candidate_ios_images[ios_router["image"]] = ios_router if candidate_ios_images: selection, ok = QtWidgets.QInputDialog.getItem( mainwindow, "IOS image", "IOS image {} could not be found\nPlease select an alternative from your existing images:" .format(image), list(candidate_ios_images.keys()), 0, False) if ok: candidate = candidate_ios_images[selection] alternative_image["image"] = candidate["image"] alternative_image["ram"] = candidate["ram"] alternative_image["idlepc"] = candidate["idlepc"] self._ios_images_cache[image] = alternative_image return alternative_image # no registered IOS image is used, let's just ask for an IOS image path msg = "Could not find the {} IOS image \nPlease select a similar IOS image!".format( image) log.error(msg) QtWidgets.QMessageBox.critical(mainwindow, "IOS image", msg) from .pages.ios_router_preferences_page import IOSRouterPreferencesPage image_path = IOSRouterPreferencesPage.getIOSImage(mainwindow, None) if image_path: alternative_image["image"] = image_path self._ios_images_cache[image] = alternative_image return alternative_image
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._ethernet_switches = {} self._items = [] self.uiNewEthernetSwitchPushButton.clicked.connect(self._newEthernetSwitchSlot) self.uiEditEthernetSwitchPushButton.clicked.connect(self._editEthernetSwitchSlot) self.uiDeleteEthernetSwitchPushButton.clicked.connect(self._deleteEthernetSwitchSlot) self.uiEthernetSwitchesTreeWidget.itemSelectionChanged.connect(self._ethernetSwitchChangedSlot)
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._qemu_vms = {} self._items = [] self.uiNewQemuVMPushButton.clicked.connect(self._qemuVMNewSlot) self.uiEditQemuVMPushButton.clicked.connect(self._qemuVMEditSlot) self.uiDeleteQemuVMPushButton.clicked.connect(self._qemuVMDeleteSlot) self.uiQemuVMsTreeWidget.itemSelectionChanged.connect(self._qemuVMChangedSlot)
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._virtualbox_vms = {} self._items = [] self.uiNewVirtualBoxVMPushButton.clicked.connect(self._vboxVMNewSlot) self.uiEditVirtualBoxVMPushButton.clicked.connect(self._vboxVMEditSlot) self.uiDeleteVirtualBoxVMPushButton.clicked.connect(self._vboxVMDeleteSlot) self.uiVirtualBoxVMsTreeWidget.itemSelectionChanged.connect(self._vboxVMChangedSlot)
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._cloud_nodes = {} self._items = [] self.uiNewCloudNodePushButton.clicked.connect(self._newCloudNodeSlot) self.uiEditCloudNodePushButton.clicked.connect(self._editCloudNodeSlot) self.uiDeleteCloudNodePushButton.clicked.connect(self._deleteCloudNodeSlot) self.uiCloudNodesTreeWidget.itemSelectionChanged.connect(self._cloudNodeChangedSlot)
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._iou_devices = {} self._items = [] self.uiNewIOUDevicePushButton.clicked.connect(self._iouDeviceNewSlot) self.uiEditIOUDevicePushButton.clicked.connect(self._iouDeviceEditSlot) self.uiDeleteIOUDevicePushButton.clicked.connect(self._iouDeviceDeleteSlot) self.uiIOUDevicesTreeWidget.itemSelectionChanged.connect(self._iouDeviceChangedSlot)
def done(self, result): """ This dialog is closed. """ super().done(result) if result: #ApplianceManager.instance().appliances_changed_signal.disconnect(self._appliancesChangedSlot) from gns3.main_window import MainWindow if self.currentPage() == self.uiApplianceFromServerWizardPage: items = self.uiAppliancesTreeWidget.selectedItems() for item in items: f = tempfile.NamedTemporaryFile(mode="w+", suffix=".builtin.gns3a", delete=False) json.dump(item.data(0, QtCore.Qt.UserRole), f) f.close() MainWindow.instance().loadPath(f.name) try: os.remove(f.name) except OSError: pass elif self.uiCreateTemplateManuallyRadioButton.isChecked(): MainWindow.instance().preferencesActionSlot() elif self.uiImportApplianceFromFileRadioButton.isChecked(): from gns3.main_window import MainWindow MainWindow.instance().openApplianceActionSlot()
def __init__(self): QtGui.QWidget.__init__(self) self.setupUi(self) self._main_window = MainWindow.instance() self._iou_devices = {} self._items = [] self.uiNewIOUDevicePushButton.clicked.connect(self._iouDeviceNewSlot) self.uiEditIOUDevicePushButton.clicked.connect(self._iouDeviceEditSlot) self.uiDeleteIOUDevicePushButton.clicked.connect(self._iouDeviceDeleteSlot) self.uiIOUDevicesTreeWidget.currentItemChanged.connect(self._iouDeviceChangedSlot) self.uiIOUDevicesTreeWidget.itemPressed.connect(self._iouDevicePressedSlot)
def on_uiButtonBox_clicked(self, button): """ Slot called when a button of the uiButtonBox is clicked. :param button: button that was clicked (QAbstractButton) """ try: from gns3.main_window import MainWindow if button == self.uiButtonBox.button(QtGui.QDialogButtonBox.Apply): self.applySettings() elif button == self.uiButtonBox.button(QtGui.QDialogButtonBox.Reset): self.resetSettings() elif button == self.uiButtonBox.button(QtGui.QDialogButtonBox.Cancel): HTTPClient.setProgressCallback(Progress(MainWindow.instance())) QtGui.QDialog.reject(self) else: self.applySettings() HTTPClient.setProgressCallback(Progress(MainWindow.instance())) QtGui.QDialog.accept(self) except ConfigurationError: pass
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._ios_routers = {} self._items = [] self.uiNewIOSRouterPushButton.clicked.connect(self._iosRouterNewSlot) self.uiEditIOSRouterPushButton.clicked.connect(self._iosRouterEditSlot) self.uiDeleteIOSRouterPushButton.clicked.connect(self._iosRouterDeleteSlot) self.uiIOSRoutersTreeWidget.itemSelectionChanged.connect(self._iosRouterChangedSlot) self.uiDecompressIOSPushButton.clicked.connect(self._decompressIOSSlot)
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._iou_devices = {} self._items = [] self.uiNewIOUDevicePushButton.clicked.connect(self._iouDeviceNewSlot) self.uiCopyIOUDevicePushButton.clicked.connect(self._iouDeviceCopySlot) self.uiEditIOUDevicePushButton.clicked.connect(self._iouDeviceEditSlot) self.uiDeleteIOUDevicePushButton.clicked.connect(self._iouDeviceDeleteSlot) self.uiIOUDevicesTreeWidget.itemSelectionChanged.connect(self._iouDeviceChangedSlot)
def __init__(self): QtGui.QWidget.__init__(self) self.setupUi(self) self._main_window = MainWindow.instance() self._qemu_vms = {} self._items = [] self.uiNewQemuVMPushButton.clicked.connect(self._qemuVMNewSlot) self.uiEditQemuVMPushButton.clicked.connect(self._qemuVMEditSlot) self.uiDeleteQemuVMPushButton.clicked.connect(self._qemuVMDeleteSlot) self.uiQemuVMsTreeWidget.currentItemChanged.connect(self._qemuVMChangedSlot) self.uiQemuVMsTreeWidget.itemPressed.connect(self._qemuVMPressedSlot)
def findAlternativeIOSImage(self, image, node): """ Tries to find an alternative IOS image. :param image: image name :param node: requesting Node instance :return: IOS image (dictionary) """ if image in self._ios_images_cache: return self._ios_images_cache[image] from gns3.main_window import MainWindow mainwindow = MainWindow.instance() ios_routers = self.VMs() candidate_ios_images = {} alternative_image = {"image": image, "ram": None, "idlepc": None} # find all images with the same platform and local server for ios_router in ios_routers.values(): if ios_router["platform"] == node.settings()["platform"] and ios_router["server"] == "local": if "chassis" in node.settings() and ios_router["chassis"] != node.settings()["chassis"]: # continue to look if the chassis is not compatible continue candidate_ios_images[ios_router["image"]] = ios_router if candidate_ios_images: selection, ok = QtWidgets.QInputDialog.getItem(mainwindow, "IOS image", "IOS image {} could not be found\nPlease select an alternative from your existing images:".format(image), list(candidate_ios_images.keys()), 0, False) if ok: candidate = candidate_ios_images[selection] alternative_image["image"] = candidate["image"] alternative_image["ram"] = candidate["ram"] alternative_image["idlepc"] = candidate["idlepc"] self._ios_images_cache[image] = alternative_image return alternative_image # no registered IOS image is used, let's just ask for an IOS image path msg = "Could not find the {} IOS image \nPlease select a similar IOS image!".format(image) log.error(msg) QtWidgets.QMessageBox.critical(mainwindow, "IOS image", msg) from .pages.ios_router_preferences_page import IOSRouterPreferencesPage image_path = IOSRouterPreferencesPage.getIOSImage(mainwindow, None) if image_path: alternative_image["image"] = image_path self._ios_images_cache[image] = alternative_image return alternative_image
def __init__(self): QtGui.QWidget.__init__(self) self.setupUi(self) self._main_window = MainWindow.instance() self._qemu_vms = {} self._items = [] self.uiNewQemuVMPushButton.clicked.connect(self._qemuVMNewSlot) self.uiEditQemuVMPushButton.clicked.connect(self._qemuVMEditSlot) self.uiDeleteQemuVMPushButton.clicked.connect(self._qemuVMDeleteSlot) self.uiQemuVMsTreeWidget.currentItemChanged.connect( self._qemuVMChangedSlot) self.uiQemuVMsTreeWidget.itemPressed.connect(self._qemuVMPressedSlot)
def accept(self): """ Saves the preferences and closes this dialog. """ # close the nodes dock to refresh the node list main_window = self.parentWidget() main_window.uiNodesDockWidget.setVisible(False) main_window.uiNodesDockWidget.setWindowTitle("") if self._applyPreferences(): from gns3.main_window import MainWindow HTTPClient.setProgressCallback(Progress(MainWindow.instance())) QtGui.QDialog.accept(self)
def allocateServer(self, node_class): """ Allocates a server. :param node_class: Node object :returns: allocated server (WebSocketClient instance) """ # check all other modules to find if they # are using a local server using_local_server = [] from gns3.modules import MODULES for module in MODULES: instance = module.instance() if instance != self: module_settings = instance.settings() if "use_local_server" in module_settings: using_local_server.append(module_settings["use_local_server"]) # allocate a server for the node servers = Servers.instance() local_server = servers.localServer() remote_servers = servers.remoteServers() if not all(using_local_server) and len(remote_servers): # a module is not using a local server if not True in using_local_server and len(remote_servers) == 1: # no module is using a local server and there is only one # remote server available, so no need to ask the user. return next(iter(servers)) server_list = [] server_list.append("Local server ({}:{})".format(local_server.host, local_server.port)) for remote_server in remote_servers: server_list.append("{}".format(remote_server)) #TODO: move this to graphics_view from gns3.main_window import MainWindow mainwindow = MainWindow.instance() (selection, ok) = QtGui.QInputDialog.getItem(mainwindow, "Server", "Please choose a server", server_list, 0, False) if ok: if selection.startswith("Local server"): return local_server else: return remote_servers[selection] else: raise ModuleError("Please select a server") return local_server
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._cloud_nodes = {} self._items = [] self.uiNewCloudNodePushButton.clicked.connect(self._newCloudNodeSlot) self.uiEditCloudNodePushButton.clicked.connect(self._editCloudNodeSlot) self.uiDeleteCloudNodePushButton.clicked.connect( self._deleteCloudNodeSlot) self.uiCloudNodesTreeWidget.itemSelectionChanged.connect( self._cloudNodeChangedSlot)
def finish(self): time.sleep(0.5) self.thread_stop = True self.status.setVisible(False) self.progressbar.setValue(self.total) os.remove(self.tmp_filename) temp = self.getRouterTemplet(self.filename) GlobalVar.totalLocalConfig.saveSectionSettings('Dynamips', temp) from gns3.main_window import MainWindow main_window = MainWindow.instance() main_window.uiNodesDockWidget.setVisible(False) main_window.uiNodesDockWidget.setWindowTitle("") GlobalVar.downloadobjectlist.remove(self) GlobalVar.downloadurllist.remove(self.url)
def __init__(self): super().__init__() self.setupUi(self) self._main_window = MainWindow.instance() self._docker_containers = {} self._items = [] self.uiNewDockerVMPushButton.clicked.connect(self._dockerImageNewSlot) self.uiEditDockerVMPushButton.clicked.connect( self._dockerImageEditSlot) self.uiDeleteDockerVMPushButton.clicked.connect( self._dockerImageDeleteSlot) self.uiDockerVMsTreeWidget.itemSelectionChanged.connect( self._dockerImageChangedSlot)
def handleSslError(self, response, ssl_errors): if self._accept_insecure_certificate: response.ignoreSslErrors() return url = response.request().url() host_port_key = f"{url.host()}:{url.port()}" # get the certificate digest ssl_config = response.sslConfiguration() peer_cert = ssl_config.peerCertificate() digest = peer_cert.digest() if host_port_key in self._ssl_exceptions: if self._ssl_exceptions[host_port_key] == digest: response.ignoreSslErrors() return from gns3.main_window import MainWindow main_window = MainWindow.instance() msgbox = QtWidgets.QMessageBox(main_window) msgbox.setWindowTitle("SSL error detected") msgbox.setText( f"This server could not prove that it is {url.host()}:{url.port()}. Please carefully examine the certificate to make sure the server can be trusted." ) msgbox.setInformativeText(f"{ssl_errors[0].errorString()}") msgbox.setDetailedText(peer_cert.toText()) msgbox.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) connect_button = QtWidgets.QPushButton( f"&Connect to {url.host()}:{url.port()}", msgbox) msgbox.addButton(connect_button, QtWidgets.QMessageBox.YesRole) abort_button = QtWidgets.QPushButton("&Abort", msgbox) msgbox.addButton(abort_button, QtWidgets.QMessageBox.RejectRole) msgbox.setDefaultButton(abort_button) msgbox.setIcon(QtWidgets.QMessageBox.Critical) msgbox.exec_() if msgbox.clickedButton() == connect_button: self._ssl_exceptions[host_port_key] = digest response.ignoreSslErrors() else: for error in ssl_errors: log.error(f"SSL error detected: {error.errorString()}") main_window.close()
def __init__(self): QtGui.QWidget.__init__(self) self.setupUi(self) self._main_window = MainWindow.instance() self._iou_images = {} self.uiSaveIOUImagePushButton.clicked.connect(self._iouImageSaveSlot) self.uiDeleteIOUImagePushButton.clicked.connect(self._iouImageDeleteSlot) self.uiIOUImagesTreeWidget.itemClicked.connect(self._iouImageClickedSlot) self.uiIOUImagesTreeWidget.itemSelectionChanged.connect(self._iouImageChangedSlot) self.uiIOUPathToolButton.clicked.connect(self._iouImageBrowserSlot) self.uiStartupConfigToolButton.clicked.connect(self._startupConfigBrowserSlot) self.uiIOUImageTestSettingsPushButton.clicked.connect(self._testSettingsSlot) self.uiDefaultValuesCheckBox.stateChanged.connect(self._useDefaultValuesSlot) #FIXME: temporally hide test button self.uiIOUImageTestSettingsPushButton.hide()
def get_icon(filename): from gns3.main_window import MainWindow style_name = MainWindow.instance().settings().get("style") if style_name.startswith("Charcoal"): style_dir = ":/charcoal_icons/" elif style_name == "Classic": style_dir = ":/classic_icons/" else: style_dir = ":/icons/" icon_path = style_dir + filename if not QtCore.QFile(style_dir + filename).exists(): # fall back to the default legacy style if the icon file doesn't exist icon_path = ":/icons/{}".format(filename) return QtGui.QIcon(icon_path)
def findAlternativeIOUImage(self, image): """ Tries to find an alternative IOU image :param image: path to IOU :return: IOU image path """ if image in self._iou_images_cache: return self._iou_images_cache[image] from gns3.main_window import MainWindow mainwindow = MainWindow.instance() iou_devices = self.iouDevices() candidate_iou_images = {} alternative_image = image # find all images with the same platform and local server for iou_device in iou_devices.values(): if iou_device["server"] == "local": candidate_iou_images[iou_device["image"]] = iou_device["path"] if candidate_iou_images: selection, ok = QtGui.QInputDialog.getItem( mainwindow, "IOU image", "IOU image {} could not be found\nPlease select an alternative from your existing images:" .format(image), list(candidate_iou_images.keys()), 0, False) if ok: iou_image = candidate_iou_images[selection] self._iou_images_cache[image] = iou_image return iou_image # no registered IOU image is used, let's just ask for an IOU image path QtGui.QMessageBox.critical( mainwindow, "IOU image", "Could not find the {} IOU image \nPlease select a similar IOU image!" .format(image)) from .pages.iou_device_preferences_page import IOUDevicePreferencesPage path = IOUDevicePreferencesPage.getIOUImage(mainwindow) if path: alternative_image = path self._iou_images_cache[image] = alternative_image return alternative_image