napalm-iosxr-0.5.6/0000755000372000037200000000000013173641204014775 5ustar travistravis00000000000000napalm-iosxr-0.5.6/napalm_iosxr/0000755000372000037200000000000013173641204017471 5ustar travistravis00000000000000napalm-iosxr-0.5.6/napalm_iosxr/templates/0000755000372000037200000000000013173641204021467 5ustar travistravis00000000000000napalm-iosxr-0.5.6/napalm_iosxr/templates/delete_ntp_peers.j20000644000372000037200000000007213173641107025246 0ustar travistravis00000000000000{% for peer in peers %} no ntp peer {{peer}} {% endfor %} napalm-iosxr-0.5.6/napalm_iosxr/templates/delete_ntp_servers.j20000644000372000037200000000010213173641107025613 0ustar travistravis00000000000000{% for server in servers %} no ntp server {{server}} {% endfor %} napalm-iosxr-0.5.6/napalm_iosxr/templates/delete_probes.j20000644000372000037200000000106513173641107024544 0ustar travistravis00000000000000ipsla {% set probe_id = 0 %} {% for probe_name, probe_test in probes.iteritems() %} {% for test_name, test_details in probe_test.iteritems() %} no schedule operation {{probe_id + loop.index}} {% endfor %} {% set probe_id = probe_id + probe_test.keys()|length %} {% endfor %} {% set probe_id = 0 %} {% for probe_name, probe_test in probes.iteritems() %} {% for test_name, test_details in probe_test.iteritems() %} no operation {{probe_id + loop.index}} {% endfor %} {% set probe_id = probe_id + probe_test.keys()|length %} {% endfor %} ! napalm-iosxr-0.5.6/napalm_iosxr/templates/delete_snmp_config.j20000644000372000037200000000067613173641107025563 0ustar travistravis00000000000000{% if (location is defined) and location %} no snmp-server location "{{location}}" {% endif %} {% if (contact is defined) and contact %} no snmp-server contact "{{contact}}" {% endif %} {% if (chassis_id is defined) and chassis_id %} no snmp-server chassis-id "{{chassis_id}}" {% endif %} {% if (community is defined) and community %} {% for comm_name, comm_details in community.iteritems() %} no community {{comm_name}} {% endfor %} {% endif %} napalm-iosxr-0.5.6/napalm_iosxr/templates/delete_users.j20000644000372000037200000000044513173641107024414 0ustar travistravis00000000000000{%- for user_name, user_details in users.iteritems() %} {%- if user_details %} username {{user_name}} {%- endif %} {%- if user_details.get('password') %} no password {%- endif %} {%- if user_details.get('level') %} no group {%- endif %} {%- else %} no username {{user_name}} {%- endfor %} napalm-iosxr-0.5.6/napalm_iosxr/templates/schedule_probes.j20000644000372000037200000000051013173641107025070 0ustar travistravis00000000000000ipsla {% set probe_id = 0 %} {% for probe_name, probe_test in probes.iteritems() %} {% for test_name, test_details in probe_test.iteritems() %} schedule operation {{probe_id + loop.index}} start-time now life forever ! {% endfor %} {% set probe_id = probe_id + probe_test.keys()|length %} {% endfor %} ! napalm-iosxr-0.5.6/napalm_iosxr/templates/set_hostname.j20000644000372000037200000000002613173641107024415 0ustar travistravis00000000000000hostname {{hostname}} napalm-iosxr-0.5.6/napalm_iosxr/templates/set_ntp_peers.j20000644000372000037200000000006713173641107024603 0ustar travistravis00000000000000{% for peer in peers %} ntp peer {{peer}} {% endfor %} napalm-iosxr-0.5.6/napalm_iosxr/templates/set_ntp_servers.j20000644000372000037200000000007713173641107025157 0ustar travistravis00000000000000{% for server in servers %} ntp server {{server}} {% endfor %} napalm-iosxr-0.5.6/napalm_iosxr/templates/set_probes.j20000644000372000037200000000227213173641107024076 0ustar travistravis00000000000000ipsla {% set probe_id = 0 %} {% for probe_name, probe_test in probes.iteritems() %} {% for test_name, test_details in probe_test.iteritems() %} no schedule operation {{probe_id + loop.index}} {% endfor %} {% set probe_id = probe_id + probe_test.keys()|length %} {% endfor %} {% set probe_id = 0 %} {% for probe_name, probe_test in probes.iteritems() %} {% for test_name, test_details in probe_test.iteritems() %} operation {{probe_id + loop.index}} {% if test_details.probe_type is defined %} type {{test_details.probe_type|replace('ping', 'echo')|replace('-', ' ')}} {% else %} type icmp echo {% endif %} tag {{test_name}} history lives 1 filter all buckets {{test_details.probe_count}} ! {% if test_details.source is defined %} source address {{test_details.source}} {% endif %} destination address {{test_details.target}} {% if test_details.test_interval is defined %} timeout {{(test_details.test_interval - 1) * 1000}} frequency {{test_details.test_interval}} {% endif %} ! {% endfor %} {% set probe_id = probe_id + probe_test.keys()|length %} ! {% endfor %} ! napalm-iosxr-0.5.6/napalm_iosxr/templates/set_users.j20000644000372000037200000000070713173641107023746 0ustar travistravis00000000000000{%- for user_name, user_details in users.items() %} username {{user_name}} {% set user_level = user_details.level|default(1) %} {%- if user_level == 15 %} group root-system {%- elif user_level == 5 %} group operator {%- elif user_level == 2 %} group serviceadmin {%- elif user_level == 1 %} group sysadmin {% endif %} {%- if user_details.get('password') %} password {{user_details.password}} {%- endif %} {%- endfor %} napalm-iosxr-0.5.6/napalm_iosxr/templates/snmp_config.j20000644000372000037200000000130613173641107024230 0ustar travistravis00000000000000{% if (location is defined) and location %} snmp-server location "{{location}}" {% endif %} {% if (contact is defined) and contact %} snmp-server contact "{{contact}}" {% endif %} {% if (chassis_id is defined) and chassis_id %} snmp-server chassis-id "{{chassis_id}}" {% endif %} {% if (community is defined) and community %} {% for comm_name, comm_details in community.iteritems() %} {% if (comm_details is defined) and comm_details %} {% if (comm_details.get('mode') is defined) and comm_details.get('mode') == 'rw' %} snmp-server community {{comm_name}} RW {% else %} snmp-server community {{comm_name}} RO {% endif %} {% else %} snmp-server community {{comm_name}} RO {% endif %} {% endfor %} {% endif %} napalm-iosxr-0.5.6/napalm_iosxr/__init__.py0000644000372000037200000000171613173641107021611 0ustar travistravis00000000000000# -*- coding: utf-8 -*- # Copyright 2016 Dravetech AB. All rights reserved. # # The contents of this file are licensed under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with the # License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under # the License. """napalm_iosxr package.""" # Import stdlib import pkg_resources # Import local modules from napalm_iosxr.iosxr import IOSXRDriver # noqa __all__ = ('IOSXRDriver',) try: __version__ = pkg_resources.get_distribution('napalm-iosxr').version except pkg_resources.DistributionNotFound: __version__ = "Not installed" napalm-iosxr-0.5.6/napalm_iosxr/constants.py0000644000372000037200000000132513173641107022062 0ustar travistravis00000000000000"""Constants for the IOS-XR driver.""" from __future__ import unicode_literals from napalm_base.constants import * # noqa SR_638170159_SOLVED = False # this flag says if the Cisco TAC SR 638170159 # has been solved # # "XML Agent Does not retrieve correct BGP routes data" # is a weird bug reported on 2016-02-22 22:54:21 # briefly, all BGP routes are handled by the XML agent # in such a way they have the following details: # # - all neighbors are 0.0.0.0 # - all routes are 0.0.0.0/0 # - all RD = 0000000000000000 # # because of this none of the data retrieved # from the BGP oper is usable thus has direct implications # in our implementation of `get_route_to` when retrieving # the BGP protocol specific attributes. napalm-iosxr-0.5.6/napalm_iosxr/iosxr.py0000644000372000037200000024127513173641107021224 0ustar travistravis00000000000000# -*- coding: utf-8 -*- # Copyright 2015 Spotify AB. All rights reserved. # # The contents of this file are licensed under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with the # License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under # the License. from __future__ import unicode_literals # import stdlib import re import copy from collections import defaultdict # import third party lib from lxml import etree as ETREE from netaddr import IPAddress # needed for traceroute, to check IP version from netaddr.core import AddrFormatError from netmiko import __version__ as netmiko_version from pyIOSXR import IOSXR from pyIOSXR.exceptions import ConnectError from pyIOSXR.exceptions import TimeoutError from pyIOSXR.exceptions import InvalidInputError # import NAPALM base import napalm_base.helpers import napalm_iosxr.constants as C from napalm_base.base import NetworkDriver from napalm_base.utils import py23_compat from napalm_base.exceptions import ConnectionException from napalm_base.exceptions import MergeConfigException from napalm_base.exceptions import ReplaceConfigException from napalm_base.exceptions import CommandTimeoutException from napalm_base.utils.py23_compat import text_type class IOSXRDriver(NetworkDriver): """IOS-XR driver class: inherits NetworkDriver from napalm_base.""" 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.lock_on_connect = optional_args.get('config_lock', False) # Netmiko possible arguments netmiko_argument_map = { 'keepalive': 30, 'verbose': False, 'global_delay_factor': 1, 'use_keys': False, 'key_file': None, 'ssh_strict': False, 'system_host_keys': False, 'alt_host_keys': False, 'alt_key_file': '', 'ssh_config_file': None } fields = netmiko_version.split('.') fields = [int(x) for x in fields] maj_ver, min_ver, bug_fix = fields if maj_ver >= 2: netmiko_argument_map['allow_agent'] = False elif maj_ver == 1 and min_ver >= 1: netmiko_argument_map['allow_agent'] = False # Build dict of any optional Netmiko args self.netmiko_optional_args = {} for k, v in netmiko_argument_map.items(): try: self.netmiko_optional_args[k] = optional_args[k] except KeyError: pass self.device = IOSXR(hostname, username, password, timeout=timeout, port=self.port, lock=self.lock_on_connect, **self.netmiko_optional_args) def open(self): try: self.device.open() except ConnectError as conn_err: raise ConnectionException(conn_err.args[0]) def close(self): self.device.close() def is_alive(self): """Returns a flag with the state of the connection.""" # Simply returns the flag from Netmiko return { 'is_alive': self.device.device.is_alive() } def load_replace_candidate(self, filename=None, config=None): self.pending_changes = True self.replace = True if not self.lock_on_connect: self.device.lock() try: self.device.load_candidate_config(filename=filename, config=config) except InvalidInputError as e: self.pending_changes = False self.replace = False raise ReplaceConfigException(e.args[0]) def load_merge_candidate(self, filename=None, config=None): self.pending_changes = True self.replace = False if not self.lock_on_connect: self.device.lock() try: self.device.load_candidate_config(filename=filename, config=config) except InvalidInputError as e: self.pending_changes = False self.replace = False raise MergeConfigException(e.args[0]) 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 if not self.lock_on_connect: self.device.unlock() def discard_config(self): self.device.discard_config() self.pending_changes = False if not self.lock_on_connect: self.device.unlock() def rollback(self): self.device.rollback() def get_facts(self): facts = { 'vendor': u'Cisco', 'os_version': u'', 'hostname': u'', 'uptime': -1, 'serial_number': u'', 'fqdn': u'', 'model': u'', 'interface_list': [] } facts_rpc_request = '\ ' facts_rpc_reply = ETREE.fromstring(self.device.make_rpc_call(facts_rpc_request)) system_time_xpath = './/SystemTime/Uptime' platform_attr_xpath = './/RackTable/Rack/Attributes/BasicInfo' system_time_tree = facts_rpc_reply.xpath(system_time_xpath)[0] try: platform_attr_tree = facts_rpc_reply.xpath(platform_attr_xpath)[0] except IndexError: platform_attr_tree = facts_rpc_reply.xpath(platform_attr_xpath) hostname = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(system_time_tree, 'Hostname')) uptime = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(system_time_tree, 'Uptime'), -1) serial = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(platform_attr_tree, 'SerialNumber')) os_version = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(platform_attr_tree, 'SoftwareRevision')) model = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(platform_attr_tree, 'ModelName')) interface_list = sorted(list(self.get_interfaces().keys())) facts.update({ 'os_version': os_version, 'hostname': hostname, 'model': model, 'uptime': uptime, 'serial_number': serial, 'fqdn': hostname, 'interface_list': interface_list }) return facts def get_interfaces(self): interfaces = {} INTERFACE_DEFAULTS = { 'is_enabled': False, 'is_up': False, 'mac_address': u'', 'description': u'', 'speed': -1, 'last_flapped': -1.0 } interfaces_rpc_request = '' interfaces_rpc_reply = ETREE.fromstring( self.device.make_rpc_call(interfaces_rpc_request)) for interface_tree in interfaces_rpc_reply.xpath('.//Interfaces/InterfaceTable/Interface'): interface_name = napalm_base.helpers.find_txt(interface_tree, 'Naming/InterfaceName') if not interface_name: continue is_up = (napalm_base.helpers.find_txt(interface_tree, 'LineState') == 'IM_STATE_UP') enabled = (napalm_base.helpers.find_txt(interface_tree, 'State') == 'IM_STATE_UP') raw_mac = napalm_base.helpers.find_txt(interface_tree, 'MACAddress/Address') mac_address = napalm_base.helpers.convert( napalm_base.helpers.mac, raw_mac, raw_mac) speed = napalm_base.helpers.convert( int, napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface_tree, 'Bandwidth'), 0) * 1e-3) description = napalm_base.helpers.find_txt(interface_tree, 'Description') interfaces[interface_name] = copy.deepcopy(INTERFACE_DEFAULTS) interfaces[interface_name].update({ 'is_up': is_up, 'speed': speed, 'is_enabled': enabled, 'mac_address': mac_address, 'description': description }) return interfaces def get_interfaces_counters(self): rpc_command = '\ ' result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) interface_counters = {} for interface in result_tree.xpath('.//Interface'): interface_name = napalm_base.helpers.find_txt(interface, 'InterfaceHandle') interface_stats = {} if not interface.xpath('InterfaceStatistics'): continue else: interface_stats = {} interface_stats['tx_multicast_packets'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'InterfaceStatistics/FullInterfaceStats/MulticastPacketsSent')) interface_stats['tx_discards'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'InterfaceStatistics/FullInterfaceStats/OutputDrops')) interface_stats['tx_octets'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'InterfaceStatistics/FullInterfaceStats/BytesSent')) interface_stats['tx_errors'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'InterfaceStatistics/FullInterfaceStats/OutputErrors')) interface_stats['rx_octets'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'InterfaceStatistics/FullInterfaceStats/BytesReceived')) interface_stats['tx_unicast_packets'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'InterfaceStatistics/FullInterfaceStats/PacketsSent')) interface_stats['rx_errors'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'InterfaceStatistics/FullInterfaceStats/InputErrors')) interface_stats['tx_broadcast_packets'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'InterfaceStatistics/FullInterfaceStats/BroadcastPacketsSent')) interface_stats['rx_multicast_packets'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'InterfaceStatistics/FullInterfaceStats/MulticastPacketsReceived')) interface_stats['rx_broadcast_packets'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'InterfaceStatistics/FullInterfaceStats/BroadcastPacketsReceived')) interface_stats['rx_discards'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'InterfaceStatistics/FullInterfaceStats/InputDrops')) interface_stats['rx_unicast_packets'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'InterfaceStatistics/FullInterfaceStats/PacketsReceived')) 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 = '\ default\ \ ' else: rpc_command = '\ default\ {vrf_name}\ \ '.format(vrf_name=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 = '\ default\ ' result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) for node in result_tree.xpath('.//ConfigVRF'): active_vrfs.append(napalm_base.helpers.find_txt(node, 'Naming/VRFName')) result = {} for vrf in active_vrfs: rpc_command = generate_vrf_query(vrf) result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) this_vrf = {} this_vrf['peers'] = {} if vrf == "global": this_vrf['router_id'] = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(result_tree, 'Get/Operational/BGP/InstanceTable/Instance/InstanceActive/DefaultVRF\ /GlobalProcessInfo/VRF/RouterID')) else: this_vrf['router_id'] = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(result_tree, 'Get/Operational/BGP/InstanceTable/Instance/InstanceActive/VRFTable/VRF\ /GlobalProcessInfo/VRF/RouterID')) neighbors = {} for neighbor in result_tree.xpath('.//Neighbor'): this_neighbor = {} this_neighbor['local_as'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'LocalAS')) this_neighbor['remote_as'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'RemoteAS')) this_neighbor['remote_id'] = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(neighbor, 'RouterID')) if napalm_base.helpers.find_txt(neighbor, 'ConnectionAdminStatus') is "1": this_neighbor['is_enabled'] = True try: this_neighbor['description'] = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(neighbor, 'Description')) except AttributeError: this_neighbor['description'] = u'' this_neighbor['is_enabled'] = ( napalm_base.helpers.find_txt(neighbor, 'ConnectionAdminStatus') == "1") if str(napalm_base.helpers.find_txt(neighbor, 'ConnectionAdminStatus')) is "1": this_neighbor['is_enabled'] = True else: this_neighbor['is_enabled'] = False if str(napalm_base.helpers.find_txt(neighbor, 'ConnectionState')) == "BGP_ST_ESTAB": this_neighbor['is_up'] = True this_neighbor['uptime'] = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'ConnectionEstablishedTime')) else: this_neighbor['is_up'] = False this_neighbor['uptime'] = -1 this_neighbor['address_family'] = {} if napalm_base.helpers.find_txt(neighbor, 'ConnectionRemoteAddress/AFI') == "IPv4": this_afi = "ipv4" elif napalm_base.helpers.find_txt(neighbor, 'ConnectionRemoteAddress/AFI') == "IPv6": this_afi = "ipv6" else: this_afi = napalm_base.helpers.find_txt(neighbor, 'ConnectionRemoteAddress/AFI') this_neighbor['address_family'][this_afi] = {} try: this_neighbor['address_family'][this_afi]["received_prefixes"] = \ napalm_base.helpers.convert(int, napalm_base.helpers.find_txt( neighbor, 'AFData/Entry/PrefixesAccepted'), 0) + \ napalm_base.helpers.convert(int, napalm_base.helpers.find_txt( neighbor, 'AFData/Entry/PrefixesDenied'), 0) this_neighbor['address_family'][this_afi]["accepted_prefixes"] = \ napalm_base.helpers.convert(int, napalm_base.helpers.find_txt( neighbor, 'AFData/Entry/PrefixesAccepted'), 0) this_neighbor['address_family'][this_afi]["sent_prefixes"] = \ napalm_base.helpers.convert(int, napalm_base.helpers.find_txt( neighbor, 'AFData/Entry/PrefixesAdvertised'), 0) 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 neighbor_ip = napalm_base.helpers.ip( napalm_base.helpers.find_txt( neighbor, 'Naming/NeighborAddress/IPV4Address') or napalm_base.helpers.find_txt( neighbor, 'Naming/NeighborAddress/IPV6Address') ) 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 '\ 0{slot}{name}\ \ '.format(slot=module, name=selection) environment_status = {} environment_status['fans'] = {} environment_status['temperature'] = {} environment_status['power'] = {} environment_status['cpu'] = {} environment_status['memory'] = 0.0 # finding slots with equipment we're interested in rpc_command = '\ 0\ ' result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) active_modules = defaultdict(list) for slot in result_tree.xpath(".//Slot"): for card in slot.xpath(".//CardTable"): # find enabled slots, figoure out type and save for later if napalm_base.helpers.find_txt(card, 'Card/Attributes/FRUInfo/ModuleAdministrativeState') == "ADMIN_UP": slot_name = napalm_base.helpers.find_txt(slot, 'Naming/Name') 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 = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) psu_status = {} psu_status['status'] = False psu_status['capacity'] = 0.0 psu_status['output'] = 0.0 for sensor in result_tree.xpath('.//SensorName'): if napalm_base.helpers.find_txt(sensor, 'Naming/Name') == "host__VOLT": this_psu_voltage = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(sensor, 'ValueBrief')) elif napalm_base.helpers.find_txt(sensor, 'Naming/Name') == "host__CURR": this_psu_current = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(sensor, 'ValueBrief')) elif napalm_base.helpers.find_txt(sensor, 'Naming/Name') == "host__PM": this_psu_capacity = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(sensor, 'ValueBrief')) 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 # facts = self.get_facts() router_model = facts.get('model') is_xrv = router_model.lower().startswith('xrv') environment_status['memory'] = { 'available_ram': 0.0, 'used_ram': 0.0 } if not is_xrv: rpc_command = '\ ' result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) for node in result_tree.xpath('.//Node'): if napalm_base.helpers.find_txt(node, 'Naming/NodeName/Slot') == active_modules['RSP'][0]: available_ram = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(node, 'Summary/SystemRAMMemory')) free_ram = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(node, 'Summary/FreeApplicationMemory')) break # we're only looking at one of the RSP's if available_ram and free_ram: used_ram = available_ram - free_ram memory = {} 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 = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) for module in result_tree.xpath('.//Module'): for sensortype in module.xpath('.//SensorType'): for sensorname in sensortype.xpath('.//SensorNameTable'): if napalm_base.helpers.find_txt(sensorname, 'SensorName/Naming/Name') == "host__FanSpeed_0": environment_status['fans'][fan] = { 'status': napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(sensorname, 'SensorName/ValueDetailed/Status') ) == 1 } # # CPU # cpu = {} rpc_command = '' result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) for module in result_tree.xpath('.//CPUUtilization'): this_cpu = {} this_cpu["%usage"] = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(module, 'TotalCPUFiveMinute')) rack = napalm_base.helpers.find_txt(module, 'Naming/NodeName/Rack') slot = napalm_base.helpers.find_txt(module, 'Naming/NodeName/Slot') instance = napalm_base.helpers.find_txt(module, 'Naming/NodeName/Instance') position = "%s/%s/%s" % (rack, slot, instance) cpu[position] = this_cpu environment_status["cpu"] = cpu # # Temperature # slot_list = set() for category, slot in active_modules.items(): slot_list |= set(slot) if not is_xrv: for slot in slot_list: rpc_command = get_module_xml_query(slot, '') result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) for sensor in result_tree.xpath(".//SensorName"): if not napalm_base.helpers.find_txt(sensor, 'Naming/Name') == "host__Inlet0": continue this_reading = {} this_reading['temperature'] = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(sensor, 'ValueBrief')) threshold_value = [ napalm_base.helpers.convert(float, x.text) for x in sensor.xpath("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 = {} 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] = [] lldp[local_interface].append({ 'hostname': napalm_base.helpers.convert( text_type, n.split()[0]), 'port': napalm_base.helpers.convert( text_type, n.split()[4]) }) return lldp def get_lldp_neighbors_detail(self, interface=''): lldp_neighbors = {} rpc_command = '' result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) for neighbor in result_tree.xpath('.//Neighbors/DetailTable/Detail/Entry'): interface_name = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(neighbor, 'ReceivingInterfaceName')) parent_interface = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(neighbor, 'ReceivingParentInterfaceName')) chassis_id_raw = napalm_base.helpers.find_txt(neighbor, 'ChassisID') chassis_id = napalm_base.helpers.convert( napalm_base.helpers.mac, chassis_id_raw, chassis_id_raw) port_id = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(neighbor, 'PortIDDetail')) port_descr = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(neighbor, 'Detail/PortDescription')) system_name = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(neighbor, 'Detail/SystemName')) system_descr = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(neighbor, 'Detail/SystemDescription')) system_capabilities = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(neighbor, 'Detail/SystemCapabilities')) enabled_capabilities = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(neighbor, 'Detail/EnabledCapabilities')) if interface_name not in lldp_neighbors.keys(): lldp_neighbors[interface_name] = [] lldp_neighbors[interface_name].append({ 'parent_interface': parent_interface, 'remote_chassis_id': chassis_id, 'remote_port': port_id, 'remote_port_description': port_descr, 'remote_system_name': system_name, 'remote_system_description': system_descr, 'remote_system_capab': system_capabilities, 'remote_system_enable_capab': enabled_capabilities }) return lldp_neighbors def cli(self, commands): cli_output = {} if type(commands) is not list: raise TypeError('Please enter a valid list of commands!') for command in commands: try: cli_output[text_type(command)] = text_type(self.device._execute_show(command)) except TimeoutError: cli_output[text_type(command)] = 'Execution of command \ "{command}" took too long! Please adjust your params!'.format(command=command) raise CommandTimeoutException(str(cli_output)) return cli_output def get_bgp_config(self, group='', neighbor=''): bgp_config = {} # a helper def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): prefix_limit = {} inet = False inet6 = False preifx_type = 'inet' if 'ipv4' in af_table.lower(): inet = True if 'ipv6' in af_table.lower(): inet6 = True preifx_type = 'inet6' if inet or inet6: prefix_limit = { preifx_type: { af_table[4:].lower(): { 'limit': limit, 'teardown': { 'threshold': prefix_percent, 'timeout': prefix_timeout } } } } return prefix_limit # here begins actual method... rpc_command = '\ default' result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) if not group: neighbor = '' bgp_group_neighbors = {} for bgp_neighbor in result_tree.xpath('.//Neighbor'): group_name = napalm_base.helpers.find_txt(bgp_neighbor, 'NeighborGroupAddMember') peer = napalm_base.helpers.ip( napalm_base.helpers.find_txt(bgp_neighbor, 'Naming/NeighborAddress/IPV4Address') or napalm_base.helpers.find_txt(bgp_neighbor, 'Naming/NeighborAddress/IPV6Address') ) if neighbor and peer != neighbor: continue description = napalm_base.helpers.find_txt(bgp_neighbor, 'Description') peer_as = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(bgp_neighbor, 'RemoteAS/AS_YY'), 0) local_as = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(bgp_neighbor, 'LocalAS/AS_YY'), 0) af_table = napalm_base.helpers.find_txt( bgp_neighbor, 'NeighborAFTable/NeighborAF/Naming/AFName') prefix_limit = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(bgp_neighbor, 'NeighborAFTable/NeighborAF/MaximumPrefixes/PrefixLimit'), 0) prefix_percent = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(bgp_neighbor, 'NeighborAFTable/NeighborAF/MaximumPrefixes/WarningPercentage'), 0) prefix_timeout = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(bgp_neighbor, 'NeighborAFTable/NeighborAF/MaximumPrefixes/RestartTime'), 0) import_policy = napalm_base.helpers.find_txt( bgp_neighbor, 'NeighborAFTable/NeighborAF/RoutePolicyIn') export_policy = napalm_base.helpers.find_txt( bgp_neighbor, 'NeighborAFTable/NeighborAF/RoutePolicyOut') local_addr_raw = (napalm_base.helpers.find_txt(bgp_neighbor, 'LocalAddress/LocalIPAddress/IPV4Address') or napalm_base.helpers.find_txt(bgp_neighbor, 'LocalAddress/LocalIPAddress/IPV6Address')) local_address = napalm_base.helpers.convert(napalm_base.helpers.ip, local_addr_raw, local_addr_raw) password = napalm_base.helpers.find_txt(bgp_neighbor, 'Password/Password/Password') nhs = False route_reflector = False if group_name not in bgp_group_neighbors.keys(): bgp_group_neighbors[group_name] = {} bgp_group_neighbors[group_name][peer] = { 'description': description, 'remote_as': peer_as, 'prefix_limit': build_prefix_limit( af_table, prefix_limit, prefix_percent, prefix_timeout), 'export_policy': export_policy, 'import_policy': import_policy, 'local_address': local_address, 'local_as': local_as, 'authentication_key': password, 'nhs': nhs, 'route_reflector_client': route_reflector } if neighbor and peer == neighbor: break for bgp_group in result_tree.xpath('.//NeighborGroup'): group_name = napalm_base.helpers.find_txt(bgp_group, 'Naming/NeighborGroupName') if group and group != group_name: continue bgp_type = 'external' # by default external # must check description = napalm_base.helpers.find_txt(bgp_group, 'Description') import_policy = napalm_base.helpers.find_txt( bgp_group, 'NeighborGroupAFTable/NeighborGroupAF/RoutePolicyIn') export_policy = napalm_base.helpers.find_txt( bgp_group, 'NeighborGroupAFTable/NeighborGroupAF/RoutePolicyOut') multipath = napalm_base.helpers.find_txt( bgp_group, 'NeighborGroupAFTable/NeighborGroupAF/Multipath') == 'true' peer_as = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(bgp_group, 'RemoteAS/AS_YY'), 0) local_as = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(bgp_group, 'LocalAS/AS_YY'), 0) multihop_ttl = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(bgp_group, 'EBGPMultihop/MaxHopCount'), 0) local_addr_raw = (napalm_base.helpers.find_txt( bgp_group, 'LocalAddress/LocalIPAddress/IPV4Address') or napalm_base.helpers.find_txt( bgp_group, 'LocalAddress/LocalIPAddress/IPV6Address')) local_address = napalm_base.helpers.convert( napalm_base.helpers.ip, local_addr_raw, local_addr_raw) af_table = napalm_base.helpers.find_txt( bgp_group, 'NeighborAFTable/NeighborAF/Naming/AFName') prefix_limit = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt( bgp_group, 'NeighborGroupAFTable/NeighborGroupAF/MaximumPrefixes/PrefixLimit'), 0) prefix_percent = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(bgp_group, 'NeighborGroupAFTable/NeighborGroupAF/MaximumPrefixes/WarningPercentage'), 0) prefix_timeout = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(bgp_group, 'NeighborGroupAFTable/NeighborGroupAF/MaximumPrefixes/RestartTime'), 0) remove_private = True # is it specified in the XML? bgp_config[group_name] = { 'apply_groups': [], # on IOS-XR will always be empty list! 'description': description, 'local_as': local_as, 'type': text_type(bgp_type), 'import_policy': import_policy, 'export_policy': export_policy, 'local_address': local_address, 'multipath': multipath, 'multihop_ttl': multihop_ttl, 'remote_as': peer_as, 'remove_private_as': remove_private, 'prefix_limit': build_prefix_limit( af_table, prefix_limit, prefix_percent, prefix_timeout), 'neighbors': bgp_group_neighbors.get(group_name, {}) } if group and group == group_name: break if '' in bgp_group_neighbors.keys(): bgp_config['_'] = { 'apply_groups': [], 'description': '', 'local_as': 0, 'type': '', 'import_policy': '', 'export_policy': '', 'local_address': '', 'multipath': False, 'multihop_ttl': 0, 'remote_as': 0, 'remove_private_as': False, 'prefix_limit': {}, 'neighbors': bgp_group_neighbors.get('', {}) } return bgp_config def get_bgp_neighbors_detail(self, neighbor_address=''): bgp_neighbors_detail = {} active_vrfs = ['default'] active_vrfs_rpc_request = '\ default\ ' active_vrfs_rpc_reply = ETREE.fromstring( self.device.make_rpc_call(active_vrfs_rpc_request)) active_vrfs_tree = active_vrfs_rpc_reply.xpath('.//ConfigVRF') for active_vrf_tree in active_vrfs_tree: active_vrfs.append(napalm_base.helpers.find_txt(active_vrf_tree, 'Naming/VRFName')) unique_active_vrfs = sorted(set(active_vrfs)) bgp_neighbors_vrf_all_rpc = '\ default' for active_vrf in unique_active_vrfs: vrf_rpc = '{vrf_name}\ ' bgp_neighbors_vrf_all_rpc += vrf_rpc.format(vrf_name=active_vrf) bgp_neighbors_vrf_all_rpc += '' bgp_neighbors_vrf_all_tree = ETREE.fromstring( self.device.make_rpc_call(bgp_neighbors_vrf_all_rpc)) _BGP_STATE_ = { '0': 'Unknown', '1': 'Idle', '2': 'Connect', '3': 'OpenSent', '4': 'OpenConfirm', '5': 'Active', '6': 'Established' } instance_active_list = bgp_neighbors_vrf_all_tree.xpath( './/InstanceTable/Instance/InstanceActive/VRFTable/VRF') for vrf_tree in instance_active_list: vrf_name = napalm_base.helpers.find_txt(vrf_tree, 'Naming/VRFName') vrf_keepalive = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt( instance_active_list, 'GlobalProcessInfo/VRF/KeepAliveTime')) vrf_holdtime = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt( instance_active_list, 'GlobalProcessInfo/VRF/HoldTime')) if vrf_name not in bgp_neighbors_detail.keys(): bgp_neighbors_detail[vrf_name] = {} for neighbor in vrf_tree.xpath('NeighborTable/Neighbor'): up = (napalm_base.helpers.find_txt(neighbor, 'ConnectionState') == 'BGP_ST_ESTAB') local_as = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'LocalAS'), 0) remote_as = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'RemoteAS'), 0) router_id = napalm_base.helpers.ip( napalm_base.helpers.find_txt(neighbor, 'RouterID')) remote_address = napalm_base.helpers.ip( napalm_base.helpers.find_txt(neighbor, 'Naming/NeighborAddress/IPV4Address') or napalm_base.helpers.find_txt(neighbor, 'Naming/NeighborAddress/IPV6Address') ) local_address_configured = napalm_base.helpers.find_txt( neighbor, 'IsLocalAddressConfigured') == 'true' local_address = napalm_base.helpers.ip( napalm_base.helpers.find_txt(neighbor, 'ConnectionLocalAddress/IPV4Address') or napalm_base.helpers.find_txt(neighbor, 'ConnectionLocalAddress/IPV6Address') ) local_port = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'ConnectionLocalPort')) remote_address = napalm_base.helpers.ip( napalm_base.helpers.find_txt(neighbor, 'ConnectionRemoteAddress/IPV4Address') or napalm_base.helpers.find_txt(neighbor, 'ConnectionRemoteAddress/IPV6Address') ) remote_port = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'ConnectionRemotePort')) multihop = napalm_base.helpers.find_txt( neighbor, 'IsExternalNeighborNotDirectlyConnected') == 'true' remove_private_as = napalm_base.helpers.find_txt( neighbor, 'AFData/Entry/RemovePrivateASFromUpdates') == 'true' multipath = napalm_base.helpers.find_txt( neighbor, 'AFData/Entry/SelectiveMultipathEligible') == 'true' import_policy = napalm_base.helpers.find_txt( neighbor, 'AFData/Entry/RoutePolicyIn') export_policy = napalm_base.helpers.find_txt( neighbor, 'AFData/Entry/RoutePolicyOut') input_messages = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'MessgesReceived'), 0) output_messages = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'MessagesSent'), 0) connection_down_count = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'ConnectionDownCount'), 0) messages_queued_out = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'MessagesQueuedOut'), 0) connection_state = napalm_base.helpers.find_txt( neighbor, 'ConnectionState').replace('BGP_ST_', '').title() if connection_state == u'Estab': connection_state = u'Established' previous_connection_state = napalm_base.helpers.convert( text_type, _BGP_STATE_.get(napalm_base.helpers.find_txt( neighbor, 'PreviousConnectionState', '0'))) active_prefix_count = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt( neighbor, 'AFData/Entry/NumberOfBestpaths'), 0) accepted_prefix_count = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt( neighbor, 'AFData/Entry/PrefixesAccepted'), 0) suppressed_prefix_count = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'AFData/Entry/PrefixesDenied'), 0) received_prefix_count = accepted_prefix_count + suppressed_prefix_count advertised_prefix_count = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt( neighbor, 'AFData/Entry/PrefixesAdvertised'), 0) suppress_4byte_as = napalm_base.helpers.find_txt( neighbor, 'Suppress4ByteAs') == 'true' local_as_prepend = napalm_base.helpers.find_txt( neighbor, 'LocalASNoPrepend') != 'true' holdtime = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'HoldTime'), 0) or vrf_holdtime configured_holdtime = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'ConfiguredHoldTime'), 0) keepalive = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'KeepAliveTime'), 0) \ or vrf_keepalive configured_keepalive = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(neighbor, 'ConfiguredKeepalive'), 0) flap_count = int(connection_down_count / 2) if up: flap_count -= 1 if remote_as not in bgp_neighbors_detail[vrf_name].keys(): bgp_neighbors_detail[vrf_name][remote_as] = [] bgp_neighbors_detail[vrf_name][remote_as].append({ 'up': up, 'local_as': local_as, 'remote_as': remote_as, 'router_id': router_id, 'local_address': local_address, 'routing_table': vrf_name, 'local_address_configured': local_address_configured, 'local_port': local_port, 'remote_address': remote_address, 'remote_port': remote_port, 'multihop': multihop, 'multipath': multipath, 'import_policy': import_policy, 'export_policy': export_policy, 'input_messages': input_messages, 'output_messages': output_messages, 'input_updates': 0, 'output_updates': 0, 'messages_queued_out': messages_queued_out, 'connection_state': connection_state, 'previous_connection_state': previous_connection_state, 'last_event': u'', 'remove_private_as': remove_private_as, 'suppress_4byte_as': suppress_4byte_as, 'local_as_prepend': local_as_prepend, 'holdtime': holdtime, 'configured_holdtime': configured_holdtime, 'keepalive': keepalive, 'configured_keepalive': configured_keepalive, 'active_prefix_count': active_prefix_count, 'received_prefix_count': received_prefix_count, 'accepted_prefix_count': accepted_prefix_count, 'suppressed_prefix_count': suppressed_prefix_count, 'advertised_prefix_count': advertised_prefix_count, 'flap_count': flap_count }) bgp_neighbors_detail['global'] = bgp_neighbors_detail.pop('default') return bgp_neighbors_detail def get_arp_table(self): arp_table = [] rpc_command = '' result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) for arp_entry in result_tree.xpath('.//EntryTable/Entry'): interface = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(arp_entry, './/InterfaceName')) ip = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(arp_entry, './/Address')) age = napalm_base.helpers.convert(float, napalm_base.helpers.find_txt(arp_entry, './/Age'), 0.0) mac_raw = napalm_base.helpers.find_txt(arp_entry, './/HardwareAddress') arp_table.append( { 'interface': interface, 'mac': napalm_base.helpers.mac(mac_raw), 'ip': napalm_base.helpers.ip(ip), 'age': age } ) return arp_table def get_ntp_peers(self): ntp_peers = {} rpc_command = '' result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) for version in ['IPV4', 'IPV6']: xpath = './/Peer{version}Table/Peer{version}'.format(version=version) for peer in result_tree.xpath(xpath): peer_type = napalm_base.helpers.find_txt( peer, 'PeerType{version}/Naming/PeerType'.format(version=version)) if peer_type != 'Peer': continue peer_address = napalm_base.helpers.find_txt( peer, 'Naming/Address{version}'.format(version=version)) if not peer_address: continue ntp_peers[peer_address] = {} return ntp_peers def get_ntp_servers(self): ntp_servers = {} rpc_command = '' result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) for version in ['IPV4', 'IPV6']: xpath = './/Peer{version}Table/Peer{version}'.format(version=version) for peer in result_tree.xpath(xpath): peer_type = napalm_base.helpers.find_txt( peer, 'PeerType{version}/Naming/PeerType'.format(version=version)) if peer_type != 'Server': continue server_address = napalm_base.helpers.find_txt( peer, 'Naming/Address{version}'.format(version=version)) if not server_address: continue ntp_servers[server_address] = {} return ntp_servers def get_ntp_stats(self): ntp_stats = [] rpc_command = '' result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) xpath = './/NodeTable/Node/Associations/PeerSummaryInfo/Entry/PeerInfoCommon' for node in result_tree.xpath(xpath): synchronized = napalm_base.helpers.find_txt(node, 'IsSysPeer') == 'true' address = napalm_base.helpers.find_txt(node, 'Address') if address == 'DLRSC node': continue referenceid = napalm_base.helpers.find_txt(node, 'ReferenceID') hostpoll = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(node, 'HostPoll', '0')) reachability = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(node, 'Reachability', '0')) stratum = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(node, 'Stratum', '0')) delay = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(node, 'Delay', '0.0')) offset = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(node, 'Offset', '0.0')) jitter = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(node, 'Dispersion', '0.0')) ntp_stats.append({ 'remote': address, 'synchronized': synchronized, 'referenceid': referenceid, 'stratum': stratum, 'type': u'', 'when': u'', 'hostpoll': hostpoll, 'reachability': reachability, 'delay': delay, 'offset': offset, 'jitter': jitter }) return ntp_stats def get_interfaces_ip(self): interfaces_ip = {} rpc_command_ipv4_ipv6 = '\ ' # only one request ipv4_ipv6_tree = ETREE.fromstring( self.device.make_rpc_call(rpc_command_ipv4_ipv6)) # parsing IPv4 ipv4_xpath = './/IPV4Network/InterfaceTable/Interface' for interface in ipv4_ipv6_tree.xpath(ipv4_xpath): interface_name = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(interface, 'Naming/InterfaceName')) primary_ip = napalm_base.helpers.ip(napalm_base.helpers.find_txt( interface, 'VRFTable/VRF/Detail/PrimaryAddress')) primary_prefix = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(interface, 'VRFTable/VRF/Detail/PrefixLength')) if interface_name not in interfaces_ip.keys(): interfaces_ip[interface_name] = {} if u'ipv4' not in interfaces_ip[interface_name].keys(): interfaces_ip[interface_name][u'ipv4'] = {} if primary_ip not in interfaces_ip[interface_name].get(u'ipv4', {}).keys(): interfaces_ip[interface_name][u'ipv4'][primary_ip] = { u'prefix_length': primary_prefix } for secondary_address in interface.xpath('VRFTable/VRF/Detail/SecondaryAddress/Entry'): secondary_ip = napalm_base.helpers.ip( napalm_base.helpers.find_txt(secondary_address, 'Address')) secondary_prefix = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(secondary_address, 'PrefixLength')) if secondary_ip not in interfaces_ip[interface_name]: interfaces_ip[interface_name][u'ipv4'][secondary_ip] = { u'prefix_length': secondary_prefix } # parsing IPv6 ipv6_xpath = ( './/IPV6Network/NodeTable/Node/InterfaceData' '/VRFTable/VRF/GlobalDetailTable/GlobalDetail' ) for interface in ipv4_ipv6_tree.xpath(ipv6_xpath): interface_name = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(interface, 'Naming/InterfaceName')) if interface_name not in interfaces_ip.keys(): interfaces_ip[interface_name] = {} if u'ipv6' not in interfaces_ip[interface_name].keys(): interfaces_ip[interface_name][u'ipv6'] = {} for address in interface.xpath('AddressList/Entry'): address_ip = napalm_base.helpers.ip( napalm_base.helpers.find_txt(address, 'Address')) address_prefix = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(address, 'PrefixLength')) if address_ip not in interfaces_ip[interface_name].get(u'ipv6', {}).keys(): interfaces_ip[interface_name][u'ipv6'][address_ip] = { u'prefix_length': address_prefix } return interfaces_ip def get_mac_address_table(self): mac_table = [] rpc_command = '' result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) for mac_entry in result_tree.xpath('.//L2FIBMACDetailTable/L2FIBMACDetail'): mac_raw = napalm_base.helpers.find_txt(mac_entry, 'Naming/Address') vlan = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt( mac_entry, 'Naming/Name', '').replace('vlan', ''), 0) interface = napalm_base.helpers.find_txt( mac_entry, 'Segment/AC/InterfaceHandle', u'') mac_table.append({ 'mac': napalm_base.helpers.mac(mac_raw), 'interface': interface, 'vlan': vlan, 'active': True, 'static': False, 'moves': 0, 'last_move': 0.0 }) return mac_table def get_route_to(self, destination='', protocol=''): routes = {} if not isinstance(destination, py23_compat.string_types): raise TypeError('Please specify a valid destination!') protocol = protocol.lower() if protocol == 'direct': protocol = 'connected' dest_split = destination.split('/') network = dest_split[0] prefix_tag = '' if len(dest_split) == 2: prefix_tag = '{prefix_length}'.format( prefix_length=dest_split[1]) ipv = 4 try: ipv = IPAddress(network).version except AddrFormatError: raise TypeError('Wrong destination IP Address!') if ipv == 6: route_info_rpc_command = '\ defaultIPv6\ Unicast\ default
\ {network}
{prefix}
\
\
'.format(network=network, prefix=prefix_tag) else: route_info_rpc_command = 'default\ IPv4\ Unicast\ default
\ {network}
{prefix}
\
'.format( network=network, prefix=prefix_tag ) routes_tree = ETREE.fromstring(self.device.make_rpc_call(route_info_rpc_command)) for route in routes_tree.xpath('.//Route'): route_protocol = napalm_base.helpers.convert( text_type, napalm_base.helpers.find_txt(route, 'ProtocolName').lower()) if protocol and route_protocol != protocol: continue # ignore routes learned via a different protocol # only in case the user requested a certain protocol route_details = {} address = napalm_base.helpers.find_txt(route, 'Prefix') length = napalm_base.helpers.find_txt(route, 'PrefixLength') priority = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(route, 'Priority')) age = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(route, 'RouteAge')) destination = napalm_base.helpers.convert( text_type, '{prefix}/{length}'.format( prefix=address, length=length ) ) if destination not in routes.keys(): routes[destination] = [] route_details = { 'current_active': False, 'last_active': False, 'age': age, 'next_hop': u'', 'protocol': route_protocol, 'outgoing_interface': u'', 'preference': priority, 'selected_next_hop': False, 'inactive_reason': u'', 'routing_table': u'default', 'protocol_attributes': {} } # from BGP will try to get some more information if route_protocol == 'bgp' and C.SR_638170159_SOLVED: # looks like IOS-XR does not filter correctly # !IMPORTANT bgp_route_info_rpc_command = '\ IPv4Unicast\ {network}{prefix_len}\ \ '.format( network=network, prefix_len=dest_split[-1] ) bgp_route_tree = ETREE.fromstring( self.device.make_rpc_call(bgp_route_info_rpc_command)) for bgp_path in bgp_route_tree.xpath('.//Path'): single_route_details = route_details.copy() if 'NotFound' not in bgp_path.keys(): best_path = napalm_base.helpers.find_txt( bgp_path, 'PathInformation/IsBestPath') == 'true' local_preference = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt( bgp_path, 'AttributesAfterPolicyIn/CommonAttributes/LocalPreference' ), 0 ) local_preference = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt( bgp_path, 'AttributesAfterPolicyIn/CommonAttributes/LocalPreference', ), 0 ) remote_as = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt( bgp_path, 'AttributesAfterPolicyIn/CommonAttributes/NeighborAS', ), 0 ) remote_address = napalm_base.helpers.ip( napalm_base.helpers.find_txt( bgp_path, 'PathInformation/NeighborAddress/IPV4Address') or napalm_base.helpers.find_txt( bgp_path, 'PathInformation/NeighborAddress/IPV6Address') ) as_path = ' '.join( [ bgp_as.text for bgp_as in bgp_path.xpath( 'AttributesAfterPolicyIn/CommonAttributes/NeighborAS/Entry') ] ) next_hop = napalm_base.helpers.find_txt( bgp_path, 'PathInformation/NextHop/IPV4Address') \ or napalm_base.helpers.find_txt( bgp_path, 'PathInformation/NextHop/IPV6Address') single_route_details['current_active'] = best_path single_route_details['next_hop'] = next_hop single_route_details['protocol_attributes'] = { 'local_preference': local_preference, 'as_path': as_path, 'remote_as': remote_as, 'remote_address': remote_address } routes[destination].append(single_route_details) else: first_route = True for route_entry in route.xpath('RoutePath/Entry'): # get all possible entries next_hop = napalm_base.helpers.find_txt(route_entry, 'Address') single_route_details = {} single_route_details.update(route_details) single_route_details.update({ 'current_active': first_route, 'next_hop': next_hop }) routes[destination].append(single_route_details) first_route = False return routes def get_snmp_information(self): snmp_information = {} snmp_rpc_command = '' snmp_result_tree = ETREE.fromstring(self.device.make_rpc_call(snmp_rpc_command)) _PRIVILEGE_MODE_MAP_ = { 'ReadOnly': u'ro', 'ReadWrite': u'rw' } snmp_information = { 'chassis_id': napalm_base.helpers.find_txt(snmp_result_tree, './/ChassisID'), 'contact': napalm_base.helpers.find_txt(snmp_result_tree, './/Contact'), 'location': napalm_base.helpers.find_txt(snmp_result_tree, './/Location'), 'community': {} } for community in snmp_result_tree.xpath('.//DefaultCommunity'): name = napalm_base.helpers.find_txt(community, 'Naming/CommunityName') privilege = napalm_base.helpers.find_txt(community, 'Priviledge') acl = napalm_base.helpers.find_txt(community, 'AccessList') snmp_information['community'][name] = { 'mode': _PRIVILEGE_MODE_MAP_.get(privilege, u''), 'acl': acl } return snmp_information def get_probes_config(self): sla_config = {} _PROBE_TYPE_XML_TAG_MAP_ = { 'ICMPEcho': u'icmp-ping', 'UDPEcho': u'udp-ping', 'ICMPJitter': u'icmp-ping-timestamp', 'UDPJitter': u'udp-ping-timestamp' } sla_config_rpc_command = '' sla_config_result_tree = ETREE.fromstring( self.device.make_rpc_call(sla_config_rpc_command)) for probe in sla_config_result_tree.xpath('.//Definition'): probe_name = napalm_base.helpers.find_txt(probe, 'Naming/OperationID') operation_type = probe.xpath('OperationType')[0].getchildren()[0].tag probe_type = _PROBE_TYPE_XML_TAG_MAP_.get(operation_type, u'') operation_xpath = 'OperationType/{op_type}'.format(op_type=operation_type) operation = probe.xpath(operation_xpath)[0] test_name = napalm_base.helpers.find_txt(operation, 'Tag') source = napalm_base.helpers.find_txt(operation, 'SourceAddress') target = napalm_base.helpers.find_txt(operation, 'DestAddress') test_interval = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(operation, 'Frequency', '0')) probe_count = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(operation, 'History/Buckets', '0')) if probe_name not in sla_config.keys(): sla_config[probe_name] = {} if test_name not in sla_config[probe_name]: sla_config[probe_name][test_name] = {} sla_config[probe_name][test_name] = { 'probe_type': probe_type, 'source': source, 'target': target, 'probe_count': probe_count, 'test_interval': test_interval } return sla_config def get_probes_results(self): sla_results = {} _PROBE_TYPE_XML_TAG_MAP_ = { 'ICMPEcho': u'icmp-ping', 'UDPEcho': u'udp-ping', 'ICMPJitter': u'icmp-ping-timestamp', 'UDPJitter': u'udp-ping-timestamp' } sla_results_rpc_command = '' sla_results_tree = ETREE.fromstring( self.device.make_rpc_call(sla_results_rpc_command)) probes_config = self.get_probes_config() # need to retrieve also the configuration # source and tag/test_name not provided for probe in sla_results_tree.xpath('.//Operation'): probe_name = napalm_base.helpers.find_txt(probe, 'Naming/OperationID') test_name = list(probes_config.get(probe_name).keys())[0] target = napalm_base.helpers.find_txt( probe, 'History/Target/LifeTable/Life/BucketTable/Bucket[0]/TargetAddress\ /IPv4AddressTarget') source = probes_config.get(probe_name).get(test_name, {}).get('source', '') probe_type = _PROBE_TYPE_XML_TAG_MAP_.get(napalm_base.helpers.find_txt( probe, 'Statistics/Latest/Target/SpecificStats/op_type')) probe_count = probes_config.get(probe_name).get(test_name, {}).get('probe_count', 0) response_times = probe.xpath( 'History/Target/LifeTable/Life[last()]/BucketTable/Bucket/ResponseTime') response_times = [ napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(response_time, '.', '0')) for response_time in response_times ] rtt = 0.0 if len(response_times): rtt = sum(response_times, 0.0)/len(response_times) return_codes = probe.xpath( 'History/Target/LifeTable/Life[last()]/BucketTable/Bucket/ReturnCode') return_codes = [ napalm_base.helpers.find_txt(return_code, '.') for return_code in return_codes ] last_test_loss = 0.0 if len(return_codes): last_test_loss = napalm_base.helpers.convert( int, 100*(1-return_codes.count('ipslaRetCodeOK')/napalm_base.helpers.convert( float, len(return_codes)))) rms = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(probe, 'Statistics/Aggregated/HourTable/Hour\ /Distributed/Target/DistributionIntervalTable/DistributionInterval/CommonStats\ /Sum2ResponseTime')) global_test_updates = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(probe, 'Statistics/Aggregated/HourTable/Hour\ /Distributed/Target/DistributionIntervalTable/DistributionInterval/CommonStats\ /UpdateCount')) jitter = 0.0 if global_test_updates: jitter = rtt-(rms/global_test_updates)**0.5 # jitter = max(rtt - max(response_times), rtt - min(response_times)) current_test_min_delay = 0.0 # no stats for undergoing test :( current_test_max_delay = 0.0 current_test_avg_delay = 0.0 last_test_min_delay = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(probe, 'Statistics/Latest/Target/CommonStats/MinResponseTime')) last_test_max_delay = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(probe, 'Statistics/Latest/Target/CommonStats/MaxResponseTime')) last_test_sum_delay = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(probe, 'Statistics/Latest/Target/CommonStats/SumResponseTime')) last_test_updates = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(probe, 'Statistics/Latest/Target/CommonStats/UpdateCount')) last_test_avg_delay = 0.0 if last_test_updates: last_test_avg_delay = last_test_sum_delay/last_test_updates global_test_min_delay = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(probe, 'Statistics/Aggregated/HourTable/Hour/Distributed/Target\ /DistributionIntervalTable/DistributionInterval/CommonStats/MinResponseTime')) global_test_max_delay = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(probe, 'Statistics/Aggregated/HourTable/Hour/Distributed/Target\ /DistributionIntervalTable/DistributionInterval/CommonStats/MaxResponseTime')) global_test_sum_delay = napalm_base.helpers.convert( float, napalm_base.helpers.find_txt(probe, 'Statistics/Aggregated/HourTable/Hour\ /Distributed/Target/DistributionIntervalTable/DistributionInterval\ /CommonStats/SumResponseTime')) global_test_avg_delay = 0.0 if global_test_updates: global_test_avg_delay = global_test_sum_delay/global_test_updates if probe_name not in sla_results.keys(): sla_results[probe_name] = {} sla_results[probe_name][test_name] = { 'target': target, 'source': source, 'probe_type': probe_type, 'probe_count': probe_count, 'rtt': rtt, 'round_trip_jitter': jitter, 'last_test_loss': last_test_loss, 'current_test_min_delay': current_test_min_delay, 'current_test_max_delay': current_test_max_delay, 'current_test_avg_delay': current_test_avg_delay, 'last_test_min_delay': last_test_min_delay, 'last_test_max_delay': last_test_max_delay, 'last_test_avg_delay': last_test_avg_delay, 'global_test_min_delay': global_test_min_delay, 'global_test_max_delay': global_test_max_delay, 'global_test_avg_delay': global_test_avg_delay } return sla_results def traceroute(self, destination, source=C.TRACEROUTE_SOURCE, ttl=C.TRACEROUTE_TTL, timeout=C.TRACEROUTE_TIMEOUT, vrf=C.TRACEROUTE_VRF): traceroute_result = {} ipv = 4 try: ipv = IPAddress(destination).version except AddrFormatError: return {'error': 'Wrong destination IP Address!'} source_tag = '' ttl_tag = '' timeout_tag = '' vrf_tag = '' if source: source_tag = '{source}'.format(source=source) if ttl: ttl_tag = '{maxttl}'.format(maxttl=ttl) if timeout: timeout_tag = '{timeout}'.format(timeout=timeout) if vrf: vrf_tag = '{vrf}'.format(vrf=vrf) traceroute_rpc_command = '{destination}\ {vrf_tag}{source_tag}{ttl_tag}{timeout_tag}\ '.format( version=ipv, destination=destination, vrf_tag=vrf_tag, source_tag=source_tag, ttl_tag=ttl_tag, timeout_tag=timeout_tag ) xml_tree_txt = self.device.make_rpc_call(traceroute_rpc_command) traceroute_tree = ETREE.fromstring(xml_tree_txt) results_tree = traceroute_tree.xpath('.//Results') if results_tree is None or not len(results_tree): return {'error': 'Device returned empty results.'} results_error = napalm_base.helpers.find_txt(results_tree[0], 'Error') if results_error: return {'error': results_error} traceroute_result['success'] = {} last_hop_index = 1 last_probe_index = 1 last_probe_ip_address = '*' last_probe_host_name = '' last_hop_dict = {'probes': {}} for thanks_cisco in results_tree[0].getchildren(): tag_name = thanks_cisco.tag tag_value = thanks_cisco.text if tag_name == 'HopIndex': new_hop_index = napalm_base.helpers.convert( int, napalm_base.helpers.find_txt(thanks_cisco, '.', '-1')) if last_hop_index and last_hop_index != new_hop_index: traceroute_result['success'][last_hop_index] = copy.deepcopy(last_hop_dict) last_hop_dict = {'probes': {}} last_probe_ip_address = '*' last_probe_host_name = '' last_hop_index = new_hop_index continue tag_value = napalm_base.helpers.find_txt(thanks_cisco, '.', '') if tag_name == 'ProbeIndex': last_probe_index = napalm_base.helpers.convert(int, tag_value, 0) + 1 if last_probe_index not in last_hop_dict.get('probes').keys(): last_hop_dict['probes'][last_probe_index] = {} if not last_probe_host_name: last_probe_host_name = last_probe_ip_address last_hop_dict['probes'][last_probe_index] = { 'ip_address': napalm_base.helpers.convert( text_type, last_probe_ip_address), 'host_name': napalm_base.helpers.convert( text_type, last_probe_host_name), 'rtt': timeout * 1000.0 } continue if tag_name == 'HopAddress': last_probe_ip_address = tag_value continue if tag_name == 'HopHostName': last_probe_host_name = tag_value continue if tag_name == 'DeltaTime': last_hop_dict['probes'][last_probe_index]['rtt'] = napalm_base.helpers.convert( float, tag_value, 0.0) continue if last_hop_index: traceroute_result['success'][last_hop_index] = last_hop_dict return traceroute_result def get_users(self): users = {} _CISCO_GROUP_TO_CISCO_PRIVILEGE_MAP = { 'root-system': 15, 'operator': 5, 'sysadmin': 1, 'serviceadmin': 1, 'root-lr': 15 } _DEFAULT_USER_DETAILS = { 'level': 0, 'password': '', 'sshkeys': [] } users_xml_req = '' users_xml_reply = ETREE.fromstring(self.device.make_rpc_call(users_xml_req)) for user_entry in users_xml_reply.xpath('.//Username'): username = napalm_base.helpers.find_txt(user_entry, 'Naming/Name') group = napalm_base.helpers.find_txt( user_entry, 'UsergroupsUnderUsername/UsergroupUnderUsername/Naming/Name') level = _CISCO_GROUP_TO_CISCO_PRIVILEGE_MAP.get(group, 0) password = napalm_base.helpers.find_txt(user_entry, 'Password/Password') user_details = _DEFAULT_USER_DETAILS.copy() user_details.update({ 'level': level, 'password': py23_compat.text_type(password) }) users[username] = user_details return users def get_config(self, retrieve='all'): config = { 'startup': '', 'running': '', 'candidate': '' } # default values if retrieve.lower() in ['running', 'all']: config['running'] = py23_compat.text_type( self.device._execute_config_show('show running-config')) if retrieve.lower() in ['candidate', 'all']: config['candidate'] = py23_compat.text_type( self.device._execute_config_show('show configuration merge')) return config napalm-iosxr-0.5.6/napalm_iosxr.egg-info/0000755000372000037200000000000013173641204021163 5ustar travistravis00000000000000napalm-iosxr-0.5.6/napalm_iosxr.egg-info/PKG-INFO0000644000372000037200000000101113173641203022250 0ustar travistravis00000000000000Metadata-Version: 1.1 Name: napalm-iosxr Version: 0.5.6 Summary: Network Automation and Programmability Abstraction Layer with Multivendor support Home-page: https://github.com/napalm-automation/napalm-iosxr Author: David Barroso, Mircea Ulinic Author-email: dbarrosop@dravetech.com, mircea@cloudflare.com License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN Classifier: Topic :: Utilities Classifier: Programming Language :: Python Classifier: Operating System :: POSIX :: Linux Classifier: Operating System :: MacOS napalm-iosxr-0.5.6/napalm_iosxr.egg-info/SOURCES.txt0000644000372000037200000000142113173641203023044 0ustar travistravis00000000000000MANIFEST.in requirements.txt setup.cfg setup.py napalm_iosxr/__init__.py napalm_iosxr/constants.py napalm_iosxr/iosxr.py napalm_iosxr.egg-info/PKG-INFO napalm_iosxr.egg-info/SOURCES.txt napalm_iosxr.egg-info/dependency_links.txt napalm_iosxr.egg-info/requires.txt napalm_iosxr.egg-info/top_level.txt napalm_iosxr/templates/delete_ntp_peers.j2 napalm_iosxr/templates/delete_ntp_servers.j2 napalm_iosxr/templates/delete_probes.j2 napalm_iosxr/templates/delete_snmp_config.j2 napalm_iosxr/templates/delete_users.j2 napalm_iosxr/templates/schedule_probes.j2 napalm_iosxr/templates/set_hostname.j2 napalm_iosxr/templates/set_ntp_peers.j2 napalm_iosxr/templates/set_ntp_servers.j2 napalm_iosxr/templates/set_probes.j2 napalm_iosxr/templates/set_users.j2 napalm_iosxr/templates/snmp_config.j2napalm-iosxr-0.5.6/napalm_iosxr.egg-info/dependency_links.txt0000644000372000037200000000000113173641203025230 0ustar travistravis00000000000000 napalm-iosxr-0.5.6/napalm_iosxr.egg-info/requires.txt0000644000372000037200000000006113173641203023557 0ustar travistravis00000000000000napalm-base>=0.25.0 pyIOSXR>=0.51 netmiko>=1.4.3 napalm-iosxr-0.5.6/napalm_iosxr.egg-info/top_level.txt0000644000372000037200000000001513173641203023710 0ustar travistravis00000000000000napalm_iosxr napalm-iosxr-0.5.6/MANIFEST.in0000644000372000037200000000007513173641107016537 0ustar travistravis00000000000000include requirements.txt include napalm_iosxr/templates/*.j2 napalm-iosxr-0.5.6/requirements.txt0000644000372000037200000000006113173641107020260 0ustar travistravis00000000000000napalm-base>=0.25.0 pyIOSXR>=0.51 netmiko>=1.4.3 napalm-iosxr-0.5.6/setup.cfg0000644000372000037200000000050113173641204016612 0ustar travistravis00000000000000[pylama] linters = mccabe,pep8,pyflakes ignore = D203,C901,E128 skip = .tox/* [pylama:pep8] max_line_length = 100 [tool:pytest] addopts = --cov=napalm_iosxr --cov-report term-missing -vs --pylama json_report = report.json jsonapi = true [coverage:run] include = napalm_iosxr/* [egg_info] tag_build = tag_date = 0 napalm-iosxr-0.5.6/setup.py0000644000372000037200000000162513173641107016515 0ustar travistravis00000000000000"""setup.py file.""" import uuid from setuptools import setup, find_packages from pip.req import parse_requirements __author__ = 'David Barroso ' install_reqs = parse_requirements('requirements.txt', session=uuid.uuid1()) reqs = [str(ir.req) for ir in install_reqs] setup( name="napalm-iosxr", version="0.5.6", packages=find_packages(exclude=["test", "test.*"]), author="David Barroso, Mircea Ulinic", author_email="dbarrosop@dravetech.com, mircea@cloudflare.com", description="Network Automation and Programmability Abstraction Layer with Multivendor support", classifiers=[ 'Topic :: Utilities', 'Programming Language :: Python', 'Operating System :: POSIX :: Linux', 'Operating System :: MacOS', ], url="https://github.com/napalm-automation/napalm-iosxr", include_package_data=True, install_requires=reqs, ) napalm-iosxr-0.5.6/PKG-INFO0000644000372000037200000000101113173641204016063 0ustar travistravis00000000000000Metadata-Version: 1.1 Name: napalm-iosxr Version: 0.5.6 Summary: Network Automation and Programmability Abstraction Layer with Multivendor support Home-page: https://github.com/napalm-automation/napalm-iosxr Author: David Barroso, Mircea Ulinic Author-email: dbarrosop@dravetech.com, mircea@cloudflare.com License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN Classifier: Topic :: Utilities Classifier: Programming Language :: Python Classifier: Operating System :: POSIX :: Linux Classifier: Operating System :: MacOS