Mechanical: ruff format, and ruff check --fix with the rule set every NAPALM driver uses (E, F, I, UP, B at line length 100, Python 3.10). Mapping and Iterable come from collections.abc, imports are sorted. What ruff cannot fix comes in the next commit.
187 lines
6.6 KiB
Python
187 lines
6.6 KiB
Python
import pytest
|
|
|
|
from napalm_redfish.parsers import (
|
|
parse_ethernet_interface,
|
|
parse_manager,
|
|
parse_network_protocol,
|
|
)
|
|
|
|
MANAGER = "/redfish/v1/Managers/BMC"
|
|
|
|
|
|
def test_manager(rackmount):
|
|
m = parse_manager(rackmount(MANAGER))
|
|
assert m["id"] == "BMC"
|
|
assert m["name"] == "Manager"
|
|
assert m["manager_type"] == "BMC"
|
|
assert m["model"] == "Joo Janta 200"
|
|
assert m["firmware_version"] == "1.45.455b66-rev4"
|
|
assert m["uuid"] == "58893887-8974-2487-2389-841168418919"
|
|
assert m["power_state"] == "On"
|
|
assert m["date_time"] == "2015-03-13T04:14:33+06:00"
|
|
assert m["state"] == "Enabled"
|
|
assert m["health"] == "OK"
|
|
assert m["links"]["EthernetInterfaces"] == MANAGER + "/EthernetInterfaces"
|
|
assert m["links"]["NetworkProtocol"] == MANAGER + "/NetworkProtocol"
|
|
assert m["links"]["LogServices"] == MANAGER + "/LogServices"
|
|
assert m["manager_for_servers"] == ["/redfish/v1/Systems/437XR1138R2"]
|
|
assert m["manager_for_chassis"] == ["/redfish/v1/Chassis/1U"]
|
|
|
|
|
|
def test_manager_minimal():
|
|
m = parse_manager({"Id": "1", "FirmwareVersion": " 3.91 "})
|
|
assert m["firmware_version"] == "3.91"
|
|
assert m["model"] is None
|
|
assert m["links"] == {}
|
|
assert m["manager_for_servers"] == []
|
|
|
|
|
|
# --- EthernetInterfaces --------------------------------------------------------------------
|
|
|
|
|
|
def test_ethernet_interface(rackmount):
|
|
eth = parse_ethernet_interface(rackmount(MANAGER + "/EthernetInterfaces/eth0"))
|
|
assert eth["name"] == "eth0"
|
|
assert eth["interface"] == {
|
|
"is_up": True,
|
|
"is_enabled": True,
|
|
"description": "Management network interface on a dedicated port",
|
|
"last_flapped": -1.0,
|
|
"speed": 100.0,
|
|
"mtu": 1500,
|
|
"mac_address": "23:11:8A:33:CF:EA",
|
|
}
|
|
assert eth["ipv4"] == {"192.168.0.10": {"prefix_length": 22}}
|
|
assert eth["ipv6"] == {"fe80::1ec1:deff:fe6f:1e24": {"prefix_length": 64}}
|
|
assert eth["hostname"] == "web483-bmc"
|
|
assert eth["fqdn"] == "web483-bmc.dmtf.org"
|
|
assert eth["vlan"] == 101
|
|
assert eth["permanent_mac_address"] == "23:11:8A:33:CF:EA"
|
|
assert eth["link_status"] == "LinkUp"
|
|
|
|
|
|
def test_ethernet_interface_without_link_status(rackmount):
|
|
# No LinkStatus (as on older schemas): enabled and Status Enabled counts as up.
|
|
eth = parse_ethernet_interface(rackmount(MANAGER + "/EthernetInterfaces/ToHost"))
|
|
assert eth["interface"]["is_up"] is True
|
|
assert eth["ipv4"] == {"192.168.20.55": {"prefix_length": 24}}
|
|
assert eth["link_status"] is None
|
|
assert eth["vlan"] is None
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"props, is_up, is_enabled",
|
|
[
|
|
({"LinkStatus": "LinkDown", "InterfaceEnabled": True}, False, True),
|
|
({"LinkStatus": "NoLink", "InterfaceEnabled": True}, False, True),
|
|
({"LinkStatus": "LinkUp", "InterfaceEnabled": False}, False, False),
|
|
({"Status": {"State": "Disabled"}}, False, False),
|
|
({"Status": {"State": "Enabled"}}, True, True),
|
|
({}, False, False),
|
|
],
|
|
)
|
|
def test_ethernet_link_state(props, is_up, is_enabled):
|
|
eth = parse_ethernet_interface({"Id": "1", **props})
|
|
assert eth["interface"]["is_up"] is is_up
|
|
assert eth["interface"]["is_enabled"] is is_enabled
|
|
|
|
|
|
def test_ethernet_unset_addresses_and_formats():
|
|
# Supermicro and others report unset addresses as 0.0.0.0 or "::" and MACs in lower case.
|
|
eth = parse_ethernet_interface(
|
|
{
|
|
"Id": "1",
|
|
"MACAddress": "0c:c4:7a:aa:bb:cc",
|
|
"SpeedMbps": None,
|
|
"IPv4Addresses": [
|
|
{"Address": "0.0.0.0", "SubnetMask": "0.0.0.0"},
|
|
{"Address": "10.1.2.3", "SubnetMask": "255.255.255.0"},
|
|
{"Address": "10.1.2.4", "SubnetMask": "garbage"},
|
|
{"Address": None},
|
|
],
|
|
"IPv6Addresses": [
|
|
{"Address": "::", "PrefixLength": 0},
|
|
{"Address": "2001:DB8::5", "PrefixLength": 64},
|
|
{"Address": "2001:db8::6"},
|
|
],
|
|
}
|
|
)
|
|
assert eth["interface"]["mac_address"] == "0C:C4:7A:AA:BB:CC"
|
|
assert eth["interface"]["speed"] == -1.0
|
|
assert eth["interface"]["mtu"] == 0
|
|
assert eth["interface"]["description"] == ""
|
|
assert eth["ipv4"] == {"10.1.2.3": {"prefix_length": 24}}
|
|
assert eth["ipv6"] == {
|
|
"2001:db8::5": {"prefix_length": 64},
|
|
"2001:db8::6": {"prefix_length": 128},
|
|
}
|
|
|
|
|
|
# --- NetworkProtocol -----------------------------------------------------------------------
|
|
|
|
|
|
def test_network_protocol(rackmount):
|
|
np = parse_network_protocol(rackmount(MANAGER + "/NetworkProtocol"))
|
|
assert np["hostname"] == "web483-bmc"
|
|
assert np["fqdn"] == "web483-bmc.dmtf.org"
|
|
assert np["protocols"] == {
|
|
"HTTP": {"enabled": True, "port": 80},
|
|
"HTTPS": {"enabled": True, "port": 443},
|
|
"IPMI": {"enabled": True, "port": 623},
|
|
"SSH": {"enabled": True, "port": 22},
|
|
"SNMP": {"enabled": True, "port": 161},
|
|
"VirtualMedia": {"enabled": True, "port": 17988},
|
|
"SSDP": {"enabled": True, "port": 1900},
|
|
"Telnet": {"enabled": True, "port": 23},
|
|
"KVMIP": {"enabled": True, "port": 5288},
|
|
}
|
|
assert np["ntp"] == {"enabled": None, "servers": []}
|
|
assert np["snmp"] == {
|
|
"enabled": True,
|
|
"port": 161,
|
|
"v1": True,
|
|
"v2c": False,
|
|
"v3": True,
|
|
"communities": [
|
|
{"name": "Read-only community", "access": "Limited"},
|
|
{"name": "Full access community", "access": "Full"},
|
|
],
|
|
}
|
|
|
|
|
|
def test_network_protocol_ntp(telemetry):
|
|
np = parse_network_protocol(telemetry("/redfish/v1/Managers/1/NetworkProtocol"))
|
|
assert np["ntp"] == {
|
|
"enabled": True,
|
|
"servers": ["0.pool.ntp.org", "1.pool.ntp.org", "time-a.nist.gov"],
|
|
}
|
|
assert np["protocols"]["NTP"] == {"enabled": True, "port": None}
|
|
# Older SNMP schema: only ProtocolEnabled and Port.
|
|
assert np["snmp"] == {
|
|
"enabled": True,
|
|
"port": 161,
|
|
"v1": None,
|
|
"v2c": None,
|
|
"v3": None,
|
|
"communities": [],
|
|
}
|
|
|
|
|
|
def test_network_protocol_port_without_flag():
|
|
np = parse_network_protocol({"IPMI": {"Port": 623}, "Proxy": {"Enabled": True}})
|
|
assert np["protocols"] == {"IPMI": {"enabled": None, "port": 623}}
|
|
|
|
|
|
def test_network_protocol_ntp_blank_entries():
|
|
servers = ["", None, " pool.ntp.org ", "pool.ntp.org"]
|
|
np = parse_network_protocol({"NTP": {"ProtocolEnabled": True, "NTPServers": servers}})
|
|
assert np["ntp"]["servers"] == ["pool.ntp.org"]
|
|
assert np["snmp"] == {
|
|
"enabled": None,
|
|
"port": None,
|
|
"v1": None,
|
|
"v2c": None,
|
|
"v3": None,
|
|
"communities": [],
|
|
}
|