def parse_command_output(self, cmd, command_result): blocks = [] table = [] # Each row is dictionary if BLOCK_PARSER_KEY in cmd: if ARGUMENTS_KEY in cmd[BLOCK_PARSER_KEY]: block_parser = import_utilities.load_block_parser( cmd[BLOCK_PARSER_KEY][NAME_KEY])( **cmd[BLOCK_PARSER_KEY][ARGUMENTS_KEY]) else: block_parser = import_utilities.load_class( cmd[BLOCK_PARSER_KEY][NAME_KEY])() blocks = import_utilities.load_class_method( block_parser, 'parse')(command_result) else: blocks.append(command_result) for block in blocks: try: if not block: continue result_dict = self.process_block(block, cmd) if len(result_dict) > 0: table += result_dict except IndexError as e: py_logger.info( "Couldn't parse block {}\nfor command {}".format( block, cmd[COMMAND_KEY])) py_logger.error(e) table = self.filter_columns(cmd, table) return table
def process_tables(self, tables): interfaces_all = tables['showInterfacesAll'] output_lines = [] for r in interfaces_all: py_logger.info("Processing row {}".format(r)) if not r['name'].startswith('Port-channel'): continue if r['name'].startswith( 'Port-channel') and r['name'].find('.') != -1: continue value = r['vlan'] d = {} d.update(name=r['name']) if value == '': d.update(vlans='' if value.strip() == '' else str(value)) else: d.update(vlans='1' if r['name'].find('.') == -1 else r['name'][r['name'].find('.') + 1:]) d.update(administrativeStatus=r['administrativeStatus']) d.update(operationalStatus=r['operationalStatus']) d.update(hardwareAddress=r['hardwareAddress']) d.update(mtu=str(r['mtu'])) d.update(interfaceSpeed=str(r['interfaceSpeed'])) d.update(operationalSpeed=str(r['operationalSpeed'])) d.update(duplex=r['duplex'].upper()) d.update(connected=r['connected']) d.update(switchPortMode=r['switchPortMode']) d.update(activePorts=r['activePorts']) d.update(passivePorts='') output_lines.append(d) return output_lines
def execute_commands(self): ssh_connect_handler = None try: ssh_connect_handler = SSHConnectHandler(ip=self.credentials.ip_or_fqdn, username=self.credentials.username, password=self.credentials.password, device_type=self.credentials.device_type, port=self.credentials.port) command_output_dict = {} for workload in self.workloads: command_id = workload[TABLE_ID_KEY] if REUSE_TABLES_KEY in workload: table = self.process_tables(workload) elif REUSE_COMMAND_KEY in workload: command_result = command_output_dict[workload[REUSE_COMMAND_KEY]] workload[COMMAND_KEY] = workload[REUSE_COMMAND_KEY] py_logger.info('Command %s Result %s' % (workload[REUSE_COMMAND_KEY], command_result)) table = self.parse_command_output(workload, command_result) else: command_result = ssh_connect_handler.execute_command(workload[COMMAND_KEY]) command_output_dict[workload[COMMAND_KEY]] = command_result py_logger.info('Command %s Result %s' % (workload[COMMAND_KEY], command_result)) table = self.parse_command_output(workload, command_result) if 'switch' == command_id: table[0]['ipAddress/fqdn'] = self.credentials.ip_or_fqdn table[0]['name'] = "{}-{}".format(table[0]['name'], self.credentials.ip_or_fqdn) self.result_map[command_id] = table except Exception as e: py_logger.error("Error occurred while executing command : {}".format(e)) raise e finally: ssh_connect_handler.close_connection()
def process_tables(self, tables): interfaces_all = tables['showInterfacesAll'] output_lines = [] for r in interfaces_all: py_logger.info("Processing row {}".format(r)) if len(r[constants.IP_KEY]) > 0: py_logger.warn('Ignoring row {}'.format(r)) continue if len(r[constants.ACTIVE_PORTS_KEY]) > 0 or len( r[constants.PASSIVE_PORTS_KEY]) > 0: py_logger.warn('Ignoring row {}'.format(r)) continue value = r[constants.VLAN_KEY] d = {} d.update(name=r[constants.NAME_KEY]) d.update(accessVlan=value) d.update(vlans='' if value.strip() == '' else ','.join([value])) d.update(administrativeStatus=r[constants.ADMIN_ST_KEY]) d.update(operationalStatus=r[constants.OP_ST_KEY]) d.update(hardwareAddress=r[constants.HW_KEY]) d.update(mtu=str(r[constants.MTU_KEY])) d.update(interfaceSpeed=str(r[constants.IF_SPEED_KEY])) d.update(operationalSpeed=str(r[constants.OP_SPEED_KEY])) d.update(duplex=r[constants.DUPLEX_KEY].upper()) d.update(connected=r[constants.CONNECTED_KEY]) d.update(switchPortMode=r[constants.SP_MODE_KEY]) output_lines.append(d) return output_lines
def __init__(self, ip=None, username=None, password=None, enablepwd=None, device_type=None, port=22, **kwargs): self.ip = ip self.username = username self.password = password self.enablemodepwd = enablemodepwd self.port = port if device_type not in DeviceType.values(): raise ValueError("Invalid device type {}".format(device_type)) self.device_type = DeviceType.value_of(device_type).to_lower_case() py_logger.info("Making connection to Device IP {} Type {}".format( ip, self.device_type)) self.net_connect = ConnectHandler(ip=ip, username=username, password=password, secret=enablemodepwd, device_type=self.device_type, port=self.port)
def process_tables(self, tables): interfaces_all = tables['showInterfacesAll'] vrf_ri = tables['showVRFRI'] output_lines = [] for r in interfaces_all: py_logger.info("Processing row {}".format(r)) if len(r[constants.IP_KEY]) == 0: continue d = {} for v in vrf_ri: if r[constants.NAME_KEY] in v[constants.NAME_KEY]: d.update(vrf=v[constants.VRF_KEY]) if constants.VRF_KEY not in d: py_logger.warn('Ignoring row {}'.format(r)) continue d.update(name=r[constants.NAME_KEY]) d.update(ipAddress=r[constants.IP_KEY]) d.update(vlan=r[constants.VLAN_KEY]) d.update(administrativeStatus=r[constants.ADMIN_ST_KEY]) d.update(operationalStatus=r[constants.OP_ST_KEY]) d.update(hardwareAddress=r[constants.HW_KEY]) d.update(mtu=str(r[constants.MTU_KEY])) d.update(interfaceSpeed=str(r[constants.IF_SPEED_KEY])) d.update(operationalSpeed=str(r[constants.OP_SPEED_KEY])) d.update(duplex=r[constants.DUPLEX_KEY].upper()) d.update(connected=r[constants.CONNECTED_KEY]) d.update(switchPortMode=r[constants.SP_MODE_KEY]) output_lines.append(d) return output_lines
def parse(self, data): py_logger.info("Parsing output \n{}".format(data)) output_lines = [] if 'Gateway of last resort' not in data: return output_lines vrf = 'default' lines = data.splitlines() for line in lines: d = dict() fields = re.split('\\s+', line) if 'via' in line: d['name'] = fields[1] d['network'] = fields[1] d['nextHop'] = fields[4].rstrip(',') d['routeType'] = re.sub('[^\\w+|\\s|\\.]', '', fields[0]) d['interfaceName'] = fields[-1] if 'Routing Table' in line: vrf = fields[-1] if 'directly connected' in line: d['name'] = fields[1] d['network'] = fields[1] d['nextHop'] = 'DIRECT' d['routeType'] = 'DIRECT' d['interfaceName'] = fields[-1] if bool(d): output_lines.append(d) for i in output_lines: i.update(vrf=vrf) return output_lines
def execute_command(self, command=None): if command is None: raise ValueError("Command not provided") py_logger.info('Executing command <{}>'.format(command)) result = self.net_connect.send_command(command, delay_factor=2, max_loops=1000) py_logger.info(result) return result
def process_tables(self, tables): interfaces_all = tables['showInterfacesAll'] vrf_ri = tables['showVRFRI'] output_lines = [] for r in interfaces_all: py_logger.info("Processing row {}".format(r)) if len(r['ipAddress']) == 0: continue d = {} for v in vrf_ri: if r['name'] in v['interfaces']: d.update(vrf=v['vrf']) if 'vrf' not in d: py_logger.warn('Ignoring row {}'.format(r)) continue d.update(name=r['name']) d.update(ipAddress=r['ipAddress']) d.update(vlan=r['vlan']) d.update(administrativeStatus=r['administrativeStatus']) d.update(operationalStatus=r['operationalStatus']) d.update(hardwareAddress=r['hardwareAddress']) d.update(mtu=str(r['mtu'])) d.update(interfaceSpeed=str(r['interfaceSpeed'])) d.update(operationalSpeed=str(r['operationalSpeed'])) d.update(duplex=r['duplex'].upper()) d.update(connected=r['connected']) d.update(switchPortMode=r['switchPortMode']) output_lines.append(d) return output_lines
def process_tables(self, tables): interfaces_all = tables['showInterfacesAll'] output_lines = [] for r in interfaces_all: py_logger.info("Processing row {}".format(r)) if len(r['ipAddress']) > 0: py_logger.warn('Ignoring row {}'.format(r)) continue if r['name'].startswith('Port-channel') and r['name'].find( '.') == -1: py_logger.warn('Ignoring row {}'.format(r)) continue value = r['vlan'] d = {} d.update(name=r['name']) d.update(accessVlan=value) d.update(vlans='' if value.strip() == '' else ','.join([value])) d.update(administrativeStatus=r['administrativeStatus']) d.update(operationalStatus=r['operationalStatus']) d.update(hardwareAddress=r['hardwareAddress']) d.update(mtu=str(r['mtu'])) d.update(interfaceSpeed=str(r['interfaceSpeed'])) d.update(operationalSpeed=str(r['operationalSpeed'])) d.update(duplex=r['duplex'].upper()) d.update(connected=r['connected']) d.update(switchPortMode=r['switchPortMode']) output_lines.append(d) return output_lines
def process_tables(self, tables): interfaces_all = tables['showInterfacesAll'] output_lines = [] for r in interfaces_all: py_logger.info("Processing row {}".format(r)) if len(r[constants.ACTIVE_PORTS_KEY]) == 0 and len( r[constants.PASSIVE_PORTS_KEY]) == 0: continue value = r[constants.VLAN_KEY] d = {} d.update(name=r[constants.NAME_KEY]) if value == '': d.update(vlans='' if value.strip() == '' else str(value)) else: d.update( vlans='1' if r[constants.NAME_KEY].find('.') == -1 else r[ constants.NAME_KEY][r[constants.NAME_KEY].find('.') + 1:]) d.update(administrativeStatus=r[constants.ADMIN_ST_KEY]) d.update(operationalStatus=r[constants.OP_ST_KEY]) d.update(hardwareAddress=r[constants.HW_KEY]) d.update(mtu=str(r[constants.MTU_KEY])) d.update(interfaceSpeed=str(r[constants.IF_SPEED_KEY])) d.update(operationalSpeed=str(r[constants.OP_SPEED_KEY])) d.update(duplex=r[constants.DUPLEX_KEY].upper()) d.update(connected=r[constants.CONNECTED_KEY]) d.update(switchPortMode=r[constants.SP_MODE_KEY]) d.update(activePorts=r[constants.ACTIVE_PORTS_KEY]) d.update(passivePorts=r[constants.PASSIVE_PORTS_KEY]) output_lines.append(d) return output_lines
def parse(self, data): py_logger.info("Parsing output \n{}".format(data)) output_lines = [] d = dict() lines = data.splitlines() for line in lines: fields = line.split(' ') if fields[0] == 'hostname': d[constants.HOSTNAME_KEY] = fields[1] output_lines.append(d) return output_lines
def parse(self, data): py_logger.info("Parsing output \n{}".format(data)) output_lines = [] d = dict() lines = data.splitlines() for line in lines: if 'board' in line: d[constants.SN_KEY] = line.split(' ')[-1] if 'Software' in line: d[constants.MODEL_KEY] = line.split('[')[0] output_lines.append(d) return output_lines
def parse(self, data): py_logger.info("Parsing output \n{}".format(data)) lines = self.reformat_lines(data) output_lines = [] for line in lines: d = dict() fields = re.split('\\s+', line) d['vrf'] = fields[0] int_names = re.split(',', fields[-1]) d['interfaces'] = self.convert_interface_names(int_names) output_lines.append(d) return output_lines
def parse(self, data): lines = data.splitlines() output_lines = [] for line in lines[1:]: py_logger.info("Processing row {}".format(line)) d = {} tokenizer = LineTokenizer() fields = tokenizer.tokenize(line) d.update(macAddress=fields[3]) d.update(vlan='1' if fields[-1].find('.') == -1 else fields[-1][fields[-1].find('.') + 1:]) d.update(switchPort=fields[-1]) output_lines.append(d) return output_lines
def parse(self, data): name_regex = "(.*) is (administratively )?(up|down), .*" mtu_regex = "MTU (\\d+) bytes.*" ip_regex = "Internet address is (.*)" interface_speed_regex = ".* BW (\\d+) .*" operational_speed_regex = interface_speed_regex administrative_status_regex = ".* is (?:administratively )?(up|down), .*" operational_status_regex = ".* line protocol is (up|down)" hardware_address_regex = ".* address is (\\w+\\.\\w+\\.\\w+) .*" duplex_regex = "(.*) Duplex.*" vlan_regex = "Encapsulation 802\\.1Q Virtual LAN, Vlan ID\\s+(\\d+).*" active_regex = 'Member.*:\\s+(.*)\\s+,.*' parser = TextProcessor(LineBasedBlockParser('line protocol')) parser.add_rule(Rule('name', name_regex, rule_match_callback)) parser.add_rule(Rule('mtu', mtu_regex, rule_match_callback)) parser.add_rule(Rule('ipAddress', ip_regex, rule_match_callback)) parser.add_rule( Rule('interfaceSpeed', interface_speed_regex, rule_match_callback)) parser.add_rule( Rule('operationalSpeed', operational_speed_regex, rule_match_callback)) parser.add_rule( Rule('administrativeStatus', administrative_status_regex, rule_match_callback)) parser.add_rule( Rule('operationalStatus', operational_status_regex, rule_match_callback)) parser.add_rule( Rule('hardwareAddress', hardware_address_regex, rule_match_callback)) parser.add_rule(Rule('duplex', duplex_regex, rule_match_callback)) parser.add_rule(Rule('vlan', vlan_regex, rule_match_callback)) parser.add_rule(Rule('activePorts', active_regex, rule_match_callback)) output_lines = parser.process(data) if not bool(output_lines): return [] for r in output_lines: py_logger.info("Processing row {}".format(r)) r.update(duplex=r['duplex'].upper()) r.update(interfaceSpeed=int(r['interfaceSpeed']) * 1000) r.update(operationalSpeed=int(r['interfaceSpeed'])) r.update(administrativeStatus=r["administrativeStatus"].upper()) r.update(operationalStatus=r["operationalStatus"].upper()) r.update(connected="TRUE" if r['administrativeStatus'] == 'UP' else "FALSE") r.update(switchPortMode="ACCESS") return output_lines
def parse(self, data): py_logger.info("Parsing output \n{}".format(data)) lines = self.reformat_lines(data) output_lines = [] for line in lines: d = dict() fields = re.split('\\s+', line) d['localInterface'] = '{}{}'.format( self.convert_interface_names(fields[1]), fields[1][2:]) d['remoteDevice'] = fields[0] d['remoteInterface'] = '{}{}'.format( self.convert_interface_names(fields[-1]), fields[-1][2:]) output_lines.append(d) return output_lines
def parse(self, data): py_logger.info("Parsing output \n{}".format(data)) output_lines = [] d = dict() lines = data.splitlines() for line in lines: py_logger.info("Processing row {}".format(line)) if 'board' in line: d['serial'] = line.split(' ')[-1] if 'uptime' in line: d['name'] = line.split(' ')[0] d['hostname'] = line.split(' ')[0] if 'IOS Software' in line: d['model'] = re.sub('[^\\w+|\\s|\\.]', '', line) d['os'] = 'IOS' d['vendor'] = 'Cisco' d['haState'] = 'ACTIVE' output_lines.append(d) return output_lines
def process_tables(self, tables): show_routes = tables['showRoutes'] show_routes_vrf = tables['showRoutesVrf'] output_lines = [] for v in show_routes_vrf: d = dict() if v['routeType'] == 'DIRECT': d['vrf'] = v['vrf'] d['name'] = v['network'] d['network'] = v['network'] d['nextHop'] = 'DIRECT' d['routeType'] = 'DIRECT' d['interfaceName'] = v['interfaceName'] else: d = self.get_dest_entry(v, show_routes, show_routes_vrf) if d is not None: if d['interfaceName'] != '': output_lines.append(d) else: py_logger.info("Ignoring Route Entry {}".format(d)) return output_lines
def parse(self, text): """ Parser output and tokenizes block :param text: :return: line_number and block """ lines = text.splitlines() i = 0 total_lines = len(lines) blocks = list() block = None while i < total_lines: self.current_line_number = i self._set_previous_line(total_lines, lines, i) self._set_next_line(total_lines, lines, i) current_line = str(lines[i]).strip() if self.is_start_of_block(current_line, i) and self.has_block_ended: self.has_block_started = True self.has_block_ended = False if self.has_block_started and not self.has_block_ended: # Block has been initialize now we can add lines to block block = ('' if block is None else block) + current_line else: py_logger.info("Ignoring line {}".format(current_line)) if self.is_end_of_block(current_line, i): blocks.append(block.strip()) self.has_block_started = False self.has_block_ended = True block = None if block is not None: block = block + self.newline_if_required() i += 1 return blocks
def reformat_lines(data): output_lines = [] lines = data.splitlines() deviceid_key = "Device ID" localinft_key = "Local Intrfce" holdtme_key = "Holdtme" capability_key = "Capability" platform_key = "Platform" portid_key = "Port ID" header_regex = '{}\\s+{}\\s+{}\\s+{}\\s+{}\\s+{}'.format( deviceid_key, localinft_key, holdtme_key, capability_key, platform_key, portid_key) is_header_found = False for line in lines: py_logger.info("Parsing line {}".format(line)) if len(line.strip()) == 0 or 'Total cdp entries' in line: continue if re.match(header_regex, line): headers = { deviceid_key: line.find(deviceid_key), localinft_key: line.find(localinft_key), localinft_key: line.find(localinft_key), holdtme_key: line.find(holdtme_key), capability_key: line.find(capability_key), platform_key: line.find(platform_key), portid_key: line.find(portid_key) } py_logger.info("Found header {}".format(headers)) is_header_found = True continue if is_header_found: if line[headers[deviceid_key]] != ' ': output_lines.append(line.strip()) else: output_lines[-1] = output_lines[-1] + ' ' + line.strip() return output_lines
if command is None: raise ValueError("Command not provided") py_logger.info('Executing command <{}>'.format(command)) result = self.net_connect.send_command(command, delay_factor=2, max_loops=1000) py_logger.info(result) return result def execute_multiple_commands(self, commands=None): if commands is None or len(commands) == 0: raise ValueError("Commands not provided") result = '' for command in commands: result = result + self.execute_command(command) + SSHConnectHandler.LINE_BREAK def close_connection(self): self.net_connect.disconnect() if __name__ == '__main__': cisco_881 = { 'device_type': 'CISCO_IOS', 'ip_or_fqdn': '10.40.13.36', 'username': '******', 'password': '******' } sshConnectHandler = SSHConnectHandler(**cisco_881) interfaces = sshConnectHandler.execute_command('show int brief') sshConnectHandler.close_connection() py_logger.info(interfaces)
def process_tables(self, tables): py_logger.info("Processing tables {}".format(tables)) output_lines = [dict(name='default')] for line in tables['showVRFRI']: output_lines.append(dict(name=line['vrf'])) return output_lines
def parse(self, data): name_regex = "(.*) is (administratively )?(up|down), .*" mtu_regex = "MTU (\\d+) bytes.*" ip_regex = "Internet address is (.*)" interface_speed_regex = ".* BW (\\d+) .*" operational_speed_regex = ".*uplex.*, (.*)Mb/s" administrative_status_regex = ".* is (?:administratively )?(up|down), .*" operational_status_regex = ".* line protocol is (?:administratively )?(up|down)" hardware_address_regex = ".* address is (\\w+\\.\\w+\\.\\w+) .*" duplex_regex = "(\\w+)-(d|D)uplex.*" vlan_regex = "Encapsulation 802\\.1Q Virtual LAN, Vlan Id\\s+(\\d+).*" ports_count_regex = "No. of members in this.*(\\d+)" block_parser = SimpleBlockParser() blocks = block_parser.parse(data) output_lines = [] for block in blocks: parser = TextProcessor() parser.add_rule( Rule(constants.NAME_KEY, name_regex, rule_match_callback)) parser.add_rule( Rule(constants.MTU_KEY, mtu_regex, rule_match_callback)) parser.add_rule( Rule(constants.IP_KEY, ip_regex, rule_match_callback)) parser.add_rule( Rule(constants.IF_SPEED_KEY, interface_speed_regex, rule_match_callback)) parser.add_rule( Rule(constants.OP_SPEED_KEY, operational_speed_regex, rule_match_callback)) parser.add_rule( Rule(constants.ADMIN_ST_KEY, administrative_status_regex, rule_match_callback)) parser.add_rule( Rule(constants.OP_ST_KEY, operational_status_regex, rule_match_callback)) parser.add_rule( Rule(constants.HW_KEY, hardware_address_regex, rule_match_callback)) parser.add_rule( Rule(constants.DUPLEX_KEY, duplex_regex, rule_match_callback)) parser.add_rule( Rule(constants.VLAN_KEY, vlan_regex, rule_match_callback)) parser.add_rule( BlockRule(constants.ACTIVE_PORTS_KEY, ports_count_regex, rule_match_callback)) output_lines.append(parser.process(block)[0]) if not bool(output_lines): return [] for r in output_lines: py_logger.info("Processing row {}".format(r)) r.update(duplex=r[constants.DUPLEX_KEY].upper()) if r[constants.IF_SPEED_KEY] == '': r[constants.IF_SPEED_KEY] = '0' r.update(interfaceSpeed=int(r[constants.IF_SPEED_KEY]) * 1024) if r[constants.OP_SPEED_KEY] == '': r[constants.OP_SPEED_KEY] = '0' if r[constants.IP_KEY].lower() == 'unknown': r[constants.IP_KEY] = '' active_ports = '' passive_ports = '' if r[constants.ACTIVE_PORTS_KEY] != '': ports_lines = r[constants.ACTIVE_PORTS_KEY].splitlines() for line in ports_lines: port_fields = line.split() if port_fields[3] == 'Active': active_ports += port_fields[0] + ',' else: passive_ports += port_fields[0] + ',' active_ports = active_ports.rstrip(',') passive_ports = passive_ports.rstrip(',') r.update(activePorts=active_ports) r[constants.PASSIVE_PORTS_KEY] = passive_ports r.update(operationalSpeed=int(r[constants.OP_SPEED_KEY])) r.update(administrativeStatus=r[constants.ADMIN_ST_KEY].upper()) r.update(operationalStatus=r[constants.OP_ST_KEY].upper()) r.update(connected="TRUE" if r[constants.ADMIN_ST_KEY] == 'UP' else "FALSE") r.update(switchPortMode="ACCESS") return output_lines