def __init__(self, hostname, username, password): self.hostname = hostname self.username = username self.password = password self.device = IOSXR(hostname, username, password) self.pending_changes = False self.replace = False
def test_open_no_lock(self, mock_spawn): ''' Test pyiosxr class open - without lock Should return None ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) self.assertIsNone(device.open())
def __init__(self, hostname, username, password, timeout=60, optional_args=None): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.device = IOSXR(hostname, username, password, timeout=timeout) self.pending_changes = False self.replace = False
def test_commit_replace_config_InvalidInputError(self, mock_rpc, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class commit_replace_config Should return InvalidInputError ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None device.open() self.assertRaises(InvalidInputError, device.commit_replace_config, label='label', comment='comment', confirmed=900)
def test_execute_config_show(self, mock_rpc, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr helper __execute_config_show__ Should return True ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None device.open() self.assertTrue(__execute_config_show__(device=device, show_command='show interfaces', timeout=10))
def test_load_candidate_config(self, mock_rpc, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class load_candidate_config Should return None ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None device.open() self.assertIsNone(device.load_candidate_config(config='config'))
def test_close_locked(self, mock_rpc, mock_lock, mock_close, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class close with lock Should return None ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=True) mock_spawn.return_value = None device.open() self.assertIsNone(device.close())
def test_open_no_passwd(self, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class open - pexpect.EOF Should return Nona ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None mock_expect.return_value = 3 self.assertIsNone(device.open())
def test_rollback(self, mock_rpc, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class rollback Should return None ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None device.open() self.assertIsNone(device.rollback())
def test_getattr_AttributeError(self, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class getattr Should return AttributeError ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None device.open() self.assertRaises(AttributeError, getattr, device, 'foo')
def test_commit_config(self, mock_rpc, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class commit_config Should return None ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None device.open() self.assertIsNone(device.commit_config(label='label', comment='comment', confirmed=30))
def test_getattr_show_config(self, mock_show, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class getattr Should return True ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None device.open() mock_show.return_value = '!! IOS XR Configuration !@#$ </Exec>' self.assertTrue(device.show_configuration_merge(config=True))
def test_load_candidate_config_InvalidInputError(self, mock_rpc, mock_discard, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class load_candidate_config Should return InvalidInputError ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None mock_rpc.side_effect = InvalidInputError('error') device.open() self.assertRaises(InvalidInputError, device.load_candidate_config, config='config')
def test_compare_replace_config(self, mock_show, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class compare_replace_config Should return True ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None device.open() mock_show.return_value = '' self.assertEqual('', device.compare_replace_config())
def test_get_candidate_config(self, mock_show, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class get_candidate_config Should return True ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None device.open() mock_show.return_value = '!! IOS XR Configuration' self.assertTrue(device.get_candidate_config(merge=True, formal=True))
def test_make_rpc_call(self, mock_rpc, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class make_rpc_call Should return True ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None mock_rpc.return_value = ElementTree.fromstring('<xml></xml>') device.open() self.assertTrue(device.make_rpc_call("<Get><Operational><LLDP><NodeTable></NodeTable></LLDP></Operational></Get>"))
def test_open(self, mock_lock, mock_spawn): ''' Test pyiosxr class open Should return None ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=True) self.assertIsNone(device.open())
def test_lock_raises_LockError(self): """Tests if DB already locked raises LockError""" if self.MOCK: self.assertRaises( LockError, self.device.lock ) self.assertFalse(self.device.locked) else: self.device.unlock() # make sure the config is not locked same_device = IOSXR(self.HOSTNAME, self.USERNAME, self.PASSWORD, port=self.PORT, lock=self.LOCK, logfile=self.LOG, timeout=self.TIMEOUT) same_device.open() same_device.lock() # the other instance locks the config DB try: # trying to acquire the config DB self.device.lock() except LockError: self.assertFalse(self.device.locked) else: self.assertTrue(self.device.locked) same_device.close()
def test_init(self): ''' Test pyiosxr class init Should return True ''' self.assertTrue( IOSXR(hostname='hostname', username='******', password='******'))
def update_asr_ifaces(asr): host = asr + '-asr' ip = boxes[host]['ip'] ifaces = {'ifaces': []} from pyIOSXR import IOSXR box = IOSXR(hostname=ip, username=IOSXRUSERNAME, password=IOSXRPASSWORD, port=22, timeout=120) box.open() output = box.show_interfaces_brief() buf = StringIO.StringIO(output) box.close() lines = buf.read().split("\n") arpa_regex = re.compile(r".*({}).*".format('ARPA')) for line in lines[3:]: mo_arpa = arpa_regex.search(line) if mo_arpa: row = mo_arpa.group().split() ifaces['ifaces'].append(row[0]) filename = os.path.join(app.root_path, asr + '_ifaces.yml') with open(filename, 'w') as f: yaml.dump(ifaces, f, default_flow_style=False)
def test_execute_config_show(self, mock_rpc, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr helper __execute_config_show__ Should return True ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None device.open() self.assertTrue( __execute_config_show__(device=device, show_command='show interfaces', timeout=10))
def provision_iosxr(port, username, password): device = IOSXR( hostname="127.0.0.1", username=username, password=password, port=port ) device.open() device.load_candidate_config(filename="../iosxr/initial.conf") try: device.commit_replace_config() except pexpect.TIMEOUT: # This actually means everything went fine print_info_message()
def test_commit_config(self, mock_rpc, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class commit_config Should return None ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None device.open() self.assertIsNone( device.commit_config(label='label', comment='comment', confirmed=30))
def test_init_port(self): ''' Test pyiosxr class init - pass port number Should return True ''' self.assertTrue( IOSXR(hostname='hostname', username='******', password='******', port=22))
def test_init_log_stdout(self): ''' Test pyiosxr class init - log to stdout Should return True ''' self.assertTrue( IOSXR(hostname='hostname', username='******', password='******', logfile=sys.stdout))
def test_init_no_lock(self): ''' Test pyiosxr class init - woithout locking Should return True ''' self.assertTrue( IOSXR(hostname='hostname', username='******', password='******', lock=False))
def test_init_log_file(self): ''' Test pyiosxr class init - log to file Should return True ''' self.assertTrue( IOSXR(hostname='hostname', username='******', password='******', logfile='filehandle'))
def test_commit_config_InvalidInputError(self, mock_rpc, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class commit_config Should return InvalidInputError ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None device.open() self.assertRaises(InvalidInputError, device.commit_config, label='label', comment='comment', confirmed=900)
def test_make_rpc_call(self, mock_rpc, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class make_rpc_call Should return True ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=False) mock_spawn.return_value = None mock_rpc.return_value = ElementTree.fromstring('<xml></xml>') device.open() self.assertTrue( device.make_rpc_call( "<Get><Operational><LLDP><NodeTable></NodeTable></LLDP></Operational></Get>" ))
def __init__(self, hostname, username, password, timeout=60, optional_args=None): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.pending_changes = False self.replace = False if optional_args is None: optional_args = {} self.port = optional_args.get('port', 22) self.device = IOSXR(hostname, username, password, timeout=timeout, port=self.port)
def provision_iosxr(port, username, password): device = IOSXR(hostname='127.0.0.1', username=username, password=password, port=port) device.open() device.load_candidate_config(filename='../iosxr/initial.conf') try: device.commit_replace_config() except pexpect.TIMEOUT: # This actually means everything went fine print_info_message()
def __init__(self, hostname, username, password, timeout=60, optional_args=None): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.pending_changes = False self.replace = False if optional_args is None: optional_args = {} self.port = optional_args.pop('port', 22) self.device = IOSXR(hostname, username, password, timeout=timeout, port=self.port)
def test_open_EOFError(self, mock_expect, mock_spawn): ''' Test pyiosxr class open - raising pexpect.EOF Should return EOFError ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=True) mock_spawn.return_value = None mock_expect.side_effect = pexpect.EOF('error') self.assertRaises(EOFError, device.open)
def test_open_XMLCLIError(self, mock_sendline, mock_expect, mock_spawn): ''' Test pyiosxr class open - error as if XML not enabled on device: ERROR: 0x24319600 Should return XMLCLIError ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=True) mock_spawn.return_value = None # expect returns 1 to raise XMLCLIError mock_expect.return_value = 1 self.assertRaises(XMLCLIError, device.open)
class IOSXRDriver(NetworkDriver): def __init__(self, hostname, username, password, timeout=60): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.device = IOSXR(hostname, username, password, timeout=timeout) self.pending_changes = False self.replace = False def open(self): self.device.open() def close(self): self.device.close() def load_replace_candidate(self, filename=None, config=None): self.pending_changes = True self.replace = True try: self.device.load_candidate_config(filename=filename, config=config) except InvalidInputError as e: self.pending_changes = False self.replace = False raise ReplaceConfigException(e.message) def load_merge_candidate(self, filename=None, config=None): self.pending_changes = True self.replace = False try: self.device.load_candidate_config(filename=filename, config=config) except InvalidInputError as e: self.pending_changes = False self.replace = False raise MergeConfigException(e.message) def compare_config(self): if not self.pending_changes: return '' elif self.replace: return self.device.compare_replace_config().strip() else: return self.device.compare_config().strip() def commit_config(self): if self.replace: self.device.commit_replace_config() else: self.device.commit_config() self.pending_changes = False def discard_config(self): self.device.discard_config() self.pending_changes = False def rollback(self): self.device.rollback() def get_facts(self): sh_ver = self.device.show_version() for line in sh_ver.splitlines(): if 'Cisco IOS XR Software' in line: os_version = line.split()[-1] elif 'uptime' in line: uptime = string_parsers.convert_uptime_string_seconds(line) hostname = line.split()[0] fqdn = line.split()[0] elif 'Series' in line: model = ' '.join(line.split()[1:3]) interface_list = list() for x in self.device.show_interface_description().splitlines()[3:-1]: if '.' not in x: interface_list.append(x.split()[0]) result = { 'vendor': u'Cisco', 'os_version': unicode(os_version), 'hostname': unicode(hostname), 'uptime': uptime, 'model': unicode(model), 'serial_number': u'', 'fqdn': unicode(fqdn), 'interface_list': interface_list, } return result def get_interfaces(self): # init result dict result = {} # fetch show interface output sh_int = self.device.show_interfaces() # split per interface, eg by empty line interface_list = sh_int.rstrip().split('\n\n') # for each interface... for interface in interface_list: # splitting this and matching each line avoids issues with order # sorry... interface_lines = interface.split('\n') # init variables to match for interface_name = None is_enabled = None is_up = None mac_address = None description = None speed = None # loop though and match each line for line in interface_lines: description = '' if 'line protocol' in line: lp = line.split() interface_name = lp[0] is_enabled = lp[2] == 'up,' is_up = lp[6] == 'up' elif 'bia' in line: mac_address = line.split()[-1].replace(')', '') elif 'Description' in line: description = ' '.join(line.split()[1:]) elif 'BW' in line: speed = int(line.split()[4]) / 1000 result[interface_name] = { 'is_enabled': is_enabled, 'is_up': is_up, 'mac_address': unicode(mac_address), 'description': unicode(description), 'speed': speed, 'last_flapped': -1.0, } return result def get_interfaces_counters(self): rpc_command = "<Get><Operational><Interfaces><InterfaceTable></InterfaceTable></Interfaces></Operational></Get>" result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) interface_counters = dict() for interface in result_tree.iter('Interface'): interface_name = interface.find('InterfaceHandle').text interface_stats = dict() if interface.find('InterfaceStatistics') is None: continue else: interface_stats = dict() interface_stats['tx_multicast_packets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/MulticastPacketsSent').text) interface_stats['tx_discards'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/OutputDrops').text) interface_stats['tx_octets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/BytesSent').text) interface_stats['tx_errors'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/OutputErrors').text) interface_stats['rx_octets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/BytesReceived').text) interface_stats['tx_unicast_packets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/PacketsSent').text) interface_stats['rx_errors'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/InputErrors').text) interface_stats['tx_broadcast_packets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/BroadcastPacketsSent').text) interface_stats['rx_multicast_packets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/MulticastPacketsReceived').text) interface_stats['rx_broadcast_packets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/BroadcastPacketsReceived').text) interface_stats['rx_discards'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/InputDrops').text) interface_stats['rx_unicast_packets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/PacketsReceived').text) interface_counters[interface_name] = interface_stats return interface_counters def get_bgp_neighbors(self): def generate_vrf_query(vrf_name): """ Helper to provide XML-query for the VRF-type we're interested in. """ if vrf_name == "global": rpc_command = """<Get> <Operational> <BGP> <InstanceTable> <Instance> <Naming> <InstanceName> default </InstanceName> </Naming> <InstanceActive> <DefaultVRF> <GlobalProcessInfo> </GlobalProcessInfo> <NeighborTable> </NeighborTable> </DefaultVRF> </InstanceActive> </Instance> </InstanceTable> </BGP> </Operational> </Get>""" else: rpc_command = """<Get> <Operational> <BGP> <InstanceTable> <Instance> <Naming> <InstanceName> default </InstanceName> </Naming> <InstanceActive> <VRFTable> <VRF> <Naming> %s </Naming> <GlobalProcessInfo> </GlobalProcessInfo> <NeighborTable> </NeighborTable> </VRF> </VRFTable> </InstanceActive> </Instance> </InstanceTable> </BGP> </Operational> </Get>""" % vrf_name return rpc_command """ Initial run to figure out what VRF's are available Decided to get this one from Configured-section because bulk-getting all instance-data to do the same could get ridiculously heavy Assuming we're always interested in the DefaultVRF """ active_vrfs = ["global"] rpc_command = """<Get> <Operational> <BGP> <ConfigInstanceTable> <ConfigInstance> <Naming> <InstanceName> default </InstanceName> </Naming> <ConfigInstanceVRFTable> </ConfigInstanceVRFTable> </ConfigInstance> </ConfigInstanceTable> </BGP> </Operational> </Get>""" result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) for node in result_tree.iter('ConfigVRF'): active_vrfs.append(str(node.find('Naming/VRFName').text)) result = dict() for vrf in active_vrfs: rpc_command = generate_vrf_query(vrf) result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) this_vrf = dict() this_vrf['peers'] = dict() if vrf == "global": this_vrf['router_id'] = unicode(result_tree.find( 'Get/Operational/BGP/InstanceTable/Instance/InstanceActive/DefaultVRF/GlobalProcessInfo/VRF/RouterID').text) else: this_vrf['router_id'] = unicode(result_tree.find( 'Get/Operational/BGP/InstanceTable/Instance/InstanceActive/VRFTable/VRF/GlobalProcessInfo/VRF/RouterID').text) neighbors = dict() for neighbor in result_tree.iter('Neighbor'): this_neighbor = dict() this_neighbor['local_as'] = int(neighbor.find('LocalAS').text) this_neighbor['remote_as'] = int(neighbor.find('RemoteAS').text) this_neighbor['remote_id'] = unicode(neighbor.find('RouterID').text) if neighbor.find('ConnectionAdminStatus').text is "1": this_neighbor['is_enabled'] = True try: this_neighbor['description'] = unicode(neighbor.find('Description').text) except: pass this_neighbor['is_enabled'] = str(neighbor.find('ConnectionAdminStatus').text) is "1" if str(neighbor.find('ConnectionAdminStatus').text) is "1": this_neighbor['is_enabled'] = True else: this_neighbor['is_enabled'] = False if str(neighbor.find('ConnectionState').text) == "BGP_ST_ESTAB": this_neighbor['is_up'] = True this_neighbor['uptime'] = int(neighbor.find('ConnectionEstablishedTime').text) else: this_neighbor['is_up'] = False this_neighbor['uptime'] = -1 this_neighbor['address_family'] = dict() if neighbor.find('ConnectionRemoteAddress/AFI').text == "IPv4": this_afi = "ipv4" elif neighbor.find('ConnectionRemoteAddress/AFI').text == "IPv6": this_afi = "ipv6" else: this_afi = neighbor.find('ConnectionRemoteAddress/AFI').text this_neighbor['address_family'][this_afi] = dict() try: this_neighbor['address_family'][this_afi][ "received_prefixes"] = int(neighbor.find('AFData/Entry/PrefixesAccepted').text) + int( neighbor.find('AFData/Entry/PrefixesDenied').text) this_neighbor['address_family'][this_afi][ "accepted_prefixes"] = int(neighbor.find('AFData/Entry/PrefixesAccepted').text) this_neighbor['address_family'][this_afi][ "sent_prefixes"] = int(neighbor.find('AFData/Entry/PrefixesAdvertised').text) except AttributeError: this_neighbor['address_family'][this_afi]["received_prefixes"] = -1 this_neighbor['address_family'][this_afi]["accepted_prefixes"] = -1 this_neighbor['address_family'][this_afi]["sent_prefixes"] = -1 try: neighbor_ip = unicode(neighbor.find('Naming/NeighborAddress/IPV4Address').text) except: neighbor_ip = unicode(neighbor.find('Naming/NeighborAddress/IPV6Address').text) neighbors[neighbor_ip] = this_neighbor this_vrf['peers'] = neighbors result[vrf] = this_vrf return result def get_environment(self): def get_module_xml_query(module,selection): return """<Get> <AdminOperational> <EnvironmentalMonitoring> <RackTable> <Rack> <Naming> <rack>0</rack> </Naming> <SlotTable> <Slot> <Naming> <slot>%s</slot> </Naming> %s </Slot> </SlotTable> </Rack> </RackTable> </EnvironmentalMonitoring> </AdminOperational> </Get>""" % (module,selection) environment_status = dict() environment_status['fans'] = dict() environment_status['temperature'] = dict() environment_status['power'] = dict() environment_status['cpu'] = dict() environment_status['memory'] = int() # finding slots with equipment we're interested in rpc_command = """<Get> <AdminOperational> <PlatformInventory> <RackTable> <Rack> <Naming> <Name>0</Name> </Naming> <SlotTable> </SlotTable> </Rack> </RackTable> </PlatformInventory> </AdminOperational> </Get>""" result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) active_modules = defaultdict(list) for slot in result_tree.iter("Slot"): for card in slot.iter("CardTable"): #find enabled slots, figoure out type and save for later if card.find('Card/Attributes/FRUInfo/ModuleAdministrativeState').text == "ADMIN_UP": slot_name = slot.find('Naming/Name').text module_type = re.sub("\d+", "", slot_name) if len(module_type) > 0: active_modules[module_type].append(slot_name) else: active_modules["LC"].append(slot_name) # # PSU's # for psu in active_modules['PM']: if psu in ["PM6", "PM7"]: # Cisco bug, chassis difference V01<->V02 continue rpc_command = get_module_xml_query(psu,'') result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) psu_status = dict() psu_status['status'] = False psu_status['capacity'] = float() psu_status['output'] = float() for sensor in result_tree.iter('SensorName'): if sensor.find('Naming/Name').text == "host__VOLT": this_psu_voltage = float(sensor.find('ValueBrief').text) elif sensor.find('Naming/Name').text == "host__CURR": this_psu_current = float(sensor.find('ValueBrief').text) elif sensor.find('Naming/Name').text == "host__PM": this_psu_capacity = float(sensor.find('ValueBrief').text) if this_psu_capacity > 0: psu_status['capacity'] = this_psu_capacity psu_status['status'] = True if this_psu_current and this_psu_voltage: psu_status['output'] = (this_psu_voltage * this_psu_current) / 1000000.0 environment_status['power'][psu] = psu_status # # Memory # rpc_command = "<Get><AdminOperational><MemorySummary></MemorySummary></AdminOperational></Get>" result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) for node in result_tree.iter('Node'): print if node.find('Naming/NodeName/Slot').text == active_modules['RSP'][0]: # first enabled RSP available_ram = int(node.find('Summary/SystemRAMMemory').text) free_ram = int(node.find('Summary/FreeApplicationMemory').text) break # we're only looking at one of the RSP's if available_ram and free_ram: used_ram = available_ram - free_ram memory = dict() memory['available_ram'] = available_ram memory['used_ram'] = used_ram environment_status['memory'] = memory # # Fans # for fan in active_modules['FT']: rpc_command = get_module_xml_query(fan,'') result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) for module in result_tree.iter('Module'): for sensortype in module.iter('SensorType'): for sensorname in sensortype.iter('SensorNameTable'): if sensorname.find('SensorName/Naming/Name').text == "host__FanSpeed_0": environment_status['fans'][fan] = {'status': int(sensorname.find( 'SensorName/ValueDetailed/Status').text) is 1} # # CPU # cpu = dict() rpc_command = "<Get><Operational><SystemMonitoring></SystemMonitoring></Operational></Get>" result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) for module in result_tree.iter('CPUUtilization'): this_cpu = dict() this_cpu["%usage"] = float(module.find('TotalCPUFiveMinute').text) rack = module.find('Naming/NodeName/Rack').text slot = module.find('Naming/NodeName/Slot').text instance = module.find('Naming/NodeName/Instance').text position = "%s/%s/%s" % (rack,slot,instance) cpu[position] = this_cpu environment_status["cpu"] = cpu # # Temperature # temperature = dict() slot_list = set() for category, slot in active_modules.iteritems(): slot_list |= set(slot) for slot in slot_list: rpc_command = get_module_xml_query(slot,'') result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) for sensor in result_tree.findall(".//SensorName"): if not sensor.find('Naming/Name').text == "host__Inlet0": continue this_reading = dict() this_reading['temperature'] = float(sensor.find('ValueBrief').text) threshold_value = [float(x.text) for x in sensor.findall("ThresholdTable/Threshold/ValueBrief")] this_reading['is_alert'] = threshold_value[2] <= this_reading['temperature'] <= threshold_value[3] this_reading['is_critical'] = threshold_value[4] <= this_reading['temperature'] <= threshold_value[5] this_reading['temperature'] = this_reading['temperature']/10 environment_status["temperature"][slot] = this_reading return environment_status def get_lldp_neighbors(self): # init result dict lldp = {} # fetch sh ip bgp output sh_lldp = self.device.show_lldp_neighbors().splitlines()[5:-3] for n in sh_lldp: local_interface = n.split()[1] if local_interface not in lldp.keys(): lldp[local_interface] = list() lldp[local_interface].append({'hostname': unicode(n.split()[0]), 'port': unicode(n.split()[4]), }) return lldp
class IOSXRDriver(NetworkDriver): def __init__(self, hostname, username, password, timeout=60): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.device = IOSXR(hostname, username, password, timeout=timeout) self.pending_changes = False self.replace = False def open(self): self.device.open() def close(self): self.device.close() def load_replace_candidate(self, filename=None, config=None): self.pending_changes = True self.replace = True try: self.device.load_candidate_config(filename=filename, config=config) except InvalidInputError as e: self.pending_changes = False self.replace = False raise ReplaceConfigException(e.message) def load_merge_candidate(self, filename=None, config=None): self.pending_changes = True self.replace = False try: self.device.load_candidate_config(filename=filename, config=config) except InvalidInputError as e: self.pending_changes = False self.replace = False raise MergeConfigException(e.message) def compare_config(self): if not self.pending_changes: return '' elif self.replace: return self.device.compare_replace_config().strip() else: return self.device.compare_config().strip() def commit_config(self): if self.replace: self.device.commit_replace_config() else: self.device.commit_config() self.pending_changes = False def discard_config(self): self.device.discard_config() self.pending_changes = False def rollback(self): self.device.rollback() def get_facts(self): sh_ver = self.device.show_version() for line in sh_ver.splitlines(): if 'Cisco IOS XR Software' in line: os_version = line.split()[-1] elif 'uptime' in line: uptime = string_parsers.convert_uptime_string_seconds(line) hostname = line.split()[0] fqdn = line.split()[0] elif 'Series' in line: model = ' '.join(line.split()[1:3]) interface_list = list() for x in self.device.show_interface_description().splitlines()[3:-1]: if '.' not in x: interface_list.append(x.split()[0]) result = { 'vendor': u'Cisco', 'os_version': unicode(os_version), 'hostname': unicode(hostname), 'uptime': uptime, 'model': unicode(model), 'serial_number': u'', 'fqdn': unicode(fqdn), 'interface_list': interface_list, } return result def get_interfaces(self): # init result dict result = {} # fetch show interface output sh_int = self.device.show_interfaces() # split per interface, eg by empty line interface_list = sh_int.rstrip().split('\n\n') # for each interface... for interface in interface_list: # splitting this and matching each line avoids issues with order # sorry... interface_lines = interface.split('\n') # init variables to match for interface_name = None is_enabled = None is_up = None mac_address = None description = None speed = None # loop though and match each line for line in interface_lines: description = '' if 'line protocol' in line: lp = line.split() interface_name = lp[0] is_enabled = lp[2] == 'up,' is_up = lp[6] == 'up' elif 'bia' in line: mac_address = line.split()[-1].replace(')', '') elif 'Description' in line: description = ' '.join(line.split()[1:]) elif 'BW' in line: speed = int(line.split()[4]) / 1000 result[interface_name] = { 'is_enabled': is_enabled, 'is_up': is_up, 'mac_address': unicode(mac_address), 'description': unicode(description), 'speed': speed, 'last_flapped': -1.0, } return result def get_interfaces_counters(self): rpc_command = "<Get><Operational><Interfaces><InterfaceTable></InterfaceTable></Interfaces></Operational></Get>" result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) interface_counters = dict() for interface in result_tree.iter('Interface'): interface_name = interface.find('InterfaceHandle').text interface_stats = dict() if not interface.find('InterfaceStatistics'): continue else: interface_stats = dict() interface_stats['tx_multicast_packets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/MulticastPacketsSent').text) interface_stats['tx_discards'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/OutputDrops').text) interface_stats['tx_octets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/BytesSent').text) interface_stats['tx_errors'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/OutputErrors').text) interface_stats['rx_octets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/BytesReceived').text) interface_stats['tx_unicast_packets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/PacketsSent').text) interface_stats['rx_errors'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/InputErrors').text) interface_stats['tx_broadcast_packets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/BroadcastPacketsSent').text) interface_stats['rx_multicast_packets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/MulticastPacketsReceived').text) interface_stats['rx_broadcast_packets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/BroadcastPacketsReceived').text) interface_stats['rx_discards'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/InputDrops').text) interface_stats['rx_unicast_packets'] = int(interface.find( 'InterfaceStatistics/FullInterfaceStats/PacketsReceived').text) interface_counters[interface_name] = interface_stats return interface_counters # def get_bgp_neighbors(self): # # # init result dict # result = {} # # todo vrfs # result['default'] = {} # result['default']['peers'] = {} # # # fetch sh ip bgp output # sh_bgp = self.device.show_ip_bgp_neighbors() # # split per bgp neighbor # bgp_list = sh_bgp.rstrip().split('\n\nBGP') # # for each neigh... # for neighbor in bgp_list: # # peer_lines = neighbor.split('\n') # # # init variables # is_up = None # is_enabled = None # uptime = None # description = None # received_prefixes = None # sent_prefixes = None # accepted_prefixes = None # remote_as = None # # for line in peer_lines: # # match1 = re.search('(BGP)? neighbor is (.*)',line) # if match1 is not None: # peer_ip = match1.group(2) # # match2 = re.search('BGP state = (.*)',line) # if match2 is not None: # if match2.group(1) == 'Active': # is_up = False # is_enabled = True # # match3 = re.search('Description: (.*)$',line) # if match3 is not None: # description = match3.group(1) # # match4 = re.search('Remote AS (\d*)',line) # if match4 is not None: # remote_as = int(match4.group(1)) # # # result['default']['peers'][peer_ip] = { # 'is_up': is_up, # 'is_enabled': is_enabled, # 'uptime': uptime, # 'description': description, # 'received_prefixes': received_prefixes, # 'sent_prefixes': sent_prefixes, # 'accepted_prefixes': accepted_prefixes, # 'remote_as': remote_as, # } # # return result def get_lldp_neighbors(self): # init result dict lldp = {} # fetch sh ip bgp output sh_lldp = self.device.show_lldp_neighbors().splitlines()[5:-3] for n in sh_lldp: local_interface = n.split()[1] if local_interface not in lldp.keys(): lldp[local_interface] = list() lldp[local_interface].append({ 'hostname': unicode(n.split()[0]), 'port': unicode(n.split()[4]), }) return lldp
def test_commit_after_other_session_commit(self): """Testing if trying to commit after another process commited does not raise CommitError""" if self.MOCK: # mock data contains the error message we are looking for self.assertIsNone(self.device.commit_config(comment="parallel")) else: # to test this will neet to apply changes to the same device # through a different SSH session same_device = IOSXR(self.HOSTNAME, self.USERNAME, self.PASSWORD, port=self.PORT, lock=self.LOCK, logfile=self.LOG, timeout=self.TIMEOUT) same_device.open() # loading something same_device.load_candidate_config( config='interface MgmtEth0/RP0/CPU0/0 description testing parallel commits' ) # committing same_device.commit_config(comment='pyIOSXR-test_parallel_commits') # trying to load something from the test instance self.device.load_candidate_config(config='interface MgmtEth0/RP0/CPU0/0 description this wont work') # and will fail because of the commit above self.assertIsNone(self.device.commit_config(comment="parallel")) # let's rollback the committed changes same_device.rollback() # and close the auxiliary connection same_device.close() # because this error was raised self.device.close() self.device.open()
class IOSXRDriver(NetworkDriver): def __init__(self, hostname, username, password, timeout=60): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.device = IOSXR(hostname, username, password, timeout=timeout) self.pending_changes = False self.replace = False def open(self): self.device.open() def close(self): self.device.close() def load_replace_candidate(self, filename=None, config=None): self.pending_changes = True self.replace = True try: self.device.load_candidate_config(filename=filename, config=config) except InvalidInputError as e: self.pending_changes = False self.replace = False raise ReplaceConfigException(e.message) def load_merge_candidate(self, filename=None, config=None): self.pending_changes = True self.replace = False try: self.device.load_candidate_config(filename=filename, config=config) except InvalidInputError as e: self.pending_changes = False self.replace = False raise MergeConfigException(e.message) def compare_config(self): if not self.pending_changes: return "" elif self.replace: return self.device.compare_replace_config().strip() else: return self.device.compare_config().strip() def commit_config(self): if self.replace: self.device.commit_replace_config() else: self.device.commit_config() self.pending_changes = False def discard_config(self): self.device.discard_config() self.pending_changes = False def rollback(self): self.device.rollback() def get_facts(self): sh_ver = self.device.show_version() for line in sh_ver.splitlines(): if "Cisco IOS XR Software" in line: os_version = line.split()[-1] elif "uptime" in line: uptime = string_parsers.convert_uptime_string_seconds(line) hostname = line.split()[0] fqdn = line.split()[0] elif "Series" in line: model = " ".join(line.split()[1:3]) interface_list = list() for x in self.device.show_interface_description().splitlines()[3:-1]: if "." not in x: interface_list.append(x.split()[0]) result = { "vendor": u"Cisco", "os_version": unicode(os_version), "hostname": unicode(hostname), "uptime": uptime, "model": unicode(model), "serial_number": u"", "fqdn": unicode(fqdn), "interface_list": interface_list, } return result def get_interfaces(self): # init result dict result = {} # fetch show interface output sh_int = self.device.show_interfaces() # split per interface, eg by empty line interface_list = sh_int.rstrip().split("\n\n") # for each interface... for interface in interface_list: # splitting this and matching each line avoids issues with order # sorry... interface_lines = interface.split("\n") # init variables to match for interface_name = None is_enabled = None is_up = None mac_address = None description = None speed = None # loop though and match each line for line in interface_lines: description = "" if "line protocol" in line: lp = line.split() interface_name = lp[0] is_enabled = lp[2] == "up," is_up = lp[6] == "up" elif "bia" in line: mac_address = line.split()[-1].replace(")", "") elif "Description" in line: description = " ".join(line.split()[1:]) elif "BW" in line: speed = int(line.split()[4]) / 1000 result[interface_name] = { "is_enabled": is_enabled, "is_up": is_up, "mac_address": unicode(mac_address), "description": unicode(description), "speed": speed, "last_flapped": -1.0, } return result # def get_bgp_neighbors(self): # # # init result dict # result = {} # # todo vrfs # result['default'] = {} # result['default']['peers'] = {} # # # fetch sh ip bgp output # sh_bgp = self.device.show_ip_bgp_neighbors() # # split per bgp neighbor # bgp_list = sh_bgp.rstrip().split('\n\nBGP') # # for each neigh... # for neighbor in bgp_list: # # peer_lines = neighbor.split('\n') # # # init variables # is_up = None # is_enabled = None # uptime = None # description = None # received_prefixes = None # sent_prefixes = None # accepted_prefixes = None # remote_as = None # # for line in peer_lines: # # match1 = re.search('(BGP)? neighbor is (.*)',line) # if match1 is not None: # peer_ip = match1.group(2) # # match2 = re.search('BGP state = (.*)',line) # if match2 is not None: # if match2.group(1) == 'Active': # is_up = False # is_enabled = True # # match3 = re.search('Description: (.*)$',line) # if match3 is not None: # description = match3.group(1) # # match4 = re.search('Remote AS (\d*)',line) # if match4 is not None: # remote_as = int(match4.group(1)) # # # result['default']['peers'][peer_ip] = { # 'is_up': is_up, # 'is_enabled': is_enabled, # 'uptime': uptime, # 'description': description, # 'received_prefixes': received_prefixes, # 'sent_prefixes': sent_prefixes, # 'accepted_prefixes': accepted_prefixes, # 'remote_as': remote_as, # } # # return result def get_lldp_neighbors(self): # init result dict lldp = {} # fetch sh ip bgp output sh_lldp = self.device.show_lldp_neighbors().splitlines()[5:-3] for n in sh_lldp: local_interface = n.split()[1] if local_interface not in lldp.keys(): lldp[local_interface] = list() lldp[local_interface].append({"hostname": unicode(n.split()[0]), "port": unicode(n.split()[4])}) return lldp
class IOSXRDriver(NetworkDriver): def __init__(self, hostname, username, password): self.hostname = hostname self.username = username self.password = password self.device = IOSXR(hostname, username, password) self.pending_changes = False def open(self): self.device.open() def close(self): self.device.close() def load_replace_candidate(self, filename=None, config=None): self.pending_changes = True self.replace = True try: self.device.load_candidate_config(filename=filename, config=config) except InvalidInputError as e: self.pending_changes = False self.replace = False raise ReplaceConfigException(e.message) def load_merge_candidate(self, filename=None, config=None): self.pending_changes = True self.replace = False try: self.device.load_candidate_config(filename=filename, config=config) except InvalidInputError as e: self.pending_changes = False self.replace = False raise MergeConfigException(e.message) def compare_config(self): if not self.pending_changes: return "" elif self.replace: return self.device.compare_replace_config() else: return self.device.compare_config() def commit_config(self): if self.replace: self.device.commit_replace_config() else: self.device.commit_config() self.pending_changes = False def discard_config(self): self.device.discard_config() self.pending_changes = False def rollback(self): self.device.rollback()
pprint("Commiting") rsp = dev.cfg.commit() if rsp is True: pprint("Commit successful") dev.close() elif commit_config == 'NO': pprint("Rolling back") dev.cfg.rollback() dev.close() for xr_filename in glob.glob('./configs/*ios_xr.txt'): with open(os.path.join(xr_filename), 'r') as f: ipaddress = str(xr_filename[10:-11]) pprint('***Processing %s port %s ***' % (ipaddress, port)) xr_device = IOSXR(hostname='172.16.2.10', username='******', password='******') xr_device.open() try: xr_device.load_candidate_config(filename=xr_filename) except Exception as err: print('Error occured while loading candidate configs', err) continue if args.confirm is True: pprint("Confirmation bypassed") xr_device.commit_config() xr_device.close() continue else:
class IOSXRDriver(NetworkDriver): def __init__(self, hostname, username, password, timeout=60): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.device = IOSXR(hostname, username, password, timeout=timeout) self.pending_changes = False self.replace = False def open(self): self.device.open() def close(self): self.device.close() def load_replace_candidate(self, filename=None, config=None): self.pending_changes = True self.replace = True try: self.device.load_candidate_config(filename=filename, config=config) except InvalidInputError as e: self.pending_changes = False self.replace = False raise ReplaceConfigException(e.message) def load_merge_candidate(self, filename=None, config=None): self.pending_changes = True self.replace = False try: self.device.load_candidate_config(filename=filename, config=config) except InvalidInputError as e: self.pending_changes = False self.replace = False raise MergeConfigException(e.message) def compare_config(self): if not self.pending_changes: return '' elif self.replace: return self.device.compare_replace_config().strip() else: return self.device.compare_config().strip() def commit_config(self): if self.replace: self.device.commit_replace_config() else: self.device.commit_config() self.pending_changes = False def discard_config(self): self.device.discard_config() self.pending_changes = False def rollback(self): self.device.rollback() def get_facts(self): sh_ver = self.device.show_version() for line in sh_ver.splitlines(): if 'Cisco IOS XR Software' in line: os_version = line.split()[-1] elif 'uptime' in line: uptime = string_parsers.convert_uptime_string_seconds(line) hostname = line.split()[0] fqdn = line.split()[0] elif 'Series' in line: model = ' '.join(line.split()[1:3]) interface_list = list() for x in self.device.show_interface_description().splitlines()[3:-1]: if '.' not in x: interface_list.append(x.split()[0]) result = { 'vendor': u'Cisco', 'os_version': unicode(os_version), 'hostname': unicode(hostname), 'uptime': uptime, 'model': unicode(model), 'serial_number': u'', 'fqdn': unicode(fqdn), 'interface_list': interface_list, } return result def get_interfaces(self): # init result dict result = {} # fetch show interface output sh_int = self.device.show_interfaces() # split per interface, eg by empty line interface_list = sh_int.rstrip().split('\n\n') # for each interface... for interface in interface_list: # splitting this and matching each line avoids issues with order # sorry... interface_lines = interface.split('\n') # init variables to match for interface_name = None is_enabled = None is_up = None mac_address = None description = None speed = None # loop though and match each line for line in interface_lines: description = '' if 'line protocol' in line: lp = line.split() interface_name = lp[0] is_enabled = lp[2] == 'up,' is_up = lp[6] == 'up' elif 'bia' in line: mac_address = line.split()[-1].replace(')', '') elif 'Description' in line: description = ' '.join(line.split()[1:]) elif 'BW' in line: speed = int(line.split()[4]) / 1000 result[interface_name] = { 'is_enabled': is_enabled, 'is_up': is_up, 'mac_address': unicode(mac_address), 'description': unicode(description), 'speed': speed, 'last_flapped': -1.0, } return result def get_interfaces_counters(self): rpc_command = "<Get><Operational><Interfaces><InterfaceTable></InterfaceTable></Interfaces></Operational></Get>" result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) interface_counters = dict() for interface in result_tree.iter('Interface'): interface_name = interface.find('InterfaceHandle').text interface_stats = dict() if interface.find('InterfaceStatistics') is None: continue else: interface_stats = dict() interface_stats['tx_multicast_packets'] = int( interface.find( 'InterfaceStatistics/FullInterfaceStats/MulticastPacketsSent' ).text) interface_stats['tx_discards'] = int( interface.find( 'InterfaceStatistics/FullInterfaceStats/OutputDrops'). text) interface_stats['tx_octets'] = int( interface.find( 'InterfaceStatistics/FullInterfaceStats/BytesSent'). text) interface_stats['tx_errors'] = int( interface.find( 'InterfaceStatistics/FullInterfaceStats/OutputErrors'). text) interface_stats['rx_octets'] = int( interface.find( 'InterfaceStatistics/FullInterfaceStats/BytesReceived' ).text) interface_stats['tx_unicast_packets'] = int( interface.find( 'InterfaceStatistics/FullInterfaceStats/PacketsSent'). text) interface_stats['rx_errors'] = int( interface.find( 'InterfaceStatistics/FullInterfaceStats/InputErrors'). text) interface_stats['tx_broadcast_packets'] = int( interface.find( 'InterfaceStatistics/FullInterfaceStats/BroadcastPacketsSent' ).text) interface_stats['rx_multicast_packets'] = int( interface.find( 'InterfaceStatistics/FullInterfaceStats/MulticastPacketsReceived' ).text) interface_stats['rx_broadcast_packets'] = int( interface.find( 'InterfaceStatistics/FullInterfaceStats/BroadcastPacketsReceived' ).text) interface_stats['rx_discards'] = int( interface.find( 'InterfaceStatistics/FullInterfaceStats/InputDrops'). text) interface_stats['rx_unicast_packets'] = int( interface.find( 'InterfaceStatistics/FullInterfaceStats/PacketsReceived' ).text) interface_counters[interface_name] = interface_stats return interface_counters def get_bgp_neighbors(self): def generate_vrf_query(vrf_name): """ Helper to provide XML-query for the VRF-type we're interested in. """ if vrf_name == "global": rpc_command = """<Get> <Operational> <BGP> <InstanceTable> <Instance> <Naming> <InstanceName> default </InstanceName> </Naming> <InstanceActive> <DefaultVRF> <GlobalProcessInfo> </GlobalProcessInfo> <NeighborTable> </NeighborTable> </DefaultVRF> </InstanceActive> </Instance> </InstanceTable> </BGP> </Operational> </Get>""" else: rpc_command = """<Get> <Operational> <BGP> <InstanceTable> <Instance> <Naming> <InstanceName> default </InstanceName> </Naming> <InstanceActive> <VRFTable> <VRF> <Naming> %s </Naming> <GlobalProcessInfo> </GlobalProcessInfo> <NeighborTable> </NeighborTable> </VRF> </VRFTable> </InstanceActive> </Instance> </InstanceTable> </BGP> </Operational> </Get>""" % vrf_name return rpc_command """ Initial run to figure out what VRF's are available Decided to get this one from Configured-section because bulk-getting all instance-data to do the same could get ridiculously heavy Assuming we're always interested in the DefaultVRF """ active_vrfs = ["global"] rpc_command = """<Get> <Operational> <BGP> <ConfigInstanceTable> <ConfigInstance> <Naming> <InstanceName> default </InstanceName> </Naming> <ConfigInstanceVRFTable> </ConfigInstanceVRFTable> </ConfigInstance> </ConfigInstanceTable> </BGP> </Operational> </Get>""" result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) for node in result_tree.iter('ConfigVRF'): active_vrfs.append(str(node.find('Naming/VRFName').text)) result = dict() for vrf in active_vrfs: rpc_command = generate_vrf_query(vrf) result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) this_vrf = dict() this_vrf['peers'] = dict() if vrf == "global": this_vrf['router_id'] = unicode( result_tree.find( 'Get/Operational/BGP/InstanceTable/Instance/InstanceActive/DefaultVRF/GlobalProcessInfo/VRF/RouterID' ).text) else: this_vrf['router_id'] = unicode( result_tree.find( 'Get/Operational/BGP/InstanceTable/Instance/InstanceActive/VRFTable/VRF/GlobalProcessInfo/VRF/RouterID' ).text) neighbors = dict() for neighbor in result_tree.iter('Neighbor'): this_neighbor = dict() this_neighbor['local_as'] = int(neighbor.find('LocalAS').text) this_neighbor['remote_as'] = int( neighbor.find('RemoteAS').text) this_neighbor['remote_id'] = unicode( neighbor.find('RouterID').text) if neighbor.find('ConnectionAdminStatus').text is "1": this_neighbor['is_enabled'] = True try: this_neighbor['description'] = unicode( neighbor.find('Description').text) except: pass this_neighbor['is_enabled'] = str( neighbor.find('ConnectionAdminStatus').text) is "1" if str(neighbor.find('ConnectionAdminStatus').text) is "1": this_neighbor['is_enabled'] = True else: this_neighbor['is_enabled'] = False if str(neighbor.find( 'ConnectionState').text) == "BGP_ST_ESTAB": this_neighbor['is_up'] = True this_neighbor['uptime'] = int( neighbor.find('ConnectionEstablishedTime').text) else: this_neighbor['is_up'] = False this_neighbor['uptime'] = -1 this_neighbor['address_family'] = dict() if neighbor.find('ConnectionRemoteAddress/AFI').text == "IPv4": this_afi = "ipv4" elif neighbor.find( 'ConnectionRemoteAddress/AFI').text == "IPv6": this_afi = "ipv6" else: this_afi = neighbor.find( 'ConnectionRemoteAddress/AFI').text this_neighbor['address_family'][this_afi] = dict() try: this_neighbor['address_family'][this_afi][ "received_prefixes"] = int( neighbor.find('AFData/Entry/PrefixesAccepted').text ) + int( neighbor.find('AFData/Entry/PrefixesDenied').text) this_neighbor['address_family'][this_afi][ "accepted_prefixes"] = int( neighbor.find( 'AFData/Entry/PrefixesAccepted').text) this_neighbor['address_family'][this_afi][ "sent_prefixes"] = int( neighbor.find( 'AFData/Entry/PrefixesAdvertised').text) except AttributeError: this_neighbor['address_family'][this_afi][ "received_prefixes"] = -1 this_neighbor['address_family'][this_afi][ "accepted_prefixes"] = -1 this_neighbor['address_family'][this_afi][ "sent_prefixes"] = -1 try: neighbor_ip = unicode( neighbor.find( 'Naming/NeighborAddress/IPV4Address').text) except: neighbor_ip = unicode( neighbor.find( 'Naming/NeighborAddress/IPV6Address').text) neighbors[neighbor_ip] = this_neighbor this_vrf['peers'] = neighbors result[vrf] = this_vrf return result def get_environment(self): def get_module_xml_query(module, selection): return """<Get> <AdminOperational> <EnvironmentalMonitoring> <RackTable> <Rack> <Naming> <rack>0</rack> </Naming> <SlotTable> <Slot> <Naming> <slot>%s</slot> </Naming> %s </Slot> </SlotTable> </Rack> </RackTable> </EnvironmentalMonitoring> </AdminOperational> </Get>""" % (module, selection) environment_status = dict() environment_status['fans'] = dict() environment_status['temperature'] = dict() environment_status['power'] = dict() environment_status['cpu'] = dict() environment_status['memory'] = int() # finding slots with equipment we're interested in rpc_command = """<Get> <AdminOperational> <PlatformInventory> <RackTable> <Rack> <Naming> <Name>0</Name> </Naming> <SlotTable> </SlotTable> </Rack> </RackTable> </PlatformInventory> </AdminOperational> </Get>""" result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) active_modules = defaultdict(list) for slot in result_tree.iter("Slot"): for card in slot.iter("CardTable"): #find enabled slots, figoure out type and save for later if card.find( 'Card/Attributes/FRUInfo/ModuleAdministrativeState' ).text == "ADMIN_UP": slot_name = slot.find('Naming/Name').text module_type = re.sub("\d+", "", slot_name) if len(module_type) > 0: active_modules[module_type].append(slot_name) else: active_modules["LC"].append(slot_name) # # PSU's # for psu in active_modules['PM']: if psu in ["PM6", "PM7"]: # Cisco bug, chassis difference V01<->V02 continue rpc_command = get_module_xml_query(psu, '') result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) psu_status = dict() psu_status['status'] = False psu_status['capacity'] = float() psu_status['output'] = float() for sensor in result_tree.iter('SensorName'): if sensor.find('Naming/Name').text == "host__VOLT": this_psu_voltage = float(sensor.find('ValueBrief').text) elif sensor.find('Naming/Name').text == "host__CURR": this_psu_current = float(sensor.find('ValueBrief').text) elif sensor.find('Naming/Name').text == "host__PM": this_psu_capacity = float(sensor.find('ValueBrief').text) if this_psu_capacity > 0: psu_status['capacity'] = this_psu_capacity psu_status['status'] = True if this_psu_current and this_psu_voltage: psu_status['output'] = (this_psu_voltage * this_psu_current) / 1000000.0 environment_status['power'][psu] = psu_status # # Memory # rpc_command = "<Get><AdminOperational><MemorySummary></MemorySummary></AdminOperational></Get>" result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) for node in result_tree.iter('Node'): print if node.find('Naming/NodeName/Slot').text == active_modules['RSP'][ 0]: # first enabled RSP available_ram = int(node.find('Summary/SystemRAMMemory').text) free_ram = int(node.find('Summary/FreeApplicationMemory').text) break # we're only looking at one of the RSP's if available_ram and free_ram: used_ram = available_ram - free_ram memory = dict() memory['available_ram'] = available_ram memory['used_ram'] = used_ram environment_status['memory'] = memory # # Fans # for fan in active_modules['FT']: rpc_command = get_module_xml_query(fan, '') result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) for module in result_tree.iter('Module'): for sensortype in module.iter('SensorType'): for sensorname in sensortype.iter('SensorNameTable'): if sensorname.find('SensorName/Naming/Name' ).text == "host__FanSpeed_0": environment_status['fans'][fan] = { 'status': int( sensorname.find( 'SensorName/ValueDetailed/Status').text ) is 1 } # # CPU # cpu = dict() rpc_command = "<Get><Operational><SystemMonitoring></SystemMonitoring></Operational></Get>" result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) for module in result_tree.iter('CPUUtilization'): this_cpu = dict() this_cpu["%usage"] = float(module.find('TotalCPUFiveMinute').text) rack = module.find('Naming/NodeName/Rack').text slot = module.find('Naming/NodeName/Slot').text instance = module.find('Naming/NodeName/Instance').text position = "%s/%s/%s" % (rack, slot, instance) cpu[position] = this_cpu environment_status["cpu"] = cpu # # Temperature # temperature = dict() slot_list = set() for category, slot in active_modules.iteritems(): slot_list |= set(slot) for slot in slot_list: rpc_command = get_module_xml_query(slot, '') result_tree = ET.fromstring(self.device.make_rpc_call(rpc_command)) for sensor in result_tree.findall(".//SensorName"): if not sensor.find('Naming/Name').text == "host__Inlet0": continue this_reading = dict() this_reading['temperature'] = float( sensor.find('ValueBrief').text) threshold_value = [ float(x.text) for x in sensor.findall( "ThresholdTable/Threshold/ValueBrief") ] this_reading['is_alert'] = threshold_value[2] <= this_reading[ 'temperature'] <= threshold_value[3] this_reading['is_critical'] = threshold_value[ 4] <= this_reading['temperature'] <= threshold_value[5] this_reading['temperature'] = this_reading['temperature'] / 10 environment_status["temperature"][slot] = this_reading return environment_status def get_lldp_neighbors(self): # init result dict lldp = {} # fetch sh ip bgp output sh_lldp = self.device.show_lldp_neighbors().splitlines()[5:-3] for n in sh_lldp: local_interface = n.split()[1] if local_interface not in lldp.keys(): lldp[local_interface] = list() lldp[local_interface].append({ 'hostname': unicode(n.split()[0]), 'port': unicode(n.split()[4]), }) return lldp
if commit_config == 'YES': pprint("Commiting") rsp = dev.cfg.commit() if rsp is True: pprint ("Commit successful") dev.close() elif commit_config == 'NO' : pprint("Rolling back") dev.cfg.rollback() dev.close() for xr_filename in glob.glob('./configs/*ios_xr.txt'): with open(os.path.join(xr_filename), 'r') as f: ipaddress = str(xr_filename[10:-11]) pprint('***Processing %s port %s ***' % (ipaddress, port)) xr_device = IOSXR(hostname='172.16.2.10',username='******',password='******') xr_device.open() try: xr_device.load_candidate_config(filename=xr_filename) except Exception as err: print ('Error occured while loading candidate configs',err) continue if args.confirm is True: pprint("Confirmation bypassed") xr_device.commit_config() xr_device.close() continue else: pprint("The following configs will be applied ")