示例#1
0
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
from getpass import getpass
from lxml import etree
from nxapi_plumbing import Device  # import device class
# Disable SSL cert warning we get as we're using self-signed cert
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# Create device object
device = Device(
    api_format="xml",
    host="nxos1.lasthop.io",
    username="******",
    password=getpass(),
    transport="https",
    port=8443,
    verify=False,  # Turn off SSL cert verification
)
# Config commands to send to the device
cmds = [
    'interface loopback 100', 'description nxapi test lo',
    'interface loopback 101', 'description nxapi test lo2'
]
# Send config commands list to the device
output = device.config_list(cmds)

# Loop through returned list of command output and print to the screen
for entry in output:
    print(etree.tostring(entry).decode())
    input('Press Enter to continue: ')
        intf_output.find(".//eth_mtu").text,
    )
)

# Exercise 7b
print("\n\n")
print("Capture and print XML output from multiple show commands")
print("-" * 20)
show_output = device.show_list(["show system uptime", "show system resources"])
for output in show_output:
    print(etree.tostring(output, encoding="unicode"))
    print("-" * 20)
print("\n\n")

# Exercise 7c
print()
print("Create two new loopbacks with descriptions")
print("-" * 20)
commands = [
    "interface loopback101",
    "description loopback101",
    "no shutdown",
    "interface loopback102",
    "description loopback102",
    "no shutdown",
]
output = device.config_list(commands)
# Look at the output XML for each configuration command
for msg in output:
    print(etree.tostring(msg, encoding="unicode"))
示例#3
0
device = Device(
    api_format="xml",
    host="nxos1.lasthop.io",
    username="******",
    password=getpass(),
    transport="https",
    port=8443,
    verify=False,
)

cmds = ["show hostname", "show version", "show lldp neighbors"]
output = device.show_list(cmds)
for entry in output:
    print(etree.tostring(entry).decode())
    input("Hit enter to continue: ")

cmds = ["show version"]
output = device.show_list(cmds, raw_text=True)
print(etree.tostring(output[0]).decode())

cfg_cmd = ["logging history size 200"]
output = device.config_list(cfg_cmd)
print(etree.tostring(output[0]).decode())

output = device.save()
print(output)

# output = device.checkpoint(filename="my_checkpoint2")
# print(output)
示例#4
0
if __name__ == "__main__":
    output = device.show("show interface Ethernet2/1")

    # Task a
    print("-" * 20)
    print("Interface Report : ")
    print("Interface : {0}, State : {1}, MTU : {2}".format(
        output.find(".//interface").text,
        output.find(".//admin_state").text,
        output.find(".//eth_mtu").text))

    # Task b
    list_cmds = ["show system uptime", "show system resources"]
    output = device.show_list(list_cmds)
    print("")
    print("-" * 20)
    print("System Report :")
    for element in output:
        bstring = etree.tostring(element)
        print(bstring.decode())

    # Task c
    list_cmds = [
        "interface loopback151", "description dev01",
        "ip address 10.111.222.254/32"
    ]
    output = device.config_list(list_cmds)
    bstring = etree.tostring(element)
    print(bstring.decode())
示例#5
0
               host="nxos1.lasthop.io",
               username="******",
               password=getpass(),
               transport="https",
               port=8443,
               verify=False)

output = nxos1.show("show interface Ethernet1/1")

# Exercise 7a
print("Interface: {}; State: {}; MTU: {}".format(
    output.find(".//interface").text,
    output.find(".//state").text,
    output.find(".//eth_mtu").text,
))

# Exercise 7b
cmds = ["show system uptime", "show system resources"]
output = nxos1.show_list(cmds)
for entry in output:
    print(etree.tostring(entry).decode())

# Exercise 7c

cfg_cmds = [
    "interface Loopback120", "description My loopback",
    "interface Loopback121", "description My loopback again"
]

output = nxos1.config_list(cfg_cmds)
示例#6
0
        interface_show.find(".//interface").text,
        interface_show.find(".//state").text,
        interface_show.find(".//eth_mtu").text))
    print("+=" * 30)

    # 7b
    show_commands_result = nxos1_conn.show_list(SHOW_COMMANDS)
    # print resut
    print("Result of show commands:")
    for command_result in show_commands_result:
        print(etree.tostring(command_result, encoding="unicode"))
    print("+=" * 30)

    # 7c
    print("Configuring Loopback interfaces")
    result = nxos1_conn.config_list(CONFIG_LOOPBACK)
    # print XML output of each command
    for output_message in result:
        print(etree.tostring(output_message, encoding="unicode"))
'''
In [11]: pprint(etree.tostring(interface_show).decode())
('<output>\n'
 '      <body>\n'
 '        <TABLE_interface>\n'
 '         <ROW_interface>\n'
 '          <interface>Ethernet1/1</interface>\n'
 '          <state>up</state>\n'
 '          <admin_state>up</admin_state>\n'
 '          <share_state>Dedicated</share_state>\n'
 '          <eth_hw_desc>100/1000/10000 Ethernet</eth_hw_desc>\n'
 '          <eth_hw_addr>000c.29d1.0001</eth_hw_addr>\n'
示例#7
0
MTU = my_xml.findall(".//eth_mtu")[0].text

print("\n")
pprint("Interface: {}; State: {}; MTU: {}".format(INT, STATE, MTU))
print("\n")

print("Exercise 7b - Run the following two show commands on the nxos1 device")
print("-" * 40)
cmd = ["show system uptime", "show system resources"]
for i in cmd:

    print(i)
    print("-" * 20)
    my_xml1 = device.show_list(i)
    print(my_xml1)
    STRING = etree.tostring(my_xml1[0]).decode()
    print(STRING)

print("Exercise 7c - Configure Loopbacks on the nxos1 device")
print("-" * 30)

cmd = [
    'interface Loopback 187', 'description Loopback187',
    'interface Loopback 189', 'description Loopback188'
]

my_xml2 = device.config_list(cmd)
print(my_xml2)
CONFIG = etree.tostring(my_xml2[0]).decode()
print(CONFIG)
示例#8
0
class NXOSDriver(NXOSDriverBase):
    def __init__(self, hostname, username, password, timeout=60, optional_args=None):
        super().__init__(hostname, username, password, timeout=timeout, optional_args=optional_args)
        if optional_args is None:
            optional_args = {}

        # nxos_protocol is there for backwards compatibility, transport is the preferred method
        self.transport = optional_args.get('transport', optional_args.get('nxos_protocol', 'https'))
        if self.transport == 'https':
            self.port = optional_args.get('port', 443)
        elif self.transport == 'http':
            self.port = optional_args.get('port', 80)

        self.ssl_verify = optional_args.get('ssl_verify', False)
        self.platform = 'nxos'

    def open(self):
        try:
            self.device = NXOSDevice(host=self.hostname,
                                     username=self.username,
                                     password=self.password,
                                     timeout=self.timeout,
                                     port=self.port,
                                     transport=self.transport,
                                     verify=self.ssl_verify,
                                     api_format="jsonrpc")
            self._send_command('show hostname')
        except (NXAPIConnectionError, NXAPIAuthError):
            # unable to open connection
            raise ConnectionException('Cannot connect to {}'.format(self.hostname))

    def close(self):
        self.device = None

    def _send_command(self, command, raw_text=False):
        """
        Wrapper for NX-API show method.

        Allows more code sharing between NX-API and SSH.
        """
        return self.device.show(command, raw_text=raw_text)

    def _send_command_list(self, commands):
        return self.device.config_list(commands)

    def _send_config(self, commands):
        if isinstance(commands, py23_compat.string_types):
            # Has to be a list generator and not generator expression (not JSON serializable)
            commands = [command for command in commands.splitlines() if command]
        return self.device.config_list(commands)

    @staticmethod
    def _compute_timestamp(stupid_cisco_output):
        """
        Some fields such `uptime` are returned as: 23week(s) 3day(s)
        This method will determine the epoch of the event.
        e.g.: 23week(s) 3day(s) -> 1462248287
        """
        if not stupid_cisco_output or stupid_cisco_output == 'never':
            return -1.0

        if '(s)' in stupid_cisco_output:
            pass
        elif ':' in stupid_cisco_output:
            stupid_cisco_output = stupid_cisco_output.replace(':', 'hour(s) ', 1)
            stupid_cisco_output = stupid_cisco_output.replace(':', 'minute(s) ', 1)
            stupid_cisco_output += 'second(s)'
        else:
            stupid_cisco_output = stupid_cisco_output.replace('d', 'day(s) ')
            stupid_cisco_output = stupid_cisco_output.replace('h', 'hour(s)')

        things = {
            'second(s)': {
                'weight': 1
            },
            'minute(s)': {
                'weight': 60
            },
            'hour(s)': {
                'weight': 3600
            },
            'day(s)': {
                'weight': 24 * 3600
            },
            'week(s)': {
                'weight': 7 * 24 * 3600
            },
            'year(s)': {
                'weight': 365.25 * 24 * 3600
            }
        }

        things_keys = things.keys()
        for part in stupid_cisco_output.split():
            for key in things_keys:
                if key in part:
                    things[key]['count'] = napalm.base.helpers.convert(
                        int, part.replace(key, ''), 0)

        delta = sum([det.get('count', 0) * det.get('weight') for det in things.values()])
        return time.time() - delta

    @staticmethod
    def _get_table_rows(parent_table, table_name, row_name):
        """
        Inconsistent behavior:
        {'TABLE_intf': [{'ROW_intf': {
        vs
        {'TABLE_mac_address': {'ROW_mac_address': [{
        vs
        {'TABLE_vrf': {'ROW_vrf': {'TABLE_adj': {'ROW_adj': {
        """
        _table = parent_table.get(table_name)
        _table_rows = []
        if isinstance(_table, list):
            _table_rows = [_table_row.get(row_name) for _table_row in _table]
        elif isinstance(_table, dict):
            _table_rows = _table.get(row_name)
        if not isinstance(_table_rows, list):
            _table_rows = [_table_rows]
        return _table_rows

    def _get_reply_table(self, result, table_name, row_name):
        return self._get_table_rows(result, table_name, row_name)

    def _get_command_table(self, command, table_name, row_name):
        json_output = self._send_command(command)
        return self._get_reply_table(json_output, table_name, row_name)

    def is_alive(self):
        if self.device:
            return {'is_alive': True}
        else:
            return {'is_alive': False}

    def _copy_run_start(self):
        results = self.device.save(filename='startup-config')
        if not results:
            msg = 'Unable to save running-config to startup-config!'
            raise CommandErrorException(msg)

    def _load_cfg_from_checkpoint(self):
        commands = ['terminal dont-ask',
                    'rollback running-config file {}'.format(self.candidate_cfg),
                    'no terminal dont-ask']
        try:
            rollback_result = self._send_command_list(commands)
        except ConnectionError:
            # requests will raise an error with verbose warning output (don't fail on this).
            return
        finally:
            self.changed = True

        # For nx-api a list is returned so extract the result associated with the
        # 'rollback' command.
        rollback_result = rollback_result[1]
        msg = rollback_result.get('msg') if rollback_result.get('msg') else rollback_result
        error_msg = True if rollback_result.get('error') else False

        if 'Rollback failed.' in msg or error_msg:
            raise ReplaceConfigException(msg)
        elif rollback_result == []:
            raise ReplaceConfigException

    def rollback(self):
        if self.changed:
            self.device.rollback(self.rollback_cfg)
            self._copy_run_start()
            self.changed = False

    def get_facts(self):
        facts = {}
        facts['vendor'] = "Cisco"

        show_version = self._send_command("show version")
        facts['model'] = show_version.get("chassis_id", "")
        facts['hostname'] = show_version.get("host_name", "")
        facts['serial_number'] = show_version.get("proc_board_id", "")
        facts['os_version'] = show_version.get("sys_ver_str", "")

        uptime_days = show_version.get("kern_uptm_days", 0)
        uptime_hours = show_version.get("kern_uptm_hrs", 0)
        uptime_mins = show_version.get("kern_uptm_mins", 0)
        uptime_secs = show_version.get("kern_uptm_secs", 0)

        uptime = 0
        uptime += uptime_days * 24 * 60 * 60
        uptime += uptime_hours * 60 * 60
        uptime += uptime_mins * 60
        uptime += uptime_secs

        facts['uptime'] = uptime

        iface_cmd = 'show interface'
        interfaces_out = self._send_command(iface_cmd)
        interfaces_body = interfaces_out['TABLE_interface']['ROW_interface']
        interface_list = [intf_data['interface'] for intf_data in interfaces_body]
        facts['interface_list'] = interface_list

        hostname_cmd = 'show hostname'
        hostname = self._send_command(hostname_cmd).get('hostname')
        if hostname:
            facts['fqdn'] = hostname

        return facts

    def get_interfaces(self):
        interfaces = {}
        iface_cmd = 'show interface'
        interfaces_out = self._send_command(iface_cmd)
        interfaces_body = interfaces_out['TABLE_interface']['ROW_interface']

        for interface_details in interfaces_body:
            interface_name = interface_details.get('interface')
            # Earlier version of Nexus returned a list for 'eth_bw' (observed on 7.1(0)N1(1a))
            interface_speed = interface_details.get('eth_bw', 0)
            if isinstance(interface_speed, list):
                interface_speed = interface_speed[0]
            interface_speed = int(interface_speed / 1000)
            if 'admin_state' in interface_details:
                is_up = interface_details.get('admin_state', '') == 'up'
            else:
                is_up = interface_details.get('state', '') == 'up'
            interfaces[interface_name] = {
                'is_up': is_up,
                'is_enabled': (interface_details.get('state') == 'up'),
                'description': py23_compat.text_type(interface_details.get('desc', '').strip('"')),
                'last_flapped': self._compute_timestamp(
                    interface_details.get('eth_link_flapped', '')),
                'speed': interface_speed,
                'mac_address': napalm.base.helpers.convert(
                    napalm.base.helpers.mac, interface_details.get('eth_hw_addr')),
            }
        return interfaces

    def get_lldp_neighbors(self):
        results = {}
        try:
            command = 'show lldp neighbors'
            lldp_raw_output = self.cli([command]).get(command, '')
            lldp_neighbors = napalm.base.helpers.textfsm_extractor(
                self, 'lldp_neighbors', lldp_raw_output)
        except NXAPICommandError:
            lldp_neighbors = []

        for neighbor in lldp_neighbors:
            local_iface = neighbor.get('local_interface')
            if neighbor.get(local_iface) is None:
                if local_iface not in results:
                    results[local_iface] = []

            neighbor_dict = {'hostname': py23_compat.text_type(neighbor.get('neighbor')),
                             'port': py23_compat.text_type(neighbor.get('neighbor_interface'))}

            results[local_iface].append(neighbor_dict)
        return results

    def get_bgp_neighbors(self):
        results = {}
        bgp_state_dict = {
            'Idle': {'is_up': False, 'is_enabled': True},
            'Active': {'is_up': False, 'is_enabled': True},
            'Open': {'is_up': False, 'is_enabled': True},
            'Established': {'is_up': True, 'is_enabled': True},
            'Closing': {'is_up': True, 'is_enabled': True},
            'Shutdown': {'is_up': False, 'is_enabled': False},
        }
        """
        af_name_dict = {
            'af-id': {'safi': "af-name"},
            'af-id': {'safi': "af-name"},
            'af-id': {'safi': "af-name"}
        }
        """
        af_name_dict = {
            1: {1: 'ipv4', 128: 'vpnv4'},
            2: {1: 'ipv6', 128: 'vpnv6'},
            25: {70: 'l2vpn'}
        }

        try:
            cmd = 'show bgp all summary vrf all'
            vrf_list = self._get_command_table(cmd, 'TABLE_vrf', 'ROW_vrf')
        except NXAPICommandError:
            vrf_list = []

        for vrf_dict in vrf_list:
            result_vrf_dict = {
                'router_id': py23_compat.text_type(vrf_dict['vrf-router-id']),
                'peers': {}
            }

            af_list = vrf_dict.get('TABLE_af', {}).get('ROW_af', [])
            if isinstance(af_list, dict):
                af_list = [af_list]

            for af_dict in af_list:
                saf_dict = af_dict.get('TABLE_saf', {}).get('ROW_saf', {})
                neighbors_list = saf_dict.get('TABLE_neighbor', {}).get('ROW_neighbor', [])

                if isinstance(neighbors_list, dict):
                    neighbors_list = [neighbors_list]

                for neighbor_dict in neighbors_list:
                    neighborid = napalm.base.helpers.ip(neighbor_dict['neighborid'])
                    remoteas = napalm.base.helpers.as_number(neighbor_dict['neighboras'])
                    state = py23_compat.text_type(neighbor_dict['state'])

                    bgp_state = bgp_state_dict[state]
                    afid_dict = af_name_dict[int(af_dict['af-id'])]
                    safi_name = afid_dict[int(saf_dict['safi'])]

                    result_peer_dict = {
                        'local_as': int(vrf_dict['vrf-local-as']),
                        'remote_as': remoteas,
                        'remote_id': neighborid,
                        'is_enabled': bgp_state['is_enabled'],
                        'uptime': -1,
                        'description': '',
                        'is_up': bgp_state['is_up'],
                        'address_family': {
                           safi_name: {
                                'sent_prefixes': -1,
                                'accepted_prefixes': -1,
                                'received_prefixes': int(neighbor_dict['prefixreceived'])
                            }
                        }
                    }
                    result_vrf_dict['peers'][neighborid] = result_peer_dict

            vrf_name = vrf_dict['vrf-name-out']
            if vrf_name == 'default':
                vrf_name = 'global'
            results[vrf_name] = result_vrf_dict
        return results

    def get_lldp_neighbors_detail(self, interface=''):
        lldp_neighbors = {}
        filter = ''
        if interface:
            filter = 'interface {name} '.format(name=interface)

        command = 'show lldp neighbors {filter}detail'.format(filter=filter)
        # seems that some old devices may not return JSON output...

        try:
            lldp_neighbors_table_str = self.cli([command]).get(command)
            # thus we need to take the raw text output
            lldp_neighbors_list = lldp_neighbors_table_str.splitlines()
        except NXAPICommandError:
            lldp_neighbors_list = []

        if not lldp_neighbors_list:
            return lldp_neighbors  # empty dict

        CHASSIS_REGEX = r'^(Chassis id:)\s+([a-z0-9\.]+)$'
        PORT_REGEX = r'^(Port id:)\s+([0-9]+)$'
        LOCAL_PORT_ID_REGEX = r'^(Local Port id:)\s+(.*)$'
        PORT_DESCR_REGEX = r'^(Port Description:)\s+(.*)$'
        SYSTEM_NAME_REGEX = r'^(System Name:)\s+(.*)$'
        SYSTEM_DESCR_REGEX = r'^(System Description:)\s+(.*)$'
        SYST_CAPAB_REEGX = r'^(System Capabilities:)\s+(.*)$'
        ENABL_CAPAB_REGEX = r'^(Enabled Capabilities:)\s+(.*)$'
        VLAN_ID_REGEX = r'^(Vlan ID:)\s+(.*)$'

        lldp_neighbor = {}
        interface_name = None

        for line in lldp_neighbors_list:
            chassis_rgx = re.search(CHASSIS_REGEX, line, re.I)
            if chassis_rgx:
                lldp_neighbor = {
                    'remote_chassis_id': napalm.base.helpers.mac(chassis_rgx.groups()[1])
                }
                continue
            lldp_neighbor['parent_interface'] = ''
            port_rgx = re.search(PORT_REGEX, line, re.I)
            if port_rgx:
                lldp_neighbor['parent_interface'] = py23_compat.text_type(port_rgx.groups()[1])
                continue
            local_port_rgx = re.search(LOCAL_PORT_ID_REGEX, line, re.I)
            if local_port_rgx:
                interface_name = local_port_rgx.groups()[1]
                continue
            port_descr_rgx = re.search(PORT_DESCR_REGEX, line, re.I)
            if port_descr_rgx:
                lldp_neighbor['remote_port'] = py23_compat.text_type(port_descr_rgx.groups()[1])
                lldp_neighbor['remote_port_description'] = py23_compat.text_type(
                    port_descr_rgx.groups()[1])
                continue
            syst_name_rgx = re.search(SYSTEM_NAME_REGEX, line, re.I)
            if syst_name_rgx:
                lldp_neighbor['remote_system_name'] = py23_compat.text_type(
                    syst_name_rgx.groups()[1])
                continue
            syst_descr_rgx = re.search(SYSTEM_DESCR_REGEX, line, re.I)
            if syst_descr_rgx:
                lldp_neighbor['remote_system_description'] = py23_compat.text_type(
                    syst_descr_rgx.groups()[1])
                continue
            syst_capab_rgx = re.search(SYST_CAPAB_REEGX, line, re.I)
            if syst_capab_rgx:
                lldp_neighbor['remote_system_capab'] = py23_compat.text_type(
                    syst_capab_rgx.groups()[1])
                continue
            syst_enabled_rgx = re.search(ENABL_CAPAB_REGEX, line, re.I)
            if syst_enabled_rgx:
                lldp_neighbor['remote_system_enable_capab'] = py23_compat.text_type(
                    syst_enabled_rgx.groups()[1])
                continue
            vlan_rgx = re.search(VLAN_ID_REGEX, line, re.I)
            if vlan_rgx:
                # at the end of the loop
                if interface_name not in lldp_neighbors.keys():
                    lldp_neighbors[interface_name] = []
                lldp_neighbors[interface_name].append(lldp_neighbor)
        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:
            command_output = self._send_command(command, raw_text=True)
            cli_output[py23_compat.text_type(command)] = command_output
        return cli_output

    def get_arp_table(self):
        arp_table = []
        command = 'show ip arp'
        arp_table_vrf = self._get_command_table(command, 'TABLE_vrf', 'ROW_vrf')
        arp_table_raw = self._get_table_rows(arp_table_vrf[0], 'TABLE_adj', 'ROW_adj')

        for arp_table_entry in arp_table_raw:
            raw_ip = arp_table_entry.get('ip-addr-out')
            raw_mac = arp_table_entry.get('mac')
            age = arp_table_entry.get('time-stamp')
            if age == '-':
                age_sec = -1.0
            elif ':' not in age:
                # Cisco sometimes returns a sub second arp time 0.411797
                try:
                    age_sec = float(age)
                except ValueError:
                    age_sec = -1.0
            else:
                fields = age.split(':')
                if len(fields) == 3:
                    try:
                        fields = [float(x) for x in fields]
                        hours, minutes, seconds = fields
                        age_sec = 3600 * hours + 60 * minutes + seconds
                    except ValueError:
                        age_sec = -1.0
            age_sec = round(age_sec, 1)

            interface = py23_compat.text_type(arp_table_entry.get('intf-out'))
            arp_table.append({
                'interface': interface,
                'mac': napalm.base.helpers.convert(
                    napalm.base.helpers.mac, raw_mac, raw_mac),
                'ip': napalm.base.helpers.ip(raw_ip),
                'age': age_sec
            })
        return arp_table

    def _get_ntp_entity(self, peer_type):
        ntp_entities = {}
        command = 'show ntp peers'
        ntp_peers_table = self._get_command_table(command, 'TABLE_peers', 'ROW_peers')

        for ntp_peer in ntp_peers_table:
            if ntp_peer.get('serv_peer', '').strip() != peer_type:
                continue
            peer_addr = napalm.base.helpers.ip(ntp_peer.get('PeerIPAddress').strip())
            ntp_entities[peer_addr] = {}

        return ntp_entities

    def get_ntp_peers(self):
        return self._get_ntp_entity('Peer')

    def get_ntp_servers(self):
        return self._get_ntp_entity('Server')

    def get_ntp_stats(self):
        ntp_stats = []
        command = 'show ntp peer-status'
        ntp_stats_table = self._get_command_table(command, 'TABLE_peersstatus', 'ROW_peersstatus')

        for ntp_peer in ntp_stats_table:
            peer_address = napalm.base.helpers.ip(ntp_peer.get('remote').strip())
            syncmode = ntp_peer.get('syncmode')
            stratum = int(ntp_peer.get('st'))
            hostpoll = int(ntp_peer.get('poll'))
            reachability = int(ntp_peer.get('reach'))
            delay = float(ntp_peer.get('delay'))
            ntp_stats.append({
                'remote': peer_address,
                'synchronized': (syncmode == '*'),
                'referenceid': peer_address,
                'stratum': stratum,
                'type': '',
                'when': '',
                'hostpoll': hostpoll,
                'reachability': reachability,
                'delay': delay,
                'offset': 0.0,
                'jitter': 0.0
            })
        return ntp_stats

    def get_interfaces_ip(self):
        interfaces_ip = {}
        ipv4_command = 'show ip interface'
        ipv4_interf_table_vrf = self._get_command_table(ipv4_command, 'TABLE_intf', 'ROW_intf')

        for interface in ipv4_interf_table_vrf:
            interface_name = py23_compat.text_type(interface.get('intf-name', ''))
            addr_str = interface.get('prefix')
            unnumbered = py23_compat.text_type(interface.get('unnum-intf', ''))
            if addr_str:
                address = napalm.base.helpers.ip(addr_str)
                prefix = int(interface.get('masklen', ''))
                if interface_name not in interfaces_ip.keys():
                    interfaces_ip[interface_name] = {}
                if 'ipv4' not in interfaces_ip[interface_name].keys():
                    interfaces_ip[interface_name]['ipv4'] = {}
                if address not in interfaces_ip[interface_name].get('ipv4'):
                    interfaces_ip[interface_name]['ipv4'][address] = {}
                interfaces_ip[interface_name]['ipv4'][address].update({
                    'prefix_length': prefix
                })
            elif unnumbered:
                for interf in ipv4_interf_table_vrf:
                    interf_name = py23_compat.text_type(interf.get('intf-name', ''))
                    if interf_name == unnumbered:
                        address = napalm.base.helpers.ip(interf.get('prefix'))
                        prefix = int(interf.get('masklen', ''))
                        if interface_name not in interfaces_ip.keys():
                            interfaces_ip[interface_name] = {}
                        if 'ipv4' not in interfaces_ip[interface_name].keys():
                            interfaces_ip[interface_name]['ipv4'] = {}
                        if address not in interfaces_ip[interface_name].get('ipv4'):
                            interfaces_ip[interface_name]['ipv4'][address] = {}
                        interfaces_ip[interface_name]['ipv4'][address].update({
                            'prefix_length': prefix
                        })

            secondary_addresses = interface.get('TABLE_secondary_address', {}) \
                .get('ROW_secondary_address', [])
            if type(secondary_addresses) is dict:
                secondary_addresses = [secondary_addresses]
            for secondary_address in secondary_addresses:
                secondary_address_ip = napalm.base.helpers.ip(secondary_address.get('prefix1'))
                secondary_address_prefix = int(secondary_address.get('masklen1', ''))
                if 'ipv4' not in interfaces_ip[interface_name].keys():
                    interfaces_ip[interface_name]['ipv4'] = {}
                if secondary_address_ip not in interfaces_ip[interface_name].get('ipv4'):
                    interfaces_ip[interface_name]['ipv4'][secondary_address_ip] = {}
                interfaces_ip[interface_name]['ipv4'][secondary_address_ip].update({
                    'prefix_length': secondary_address_prefix
                })

        ipv6_command = 'show ipv6 interface'
        ipv6_interf_table_vrf = self._get_command_table(ipv6_command, 'TABLE_intf', 'ROW_intf')

        for interface in ipv6_interf_table_vrf:
            interface_name = py23_compat.text_type(interface.get('intf-name', ''))

            if interface_name not in interfaces_ip.keys():
                interfaces_ip[interface_name] = {}
            if 'ipv6' not in interfaces_ip[interface_name].keys():
                interfaces_ip[interface_name]['ipv6'] = {}

            if type(interface.get('addr', '')) is list:
                for ipv6_address in interface.get('addr', ''):
                    address = napalm.base.helpers.ip(ipv6_address.split('/')[0])
                    prefix = int(ipv6_address.split('/')[-1])
                    if address not in interfaces_ip[interface_name].get('ipv6'):
                        interfaces_ip[interface_name]['ipv6'][address] = {}
                    interfaces_ip[interface_name]['ipv6'][address].update({
                        'prefix_length': prefix
                    })
            else:
                address = napalm.base.helpers.ip(interface.get('addr', '').split('/')[0])
                prefix = interface.get('prefix', '').split('/')[-1]
                if prefix:
                    prefix = int(interface.get('prefix', '').split('/')[-1])
                else:
                    prefix = 128

                if address not in interfaces_ip[interface_name].get('ipv6'):
                    interfaces_ip[interface_name]['ipv6'][address] = {}
                interfaces_ip[interface_name]['ipv6'][address].update({
                    'prefix_length': prefix
                })
        return interfaces_ip

    def get_mac_address_table(self):
        mac_table = []
        command = 'show mac address-table'
        mac_table_raw = self._get_command_table(command, 'TABLE_mac_address', 'ROW_mac_address')

        for mac_entry in mac_table_raw:
            raw_mac = mac_entry.get('disp_mac_addr')
            interface = py23_compat.text_type(mac_entry.get('disp_port'))
            vlan = int(mac_entry.get('disp_vlan'))
            active = True
            static = (mac_entry.get('disp_is_static') != '0')
            moves = 0
            last_move = 0.0
            mac_table.append({
                'mac': napalm.base.helpers.mac(raw_mac),
                'interface': interface,
                'vlan': vlan,
                'active': active,
                'static': static,
                'moves': moves,
                'last_move': last_move
            })
        return mac_table

    def get_snmp_information(self):
        snmp_information = {}
        snmp_command = 'show running-config'
        snmp_raw_output = self.cli([snmp_command]).get(snmp_command, '')
        snmp_config = napalm.base.helpers.textfsm_extractor(self, 'snmp_config', snmp_raw_output)

        if not snmp_config:
            return snmp_information

        snmp_information = {
            'contact': py23_compat.text_type(''),
            'location': py23_compat.text_type(''),
            'community': {},
            'chassis_id': py23_compat.text_type('')
        }

        for snmp_entry in snmp_config:
            contact = py23_compat.text_type(snmp_entry.get('contact', ''))
            if contact:
                snmp_information['contact'] = contact
            location = py23_compat.text_type(snmp_entry.get('location', ''))
            if location:
                snmp_information['location'] = location

            community_name = py23_compat.text_type(snmp_entry.get('community', ''))
            if not community_name:
                continue

            if community_name not in snmp_information['community'].keys():
                snmp_information['community'][community_name] = {
                    'acl': py23_compat.text_type(snmp_entry.get('acl', '')),
                    'mode': py23_compat.text_type(snmp_entry.get('mode', '').lower())
                }
            else:
                acl = py23_compat.text_type(snmp_entry.get('acl', ''))
                if acl:
                    snmp_information['community'][community_name]['acl'] = acl
                mode = py23_compat.text_type(snmp_entry.get('mode', '').lower())
                if mode:
                    snmp_information['community'][community_name]['mode'] = mode
        return snmp_information

    def get_users(self):
        _CISCO_TO_CISCO_MAP = {
            'network-admin': 15,
            'network-operator': 5
        }

        _DEFAULT_USER_DICT = {
            'password': '',
            'level': 0,
            'sshkeys': []
        }

        users = {}
        command = 'show running-config'
        section_username_raw_output = self.cli([command]).get(command, '')
        section_username_tabled_output = napalm.base.helpers.textfsm_extractor(
            self, 'users', section_username_raw_output)

        for user in section_username_tabled_output:
            username = user.get('username', '')
            if not username:
                continue
            if username not in users:
                users[username] = _DEFAULT_USER_DICT.copy()

            password = user.get('password', '')
            if password:
                users[username]['password'] = py23_compat.text_type(password.strip())

            level = 0
            role = user.get('role', '')
            if role.startswith('priv'):
                level = int(role.split('-')[-1])
            else:
                level = _CISCO_TO_CISCO_MAP.get(role, 0)
            if level > users.get(username).get('level'):
                # unfortunately on Cisco you can set different priv levels for the same user
                # Good news though: the device will consider the highest level
                users[username]['level'] = level

            sshkeytype = user.get('sshkeytype', '')
            sshkeyvalue = user.get('sshkeyvalue', '')
            if sshkeytype and sshkeyvalue:
                if sshkeytype not in ['ssh-rsa', 'ssh-dsa']:
                    continue
                users[username]['sshkeys'].append(py23_compat.text_type(sshkeyvalue))
        return users

    def get_network_instances(self, name=''):
        """ get_network_instances implementation for NX-OS """

        # command 'show vrf detail' returns all VRFs with detailed information
        # format: list of dictionaries with keys such as 'vrf_name' and 'rd'
        command = u'show vrf detail'
        vrf_table_raw = self._get_command_table(command, u'TABLE_vrf', u'ROW_vrf')

        # command 'show vrf interface' returns all interfaces including their assigned VRF
        # format: list of dictionaries with keys 'if_name', 'vrf_name', 'vrf_id' and 'soo'
        command = u'show vrf interface'
        intf_table_raw = self._get_command_table(command, u'TABLE_if', u'ROW_if')

        # create a dictionary with key = 'vrf_name' and value = list of interfaces
        vrf_intfs = defaultdict(list)
        for intf in intf_table_raw:
            vrf_intfs[intf[u'vrf_name']].append(py23_compat.text_type(intf['if_name']))

        vrfs = {}
        for vrf in vrf_table_raw:
            vrf_name = py23_compat.text_type(vrf.get('vrf_name'))
            vrfs[vrf_name] = {}
            vrfs[vrf_name][u'name'] = vrf_name

            # differentiate between VRF type 'DEFAULT_INSTANCE' and 'L3VRF'
            if vrf_name == u'default':
                vrfs[vrf_name][u'type'] = u'DEFAULT_INSTANCE'
            else:
                vrfs[vrf_name][u'type'] = u'L3VRF'

            vrfs[vrf_name][u'state'] = {u'route_distinguisher':
                                        py23_compat.text_type(vrf.get('rd'))}

            # convert list of interfaces (vrf_intfs[vrf_name]) to expected format
            # format = dict with key = interface name and empty values
            vrfs[vrf_name][u'interfaces'] = {}
            vrfs[vrf_name][u'interfaces'][u'interface'] = dict.fromkeys(vrf_intfs[vrf_name], {})

        # if name of a specific VRF was passed as an argument
        # only return results for this particular VRF
        if name:
            if name in vrfs.keys():
                return {py23_compat.text_type(name): vrfs[name]}
            else:
                return {}
        # else return results for all VRFs
        else:
            return vrfs
示例#9
0
#!/usr/bin/python

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
from pprint import pprint
from getpass import getpass
from nxapi_plumbing import Device
from lxml import etree

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

nxos1 = Device(
    api_format='xml',
    host='nxos1.lasthop.io',
    username='******',
    password=getpass(),
    transport='https',
    port=8443,
    verify=False,
)

commands = [
    'interface loopback 100', 'description LOOPBACK 100',
    'interface loopback 199', 'description LOOPBACK 199'
]

output = nxos1.config_list(commands)
for out in output:
    pprint(etree.tostring(out).decode())
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
from getpass import getpass
from nxapi_plumbing import Device
from lxml import etree

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

password = getpass()

device = Device(
    api_format="xml",
    host="nxos1.lasthop.io",
    username="******",
    password=password,
    transport="https",
    port=8443,
    verify=False,
)

config = device.config_list([
    "interface loopback180", "ip address 10.50.10.10/32",
    "interface loopback170", "ip address 10.50.20.20/32"
])

for output_list in config:
    print(etree.tostring(output_list).decode())