def __init__(self, node, controller): super().__init__() self.node = node action_label = QLabel('Action') object_label = QLabel('Object') self.general_list = QListWidget() self.general_list.setSortingEnabled(True) self.general_list.itemSelectionChanged.connect(self.info_update) self.action_list = QListWidget() self.action_list.setSortingEnabled(True) self.action_list.itemSelectionChanged.connect(self.action_update) self.properties_edit = QConsoleEdit() self.properties_edit.setMinimumSize(300, 300) layout = QGridLayout() layout.addWidget(object_label, 0, 0) layout.addWidget(self.general_list, 1, 0) layout.addWidget(action_label, 0, 1) layout.addWidget(self.action_list, 1, 1) layout.addWidget(self.properties_edit, 2, 0, 1, 2) self.setLayout(layout)
class NapalmGeneral(QWidget): # Facts and environment @update_paths def __init__(self, node, controller): super().__init__() self.node = node action_label = QLabel('Action') object_label = QLabel('Object') self.general_list = QListWidget() self.general_list.setSortingEnabled(True) self.general_list.itemSelectionChanged.connect(self.info_update) self.action_list = QListWidget() self.action_list.setSortingEnabled(True) self.action_list.itemSelectionChanged.connect(self.action_update) self.properties_edit = QConsoleEdit() self.properties_edit.setMinimumSize(300, 300) layout = QGridLayout() layout.addWidget(object_label, 0, 0) layout.addWidget(self.general_list, 1, 0) layout.addWidget(action_label, 0, 1) layout.addWidget(self.action_list, 1, 1) layout.addWidget(self.properties_edit, 2, 0, 1, 2) self.setLayout(layout) def update(self): self.general_list.clear() if 'Environment' in self.node.napalm_data: infos = ['Facts'] + list(self.node.napalm_data['Environment']) self.general_list.addItems(infos) def info_update(self): self.properties_edit.clear() info = self.general_list.currentItem().text() if info == 'Facts': value = str_dict(self.node.napalm_data['Facts']) self.properties_edit.insertPlainText(value) else: self.action_list.clear() values = map(str, self.node.napalm_data['Environment'][info]) self.action_list.addItems(values) def action_update(self): self.properties_edit.clear() action = self.action_list.currentItem() if action: info = self.general_list.currentItem().text() action_dict = self.node.napalm_data['Environment'][info][ action.text()] self.properties_edit.insertPlainText(str_dict(action_dict))
def __init__(self, node, controller): super().__init__() self.setWindowTitle('Router configuration') self.setMinimumSize(600, 400) config_edit = QConsoleEdit() for conf in self.network.build_router_configuration(node): config_edit.insertPlainText(conf + '\n') layout = QGridLayout() layout.addWidget(config_edit, 0, 0, 1, 1) self.setLayout(layout)
def __init__(self, node, controller): super().__init__() self.setWindowTitle('Switch configuration') self.setMinimumSize(500, 600) config_edit = QConsoleEdit() for conf in self.network.build_switch_configuration(node): config_edit.insertPlainText(conf + '\n') layout = QGridLayout() layout.addWidget(config_edit, 0, 0, 1, 1) self.setLayout(layout)
def __init__(self, nodes, controller): super().__init__() self.nodes = nodes self.setWindowTitle('Send a Jinja2 script') self.setMinimumSize(1000, 500) self.script_content_edit = QConsoleEdit() send_button = QPushButton('Send script') send_button.clicked.connect(self.send_script) layout = QGridLayout() layout.addWidget(self.script_content_edit, 0, 0) layout.addWidget(send_button, 1, 0) self.setLayout(layout)
def __init__(self, node, controller): super().__init__() self.node = node action_label = QLabel('Action') object_label = QLabel('Object') self.object_list = QListWidget() self.object_list.setSortingEnabled(True) self.object_list.itemSelectionChanged.connect(self.text_update) self.action_list = QListWidget() self.action_list.setSortingEnabled(True) self.action_list.itemSelectionChanged.connect(self.text_update) self.action_list.addItems(self.napalm_actions) self.properties_edit = QConsoleEdit() self.properties_edit.setMinimumSize(300, 300) layout = QGridLayout() layout.addWidget(object_label, 0, 0) layout.addWidget(self.object_list, 1, 0) layout.addWidget(action_label, 0, 1) layout.addWidget(self.action_list, 1, 1) layout.addWidget(self.properties_edit, 2, 0, 1, 2) self.setLayout(layout)
def __init__(self, napalm_window, node, credentials): super().__init__() self.napalm_window = napalm_window self.node = node self.credentials = credentials destination = QLabel('Destination') destination_edit = QLineEdit() parameters_groupbox = QGroupBox('Ping / Traceroute') parameters_groupbox_layout = QGridLayout(parameters_groupbox) self.dict_line_edit = {'destination': destination_edit} for index, (parameter, info) in enumerate(self.default_parameters.items()): value, pretty_name = info label = QLabel(pretty_name) label.setMinimumWidth(200) line_edit = QLineEdit(str(value)) # line_edit.setMaximumWidth(200) self.dict_line_edit[parameter] = line_edit y = 2 * bool(index // 3) parameters_groupbox_layout.addWidget(label, index % 3, y) parameters_groupbox_layout.addWidget(line_edit, index % 3, y + 1) napalm_ping = QPushButton('Ping') napalm_ping.clicked.connect(self.ping) parameters_groupbox_layout.addWidget(napalm_ping, 7, 0, 1, 2) napalm_traceroute = QPushButton('Traceroute') napalm_traceroute.clicked.connect(self.traceroute) parameters_groupbox_layout.addWidget(napalm_traceroute, 7, 2, 1, 2) parameters_groupbox.setLayout(parameters_groupbox_layout) result_groupbox = QGroupBox('Result') result_groupbox_layout = QGridLayout(result_groupbox) self.console = QConsoleEdit() result_groupbox_layout.addWidget(self.console, 0, 0) layout = QGridLayout() layout.addWidget(destination, 0, 0) layout.addWidget(destination_edit, 0, 1) layout.addWidget(parameters_groupbox, 1, 0, 1, 2) layout.addWidget(result_groupbox, 2, 0, 1, 2) self.setLayout(layout)
def __init__(self, node, controller): super().__init__() self.node = node self.config_edit = {} for config in ('running', 'startup', 'candidate', 'compare'): text_edit = QConsoleEdit() self.config_edit[config] = text_edit self.addTab(text_edit, '{} config'.format(config.title()))
def __init__(self, node, controller): super().__init__() self.setWindowTitle('ARP table') self.setMinimumSize(1000, 800) config_edit = QConsoleEdit() introduction = ''' Address Resolution Protocol Table ---------------------------------------------------------------------------- Address | Hardware Addr | Type | Interface\n\n''' config_edit.insertPlainText(introduction) arp_table = sorted(node.arpt.items(), key=itemgetter(0)) for oip, (mac_addr, outgoing_interface) in arp_table: line = (oip.ip_addr, mac_addr, 'ARPA', str(outgoing_interface), '\n') config_edit.insertPlainText(8*" " + (9*" ").join(line)) layout = QGridLayout() layout.addWidget(config_edit, 0, 0, 1, 1) self.setLayout(layout)
def __init__(self, node, controller): super().__init__() self.setWindowTitle('Switching table') self.setMinimumSize(600, 800) config_edit = QConsoleEdit() introduction = ''' Mac Address Table ---------------------------------------------------------------------------- Vlan | Mac Address | Type | Ports\n\n''' config_edit.insertPlainText(introduction) switching_table = sorted(node.st.items(), key=itemgetter(0)) for mac_address, outgoing_interface in switching_table: line = ('All', mac_address, 'DYNAMIC', str(outgoing_interface), '\n') config_edit.insertPlainText(16*" " + (8*" ").join(line)) layout = QGridLayout() layout.addWidget(config_edit, 0, 0, 1, 1) self.setLayout(layout)
class NapalmInterfaces(QWidget): napalm_actions = ( 'Interfaces', 'Interface IP', 'Interfaces counters', ) @update_paths def __init__(self, node, controller): super().__init__() self.node = node action_label = QLabel('Action') object_label = QLabel('Object') self.object_list = QListWidget() self.object_list.setSortingEnabled(True) self.object_list.itemSelectionChanged.connect(self.text_update) self.action_list = QListWidget() self.action_list.setSortingEnabled(True) self.action_list.itemSelectionChanged.connect(self.text_update) self.action_list.addItems(self.napalm_actions) self.properties_edit = QConsoleEdit() self.properties_edit.setMinimumSize(300, 300) layout = QGridLayout() layout.addWidget(object_label, 0, 0) layout.addWidget(self.object_list, 1, 0) layout.addWidget(action_label, 0, 1) layout.addWidget(self.action_list, 1, 1) layout.addWidget(self.properties_edit, 2, 0, 1, 2) self.setLayout(layout) def update(self): self.object_list.clear() if 'Interfaces' in self.node.napalm_data: self.object_list.addItems(self.node.napalm_data['Interfaces']) def text_update(self): action = self.action_list.currentItem() object = self.object_list.currentItem() if action and object: self.properties_edit.clear() # we display a dictionnary with the following format: # property1: value1 # property2: value2 action, object = action.text(), object.text() value = str_dict(self.node.napalm_data[action][object]) self.properties_edit.insertPlainText(value)
class SendScriptWindow(QWidget): # this window is a console which content will be convert it into a # jinja2 template before being sent to the device @update_paths def __init__(self, nodes, controller): super().__init__() self.nodes = nodes self.setWindowTitle('Send a Jinja2 script') self.setMinimumSize(1000, 500) self.script_content_edit = QConsoleEdit() send_button = QPushButton('Send script') send_button.clicked.connect(self.send_script) layout = QGridLayout() layout.addWidget(self.script_content_edit, 0, 0) layout.addWidget(send_button, 1, 0) self.setLayout(layout) def send_script(self): config = self.script_content_edit.toPlainText() for node in self.nodes: # log in to the device credentials = self.network.get_credentials(node) connection_parameters = { 'device_type': node.netmiko_operating_system, 'ip': node.ip_address, # credentials to log in to the device 'username': credentials['username'], 'password': credentials['password'], 'enable_password': credentials['enable_password'] } netmiko_connection = ConnectHandler(**connection_parameters) # turn the script into a Jinja2 template j2_config = Template(config).render(**node.__dict__) # send the script line per line for line in j2_config.splitlines(): netmiko_connection.send_command(line) netmiko_connection.disconnect()
def __init__(self, napalm_window, node, credentials): super().__init__() self.napalm_window = napalm_window self.node = node self.credentials = credentials destination = QLabel('Destination') destination_edit = QLineEdit() parameters_groupbox = QGroupBox('Ping / Traceroute') parameters_groupbox_layout = QGridLayout(parameters_groupbox) self.dict_line_edit = {'destination': destination_edit} for index, (parameter, info) in enumerate(self.default_parameters.items()): value, pretty_name = info label = QLabel(pretty_name) label.setMinimumWidth(200) line_edit = QLineEdit(str(value)) # line_edit.setMaximumWidth(200) self.dict_line_edit[parameter] = line_edit y = 2*bool(index // 3) parameters_groupbox_layout.addWidget(label, index % 3, y) parameters_groupbox_layout.addWidget(line_edit, index % 3, y + 1) napalm_ping = QPushButton('Ping') napalm_ping.clicked.connect(self.ping) parameters_groupbox_layout.addWidget(napalm_ping, 7, 0, 1, 2) napalm_traceroute = QPushButton('Traceroute') napalm_traceroute.clicked.connect(self.traceroute) parameters_groupbox_layout.addWidget(napalm_traceroute, 7, 2, 1, 2) parameters_groupbox.setLayout(parameters_groupbox_layout) result_groupbox = QGroupBox('Result') result_groupbox_layout = QGridLayout(result_groupbox) self.console = QConsoleEdit() result_groupbox_layout.addWidget(self.console, 0, 0) layout = QGridLayout() layout.addWidget(destination, 0, 0) layout.addWidget(destination_edit, 0, 1) layout.addWidget(parameters_groupbox, 1, 0, 1, 2) layout.addWidget(result_groupbox, 2, 0, 1, 2) self.setLayout(layout)
def __init__(self, node, controller): super().__init__() self.setWindowTitle('ARP table') self.setMinimumSize(1000, 800) config_edit = QConsoleEdit() introduction = ''' Address Resolution Protocol Table ---------------------------------------------------------------------------- Address | Hardware Addr | Type | Interface\n\n''' config_edit.insertPlainText(introduction) arp_table = sorted(node.arpt.items(), key=itemgetter(0)) for oip, (mac_addr, outgoing_interface) in arp_table: line = (oip.ip_addr, mac_addr, 'ARPA', str(outgoing_interface), '\n') config_edit.insertPlainText(8 * " " + (9 * " ").join(line)) layout = QGridLayout() layout.addWidget(config_edit, 0, 0, 1, 1) self.setLayout(layout)
def __init__(self, node, controller): super().__init__() self.setWindowTitle('Switching table') self.setMinimumSize(600, 800) config_edit = QConsoleEdit() introduction = ''' Mac Address Table ---------------------------------------------------------------------------- Vlan | Mac Address | Type | Ports\n\n''' config_edit.insertPlainText(introduction) switching_table = sorted(node.st.items(), key=itemgetter(0)) for mac_address, outgoing_interface in switching_table: line = ('All', mac_address, 'DYNAMIC', str(outgoing_interface), '\n') config_edit.insertPlainText(16 * " " + (8 * " ").join(line)) layout = QGridLayout() layout.addWidget(config_edit, 0, 0, 1, 1) self.setLayout(layout)
def __init__(self, node, controller): super().__init__() self.setWindowTitle('Routing table') self.setMinimumSize(1000, 500) config_edit = QConsoleEdit() codes = ''' Codes: C - connected, S - static, R - RIP, M - mobile, B - BGP D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2 E1 - OSPF external type 1, E2 - OSPF external type 2 i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2 ia - IS-IS inter area, * - candidate default, U - per-user static route o - ODR, P - periodic downloaded static route\n\n''' config_edit.insertPlainText(codes) gateway = 'Gateway of last resort is not set\n\n' config_edit.insertPlainText(gateway) list_RT = sorted(node.rt.items(), key=itemgetter(1)) for sntw, routes in list_RT: if len(routes) - 1: for idx, route in enumerate(routes): rtype, ex_ip, ex_int, cost, *_, = route rtype = rtype + ' ' * (8 - len(rtype)) if not idx: line = '{rtype}{sntw} [{AD}/{cost}] via {ex_ip}, {ex_int}\n'\ .format( cost = int(cost), rtype = rtype, sntw = sntw, AD = AD[rtype[0]], ex_ip = ex_ip.ip_addr, ex_int = ex_int ) else: spaces = ' ' * (len(rtype) + len(sntw)) line = '{spaces} [{AD}/{cost}] via {ex_ip}, {ex_int}\n'\ .format( spaces = spaces, AD = AD[rtype[0]], cost = int(cost), ex_ip = ex_ip.ip_addr, ex_int = ex_int ) config_edit.insertPlainText(line) else: route, = routes rtype, ex_ip, ex_int, cost, *_, = route rtype = rtype + ' ' * (8 - len(rtype)) if rtype[0] in ('O', 'i', 'R'): route = '{rtype}{sntw} [{AD}/{cost}] via {ex_ip}, {ex_int}\n'\ .format( cost = int(cost), rtype = rtype, sntw = sntw, AD = AD[rtype[0]], ex_ip = ex_ip.ip_addr, ex_int = ex_int ) elif rtype[0] == 'S': route = '{rtype}{sntw} [{AD}/{cost}] via {ex_ip}\n'\ .format( cost = int(cost), rtype = rtype, sntw = sntw, AD = AD[rtype[0]], ex_ip = ex_ip.ip_addr, ) else: route = '{rtype}{sntw} is directly connected, {ex_int}\n'\ .format(rtype=rtype, sntw=sntw, ex_int=ex_int) config_edit.insertPlainText(route) layout = QGridLayout() layout.addWidget(config_edit, 0, 0, 1, 1) self.setLayout(layout)
def __init__(self, node, controller): super().__init__() self.setMinimumSize(1000, 800) ## General troubleshooting commands debug_edit = QConsoleEdit() self.addTab(debug_edit, 'General troubleshooting commands') for line in self.general_troubleshooting_commands(): debug_edit.insertPlainText(line) if any(AS.AS_type == 'RIP' for AS in node.AS): ## RIP Troubleshooting debug_rip = QConsoleEdit() self.addTab(debug_rip, 'RIP Troubleshooting') for line in self.rip_troubleshooting_commands(): debug_rip.insertPlainText(line) if any(AS.AS_type == 'OSPF' for AS in node.AS): ## OSPF Information information_ospf = QConsoleEdit() self.addTab(information_ospf, 'OSPF Information') for line in self.ospf_information(): information_ospf.insertPlainText(line) ## OSPF Troubleshooting debug_ospf = QConsoleEdit() self.addTab(debug_ospf, 'OSPF Troubleshooting') for line in self.ospf_troubleshooting_commands(): debug_ospf.insertPlainText(line)
class NapalmTroubleshoot(QWidget): default_parameters = { 'source': ('', 'Source'), 'ttl': (255, 'TTL'), 'timeout': (2, 'Timeout'), 'vrf': ('', 'VRF'), 'size' : (100, 'Size'), 'count': (5, 'Count') } def __init__(self, napalm_window, node, credentials): super().__init__() self.napalm_window = napalm_window self.node = node self.credentials = credentials destination = QLabel('Destination') destination_edit = QLineEdit() parameters_groupbox = QGroupBox('Ping / Traceroute') parameters_groupbox_layout = QGridLayout(parameters_groupbox) self.dict_line_edit = {'destination': destination_edit} for index, (parameter, info) in enumerate(self.default_parameters.items()): value, pretty_name = info label = QLabel(pretty_name) label.setMinimumWidth(200) line_edit = QLineEdit(str(value)) # line_edit.setMaximumWidth(200) self.dict_line_edit[parameter] = line_edit y = 2*bool(index // 3) parameters_groupbox_layout.addWidget(label, index % 3, y) parameters_groupbox_layout.addWidget(line_edit, index % 3, y + 1) napalm_ping = QPushButton('Ping') napalm_ping.clicked.connect(self.ping) parameters_groupbox_layout.addWidget(napalm_ping, 7, 0, 1, 2) napalm_traceroute = QPushButton('Traceroute') napalm_traceroute.clicked.connect(self.traceroute) parameters_groupbox_layout.addWidget(napalm_traceroute, 7, 2, 1, 2) parameters_groupbox.setLayout(parameters_groupbox_layout) result_groupbox = QGroupBox('Result') result_groupbox_layout = QGridLayout(result_groupbox) self.console = QConsoleEdit() result_groupbox_layout.addWidget(self.console, 0, 0) layout = QGridLayout() layout.addWidget(destination, 0, 0) layout.addWidget(destination_edit, 0, 1) layout.addWidget(parameters_groupbox, 1, 0, 1, 2) layout.addWidget(result_groupbox, 2, 0, 1, 2) self.setLayout(layout) def get_parameters(self, traceroute=True): parameters = {} for parameter, line_edit in self.dict_line_edit.items(): # the traceroute function does not need the following parameters if traceroute and parameter in ('size', 'count'): continue value = line_edit.text() if parameter in ('ttl', 'timeout', 'size', 'count'): value = int(value) parameters[parameter] = value return parameters def traceroute(self): self.console.clear() output = napalm_traceroute(self.credentials, self.node, **self.get_parameters()) self.console.insertPlainText(str_dict(output)) def ping(self): self.console.clear() output = napalm_ping(self.credentials, self.node, **self.get_parameters(False)) self.console.insertPlainText(str_dict(output))
class NapalmTroubleshoot(QWidget): default_parameters = { 'source': ('', 'Source'), 'ttl': (255, 'TTL'), 'timeout': (2, 'Timeout'), 'vrf': ('', 'VRF'), 'size': (100, 'Size'), 'count': (5, 'Count') } def __init__(self, napalm_window, node, credentials): super().__init__() self.napalm_window = napalm_window self.node = node self.credentials = credentials destination = QLabel('Destination') destination_edit = QLineEdit() parameters_groupbox = QGroupBox('Ping / Traceroute') parameters_groupbox_layout = QGridLayout(parameters_groupbox) self.dict_line_edit = {'destination': destination_edit} for index, (parameter, info) in enumerate(self.default_parameters.items()): value, pretty_name = info label = QLabel(pretty_name) label.setMinimumWidth(200) line_edit = QLineEdit(str(value)) # line_edit.setMaximumWidth(200) self.dict_line_edit[parameter] = line_edit y = 2 * bool(index // 3) parameters_groupbox_layout.addWidget(label, index % 3, y) parameters_groupbox_layout.addWidget(line_edit, index % 3, y + 1) napalm_ping = QPushButton('Ping') napalm_ping.clicked.connect(self.ping) parameters_groupbox_layout.addWidget(napalm_ping, 7, 0, 1, 2) napalm_traceroute = QPushButton('Traceroute') napalm_traceroute.clicked.connect(self.traceroute) parameters_groupbox_layout.addWidget(napalm_traceroute, 7, 2, 1, 2) parameters_groupbox.setLayout(parameters_groupbox_layout) result_groupbox = QGroupBox('Result') result_groupbox_layout = QGridLayout(result_groupbox) self.console = QConsoleEdit() result_groupbox_layout.addWidget(self.console, 0, 0) layout = QGridLayout() layout.addWidget(destination, 0, 0) layout.addWidget(destination_edit, 0, 1) layout.addWidget(parameters_groupbox, 1, 0, 1, 2) layout.addWidget(result_groupbox, 2, 0, 1, 2) self.setLayout(layout) def get_parameters(self, traceroute=True): parameters = {} for parameter, line_edit in self.dict_line_edit.items(): # the traceroute function does not need the following parameters if traceroute and parameter in ('size', 'count'): continue value = line_edit.text() if parameter in ('ttl', 'timeout', 'size', 'count'): value = int(value) parameters[parameter] = value return parameters def traceroute(self): self.console.clear() output = napalm_traceroute(self.credentials, self.node, **self.get_parameters()) self.console.insertPlainText(str_dict(output)) def ping(self): self.console.clear() output = napalm_ping(self.credentials, self.node, **self.get_parameters(False)) self.console.insertPlainText(str_dict(output))