Skip to content

Commit

Permalink
Incorrectly taken serial number in NXOS. (napalm-automation#1025)
Browse files Browse the repository at this point in the history
* The serial number is taken incorrectly, in particular,
the "Processor Board ID" is displayed,
and you need a Chassis -> serialnum:

* Additional safety net for the lack of a serial number in the output.

* black test

* mov function _get_table_rows, _get_reply_table and _get_command_table
from class  NXOSDriver to NXOSDriverBase, because used in NXOSSSHDriver.

* Added verification and conversion from string to json
  • Loading branch information
VictorPavlushin authored and mirceaulinic committed Sep 3, 2019
1 parent 5bfbee5 commit 3a7e9c0
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 34 deletions.
75 changes: 45 additions & 30 deletions napalm/nxos/nxos.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from netmiko import file_transfer
from nxapi_plumbing import Device as NXOSDevice
from nxapi_plumbing import NXAPIAuthError, NXAPIConnectionError, NXAPICommandError
import json

# import NAPALM Base
import napalm.base.helpers
Expand Down Expand Up @@ -601,6 +602,37 @@ def get_lldp_neighbors_detail(self, interface=""):

return lldp

@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': {
"""
if parent_table is None:
return []
_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)
if type(json_output) is not dict:
json_output = json.loads(json_output)
return self._get_reply_table(json_output, table_name, row_name)


class NXOSDriver(NXOSDriverBase):
def __init__(self, hostname, username, password, timeout=60, optional_args=None):
Expand Down Expand Up @@ -701,35 +733,6 @@ def _compute_timestamp(stupid_cisco_output):
)
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': {
"""
if parent_table is None:
return []
_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}
Expand Down Expand Up @@ -781,10 +784,22 @@ def get_facts(self):
facts = {}
facts["vendor"] = "Cisco"

show_inventory_table = self._get_command_table(
"show inventory", "TABLE_inv", "ROW_inv"
)
if isinstance(show_inventory_table, dict):
show_inventory_table = [show_inventory_table]

facts["serial_number"] = None

for row in show_inventory_table:
if row["name"] == "Chassis":
facts["serial_number"] = row.get("serialnum", "")
break

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)
Expand Down
15 changes: 11 additions & 4 deletions napalm/nxos_ssh/nxos_ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,16 +584,23 @@ def get_facts(self):
show_int_status = self._send_command("show interface status")
show_hostname = self._send_command("show hostname")

show_inventory_table = self._get_command_table(
"show inventory | json", "TABLE_inv", "ROW_inv"
)
if isinstance(show_inventory_table, dict):
show_inventory_table = [show_inventory_table]

for row in show_inventory_table:
if row["name"] == "Chassis":
serial_number = row.get("serialnum", "")
break

# uptime/serial_number/IOS version
for line in show_ver.splitlines():
if " uptime is " in line:
_, uptime_str = line.split(" uptime is ")
uptime = self.parse_uptime(uptime_str)

if "Processor Board ID" in line:
_, serial_number = line.split("Processor Board ID ")
serial_number = serial_number.strip()

if "system: " in line or "NXOS: " in line:
line = line.strip()
os_version = line.split()[2]
Expand Down
34 changes: 34 additions & 0 deletions test/nxos/mocked_data/test_get_facts/normal/show_inventory.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"TABLE_inv": {
"ROW_inv": [
{
"name": "Chassis",
"desc": "Nexus 6001 Chassis",
"productid": "N6K-C6001-64P",
"vendorid": "V01",
"serialnum": "TM6017D760B"
},
{
"name": "Module 1",
"desc": "Nexus 64 Supervisor",
"productid": "N6K-C6001-64P",
"vendorid": "V01",
"serialnum": "FOC11111111"
},
{
"name": "Module 2",
"desc": "Nexus 4xQSFP Ethernet Module",
"productid": "N6K-C6001-M4Q",
"vendorid": "V01",
"serialnum": "FOC11111111"
},
{
"name": "Fan 1",
"desc": "Chassis fan module",
"productid": "N6K-C6001-FAN-B",
"vendorid": "N/A",
"serialnum": "N/A"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"TABLE_inv": {
"ROW_inv": [
{
"name": "Chassis",
"desc": "Nexus 6001 Chassis",
"productid": "N6K-C6001-64P",
"vendorid": "V01",
"serialnum": "JAF1602BKEN"
},
{
"name": "Module 1",
"desc": "Nexus 64 Supervisor",
"productid": "N6K-C6001-64P",
"vendorid": "V01",
"serialnum": "FOC11111111"
},
{
"name": "Module 2",
"desc": "Nexus 4xQSFP Ethernet Module",
"productid": "N6K-C6001-M4Q",
"vendorid": "V01",
"serialnum": "FOC11111111"
},
{
"name": "Fan 1",
"desc": "Chassis fan module",
"productid": "N6K-C6001-FAN-B",
"vendorid": "N/A",
"serialnum": "N/A"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"TABLE_inv": {
"ROW_inv": [
{
"name": "Chassis",
"desc": "Nexus 6001 Chassis",
"productid": "N6K-C6001-64P",
"vendorid": "V01",
"serialnum": "FDO21270U84"
},
{
"name": "Module 1",
"desc": "Nexus 64 Supervisor",
"productid": "N6K-C6001-64P",
"vendorid": "V01",
"serialnum": "FOC11111111"
},
{
"name": "Module 2",
"desc": "Nexus 4xQSFP Ethernet Module",
"productid": "N6K-C6001-M4Q",
"vendorid": "V01",
"serialnum": "FOC11111111"
},
{
"name": "Fan 1",
"desc": "Chassis fan module",
"productid": "N6K-C6001-FAN-B",
"vendorid": "N/A",
"serialnum": "N/A"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"TABLE_inv": {
"ROW_inv": [
{
"name": "Chassis",
"desc": "Nexus 6001 Chassis",
"productid": "N6K-C6001-64P",
"vendorid": "V01",
"serialnum": "TM6012EC74B"
},
{
"name": "Module 1",
"desc": "Nexus 64 Supervisor",
"productid": "N6K-C6001-64P",
"vendorid": "V01",
"serialnum": "FOC11111111"
},
{
"name": "Module 2",
"desc": "Nexus 4xQSFP Ethernet Module",
"productid": "N6K-C6001-M4Q",
"vendorid": "V01",
"serialnum": "FOC11111111"
},
{
"name": "Fan 1",
"desc": "Chassis fan module",
"productid": "N6K-C6001-FAN-B",
"vendorid": "N/A",
"serialnum": "N/A"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"TABLE_inv": {
"ROW_inv": [
{
"name": "Chassis",
"desc": "Nexus 6001 Chassis",
"productid": "N6K-C6001-64P",
"vendorid": "V01",
"serialnum": "TM6012EC74B"
},
{
"name": "Module 1",
"desc": "Nexus 64 Supervisor",
"productid": "N6K-C6001-64P",
"vendorid": "V01",
"serialnum": "FOC11111111"
},
{
"name": "Module 2",
"desc": "Nexus 4xQSFP Ethernet Module",
"productid": "N6K-C6001-M4Q",
"vendorid": "V01",
"serialnum": "FOC11111111"
},
{
"name": "Fan 1",
"desc": "Chassis fan module",
"productid": "N6K-C6001-FAN-B",
"vendorid": "N/A",
"serialnum": "N/A"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"TABLE_inv": {
"ROW_inv": [
{
"name": "Chassis",
"desc": "Nexus 6001 Chassis",
"productid": "N6K-C6001-64P",
"vendorid": "V01",
"serialnum": "TM6012EC74B"
},
{
"name": "Module 1",
"desc": "Nexus 64 Supervisor",
"productid": "N6K-C6001-64P",
"vendorid": "V01",
"serialnum": "FOC11111111"
},
{
"name": "Module 2",
"desc": "Nexus 4xQSFP Ethernet Module",
"productid": "N6K-C6001-M4Q",
"vendorid": "V01",
"serialnum": "FOC11111111"
},
{
"name": "Fan 1",
"desc": "Chassis fan module",
"productid": "N6K-C6001-FAN-B",
"vendorid": "N/A",
"serialnum": "N/A"
}
]
}
}

0 comments on commit 3a7e9c0

Please sign in to comment.