napalm-automation / napalm

Network Automation and Programmability Abstraction Layer with Multivendor support
Apache License 2.0
2.26k stars 555 forks source link

nxos - napalm_validate - get_interfaces_ip - not working with nxos driver #1097

Closed writememe closed 4 years ago

writememe commented 4 years ago

Description of Issue/Question

It appears that the nxos driver is not working correctly for napalm validation on get_interfaces_ip, however when using the nxos_ssh driver with the same validation file, it works correctly.

Did you follow the steps from https://github.com/napalm-automation/napalm#faq

(Place an x between the square brackets where applicable)

Setup

napalm version

(Paste verbatim output from pip freeze | grep napalm between quotes below)

napalm==2.5.0
napalm-ansible==1.0.0

Network operating system version

(Paste verbatim output from show version - or equivalent - between quotes below)

lab-nxos-01# show version
Cisco Nexus Operating System (NX-OS) Software
TAC support: http://www.cisco.com/tac
Documents: http://www.cisco.com/en/US/products/ps9372/tsd_products_support_serie
s_home.html
Copyright (c) 2002-2017, Cisco Systems, Inc. All rights reserved.
The copyrights to certain works contained herein are owned by
other third parties and are used and distributed under license.
Some parts of this software are covered under the GNU Public
License. A copy of the license is available at
http://www.gnu.org/licenses/gpl.html.

NX-OSv9K is a demo version of the Nexus Operating System

Software
  BIOS: version 
  NXOS: version 7.0(3)I5(2)
  BIOS compile time:  
  NXOS image file is: bootflash:///nxos.7.0.3.I5.2.bin
  NXOS compile time:  2/16/2017 8:00:00 [02/17/2017 03:03:27]

Hardware
  cisco NX-OSv Chassis 
   with 8165356 kB of memory.
  Processor Board ID 9G6HUPYK9MO

  Device name: lab-nxos-01
  bootflash:    3509454 kB
Kernel uptime is 11 day(s), 3 hour(s), 3 minute(s), 9 second(s)

Last reset 
  Reason: Unknown
  System version: 
  Service: 

plugin
  Core Plugin, Ethernet Plugin

Active Package(s):

lab-nxos-01# 

Steps to Reproduce the Issue

1) Create a napalm validation file with a get_interfaces_ip validation check. For the purposes of this example, it will be called automated-validation.yml

---
- get_interfaces_ip:
    Ethernet1/3:
      ipv4:
        192.168.30.10:
          prefix_length: 30
    Ethernet1/2:
      ipv4:
        192.168.30.14:
          prefix_length: 30
    loopback0:
      ipv4:
        192.168.40.14:
          prefix_length: 32

2) Create the following Python script to validate the network device. For the purposes of this example, I will refer to this as nxos_ssh_validate.py. NOTE: The network driver for this script is nxos_ssh:

from napalm import get_network_driver
import pprint

nxos_driver = get_network_driver("nxos_ssh")
nxos_config = {
    "hostname": "lab-nxos-01.lab.dfjt.local",
    "username": "<username>",
    "password": "<password>",
}

with nxos_driver(**nxos_config) as nxos:
    pprint.pprint(nxos.compliance_report("automated-validation.yml"))

3) Run the script nxos_ssh_validate.py. This should be successful

4) Use the following Python script to validate the device. For the purposes of this example, I will refer to this as nxos_validate.py. NOTE: The network driver for this script is nxos and is identical except for the driver:

from napalm import get_network_driver
import pprint

nxos_driver = get_network_driver("nxos")
nxos_config = {
    "hostname": "lab-nxos-01.lab.dfjt.local",
    "username": "<username>",
    "password": "<password>",
}

with nxos_driver(**nxos_config) as nxos:
    pprint.pprint(nxos.compliance_report("automated-validation.yml"))

5) Run the script nxos_validate.py.
This will not be successful.

6) Next, create another validation file, which uses other getters such as get_facts, get_interfaces, get_bgp_neighbors and get_lldp_neighbors_detail. For the purposes of this example, I will call it alternate-validation.yml

---
- get_facts:
    fqdn: lab-nxos-01.lab.dfjt.local
    hostname: lab-nxos-01
- get_bgp_neighbors:
    global:
      peers:
        192.168.30.9:
          is_enabled: true
          is_up: true
          local_as: 65014
          remote_as: 65011
        192.168.30.13:
          is_enabled: true
          is_up: true
          local_as: 65014
          remote_as: 65018
      router_id: 192.168.40.14
- get_interfaces:
    Ethernet1/3:
      description: To lab-arista-01.lab.dfjt.local - Ethernet3
      is_enabled: true
      is_up: true
- get_lldp_neighbors_detail:
    Ethernet1/3:
    - remote_system_name: lab-arista-01

7) Change both the nxos_validate.py and nxos_ssh_validate.py scripts by modifying the last line: Find the line:

    pprint.pprint(nxos.compliance_report("automated-validation.yml"))

Replace with

    pprint.pprint(nxos.compliance_report("alternate-validation.yml"))

8) Run both the nxos_validate.py and nxos_ssh_validate.py scripts. These will both be successful.

_CONCLUSION: It seems to be an issue with the nxos driver and the get_interfaces_ip validation._

I've initially came across this attempting to use napalm_validate in Ansible and have subsequently had more time investigate it further. I'm not sure whether I should close the napalm-ansible issue I raised, but please let me know and I can cancel it.

Thanks, Daniel

Error Traceback

(Paste the complete traceback of the exception between quotes below)

Traceback (most recent call last):
  File "/Users/danielteycheney/Documents/Networking/Python/ansible-meetup-demo/ansible-mel-meetup-2020/scratch/nxos_validate.py", line 12, in <module>
    pprint.pprint(nxos.compliance_report("automated-validation.yml"))
  File "/Users/danielteycheney/Documents/Networking/Python/ansible-meetup-demo/venv/lib/python3.6/site-packages/napalm/base/base.py", line 1676, in compliance_report
    self, validation_file=validation_file, validation_source=validation_source
  File "/Users/danielteycheney/Documents/Networking/Python/ansible-meetup-demo/venv/lib/python3.6/site-packages/napalm/base/validate.py", line 204, in compliance_report
    actual_results = getattr(cls, getter)(**kwargs)
  File "/Users/danielteycheney/Documents/Networking/Python/ansible-meetup-demo/venv/lib/python3.6/site-packages/napalm/nxos/nxos.py", line 1127, in get_interfaces_ip
    ipv6_command, "TABLE_intf", "ROW_intf"
  File "/Users/danielteycheney/Documents/Networking/Python/ansible-meetup-demo/venv/lib/python3.6/site-packages/napalm/nxos/nxos.py", line 639, in _get_command_table
    json_output = json.loads(json_output)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 348, in loads
    'not {!r}'.format(s.__class__.__name__))
TypeError: the JSON object must be str, bytes or bytearray, not 'NoneType'
writememe commented 4 years ago

Hi NAPALM team, would it be possible to get some assistance on this issue? I'd be happy to help fix it if you lead me to where the problem might be. Thanks

tcaiazza commented 4 years ago

I stumbled across this issue and took a stab at it.

I was able to reproduce the issue if my lab switch didn't have any IP interfaces assigned to the switch. I suspect if you just ran the command get_interfaces_ip it would throw the same stack trace. After assigning an IP address my lab setup, the script complained about not being able to run show ipv6 interface. After I commented the IPV6 part out I was able to get the test scripts you posted to work.

I'll create a PR to skip ipv6 if it isn't configured and in the case no IPs are set on the device that get_interfaces_ip returns nothing instead of a stack trace.

tcaiazza commented 4 years ago

So it looks like the interface not having an IP address was just fixed with https://github.com/napalm-automation/napalm/commit/ed9cbe4841d67d90cbd043303c634719a3fcd902

writememe commented 4 years ago

Hey @tcaiazza , thanks a lot for helping! That fix seems to be with the nxos_ssh (napalm/nxos_ssh/nxos_ssh.py) driver however my issue is with the nxos (napalm/nxos/nxos.py) driver.

I commented out the entire get_interfaces_ip ipv6 block (lines 1125 to 1170) and the code now runs: Screen Shot 2020-01-19 at 12 46 30 pm

I'm guessing that the logic needs to be something like:

if ipv6 addresses exist: do ipv6 block else: continue

I'm no expert but hopefully this helps in hunting down the problem?

tcaiazza commented 4 years ago

@writememe Yeah that is still the issue, I have a PR now that once it is merged should fix your issue. https://github.com/napalm-automation/napalm/pull/1108

writememe commented 4 years ago

Thanks! @tcaiazza

mirceaulinic commented 4 years ago

1108 got merged, @writememe are you able to confirm it works as expected now (install the code from the develop branch)?

writememe commented 4 years ago

Hi @mirceaulinic, using the python script above works. I'll double check using napalm_ansible tomorrow and let you know (having issues with my lab) and confirm 100%. Thanks again

writememe commented 4 years ago

Hi @mirceaulinic, I've checked this again and it's now working. Thanks to you and @tcaiazza for helping out, much appreciated

mirceaulinic commented 4 years ago

Great, thanks for confirming!