From c31952ea915249e81196ec1a558141e7fb8960b4 Mon Sep 17 00:00:00 2001 From: N0odlez <3342020+N0odlez@users.noreply.github.com> Date: Sat, 18 Nov 2023 12:19:55 +0000 Subject: [PATCH] Added support for Environment - Tested with 2930M Standalone and Stacked, 2930F --- README.md | 2 +- napalm_arubaoss/ArubaOS.py | 25 ++---- napalm_arubaoss/helper/__init__.py | 2 + napalm_arubaoss/helper/get_environment.py | 90 +++++++++++++++++++ .../utils/textfsm_templates/show_system.tpl | 13 +++ .../textfsm_templates/show_system_fans.tpl | 12 +++ .../show_system_power-supply.tpl | 15 ++++ .../show_system_temperature.tpl | 11 +++ .../normal/cli_mapping.json | 6 ++ .../normal/expected_result.json | 47 ++++++++++ .../stack/cli_mapping.json | 6 ++ .../stack/expected_result.json | 80 +++++++++++++++++ .../utils/textfsm_templates/show_system.tpl | 13 +++ .../textfsm_templates/show_system_fans.tpl | 12 +++ .../show_system_power-supply.tpl | 15 ++++ .../show_system_temperature.tpl | 11 +++ 16 files changed, 340 insertions(+), 20 deletions(-) create mode 100644 napalm_arubaoss/helper/get_environment.py create mode 100644 napalm_arubaoss/utils/textfsm_templates/show_system.tpl create mode 100644 napalm_arubaoss/utils/textfsm_templates/show_system_fans.tpl create mode 100644 napalm_arubaoss/utils/textfsm_templates/show_system_power-supply.tpl create mode 100644 napalm_arubaoss/utils/textfsm_templates/show_system_temperature.tpl create mode 100644 test/unit/mocked_data/test_get_environment/normal/cli_mapping.json create mode 100644 test/unit/mocked_data/test_get_environment/normal/expected_result.json create mode 100644 test/unit/mocked_data/test_get_environment/stack/cli_mapping.json create mode 100644 test/unit/mocked_data/test_get_environment/stack/expected_result.json create mode 100644 test/unit/utils/textfsm_templates/show_system.tpl create mode 100644 test/unit/utils/textfsm_templates/show_system_fans.tpl create mode 100644 test/unit/utils/textfsm_templates/show_system_power-supply.tpl create mode 100644 test/unit/utils/textfsm_templates/show_system_temperature.tpl diff --git a/README.md b/README.md index 546f1ab..21513eb 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Driver implementation for Aruba OS Switch. Tested in AOS > WC.16.09.0004, some m * get_bgp_neighbors() ❌* * get_bgp_neighbors_detail() ❌* * get_config() ✅ - * get_environment() ❌ - Planned + * get_environment() ✅ * get_facts() ✅ * get_firewall_policies() ❌* * get_interfaces_counters() ❌*** diff --git a/napalm_arubaoss/ArubaOS.py b/napalm_arubaoss/ArubaOS.py index 61a9852..7faee0b 100644 --- a/napalm_arubaoss/ArubaOS.py +++ b/napalm_arubaoss/ArubaOS.py @@ -11,6 +11,7 @@ confirm_commit, get_arp_table, get_config, + get_environment, get_facts, get_interfaces, get_interfaces_ip, @@ -230,27 +231,13 @@ def get_config(self, retrieve="all", full=False, sanitized=False): def get_environment(self): """ - Get environment readings - NOT IMPLEMENTED. - - Currently (API v7) the API does not support reading information about - fans, temperature, power or CPU. - A textfsm template needs to be created to parse: - - show system temperature - - show system fan - - show system power-consumption - - show system power-supply - - show system information (CPU/MEM) + Get environment readings :return: - output = { - "fans": {}, - "temperature": {}, - "power": {}, - "cpu": {}, - "memory": {} - } """ - return super(ArubaOSS, self).get_environment() + ret = get_environment(self=self) + + return ret def get_facts(self): """ @@ -504,7 +491,7 @@ def get_users(self): :return: """ - return super(ArubaOSS, self).get_users() + return get_users() def has_pending_commit(self): """ diff --git a/napalm_arubaoss/helper/__init__.py b/napalm_arubaoss/helper/__init__.py index d55f368..985d8b2 100644 --- a/napalm_arubaoss/helper/__init__.py +++ b/napalm_arubaoss/helper/__init__.py @@ -6,6 +6,7 @@ from napalm_arubaoss.helper.confirm_commit import confirm_commit from napalm_arubaoss.helper.get_arp_table import get_arp_table from napalm_arubaoss.helper.get_config import get_config +from napalm_arubaoss.helper.get_environment import get_environment from napalm_arubaoss.helper.get_facts import get_facts from napalm_arubaoss.helper.get_interfaces import get_interfaces from napalm_arubaoss.helper.get_interfaces_ip import get_interfaces_ip @@ -44,6 +45,7 @@ "get_facts", "get_arp_table", "get_config", + "get_environment", "get_interfaces", "get_interfaces_ip", "get_lldp_neighbors", diff --git a/napalm_arubaoss/helper/get_environment.py b/napalm_arubaoss/helper/get_environment.py new file mode 100644 index 0000000..7801359 --- /dev/null +++ b/napalm_arubaoss/helper/get_environment.py @@ -0,0 +1,90 @@ +"""Get the environment variables of the switch/es""" + +import logging + +from napalm.base.helpers import textfsm_extractor + +logger = logging.getLogger("arubaoss.helper.get_environment") + + +def get_environment(self): + """ + Get device's Environment table. + + :param self: object from class + :return: + """ + + out = { + "fans": {}, + "temperature": {}, + "power": {}, + "cpu": {}, + "memory": {} + } + + raw_system = self.connection.run_cmd("show system") + system_list = textfsm_extractor(self, "show_system", raw_system) + + memtotal = 0 + memfree = 0 + + for switch in system_list: + member = switch.pop("member") + if member == "": + member = 0 + else: + member = "Member " + member + + out["cpu"][member] = { + "%usage": float(switch.pop("cpu")) + } + + memtotal += int(switch.pop("memtotal").replace(',', '')) + memfree += int(switch.pop("memfree").replace(',', '')) + + out["memory"] = { + "available_ram": int(memtotal), + "used_ram": int(memfree) + } + + raw_system_fans = self.connection.run_cmd("show system fans") + system_fans_list = textfsm_extractor(self, "show_system_fans", raw_system_fans) + for fan in system_fans_list: + member = fan.pop("member") + if member != "": + member = "Member " + member + " " + + out["fans"][member + fan.pop('location') + " " + fan.pop('num')] = { + "status": True if fan.pop('state') == "Fan OK" else False + } + + raw_system_temperature = self.connection.run_cmd("show system temperature") + system_temperature_list = textfsm_extractor(self, "show_system_temperature", raw_system_temperature) + for temp in system_temperature_list: + member = temp.pop("member") + if member != "": + member = "Member " + member + " " + + overtemp = True if temp.pop('overtemp') == "YES" else False + + out["temperature"][member + temp.pop('sensor')] = { + "temperature": float(temp.pop('temperature')), + "is_alert": overtemp, + "is_critical": overtemp + } + + raw_system_power = self.connection.run_cmd("show system power-supply") + system_power_list = textfsm_extractor(self, "show_system_power-supply", raw_system_power) + for power in system_power_list: + member = power.pop("member") + if member != "": + member = "Member " + member + " " + + out["power"][member + power.pop('ps')] = { + "status": True if power.pop('state') == "Powered" else False, + "capacity": float(power.pop('max')), + "output": float(power.pop('wattage')) + } + + return out diff --git a/napalm_arubaoss/utils/textfsm_templates/show_system.tpl b/napalm_arubaoss/utils/textfsm_templates/show_system.tpl new file mode 100644 index 0000000..2f0a61a --- /dev/null +++ b/napalm_arubaoss/utils/textfsm_templates/show_system.tpl @@ -0,0 +1,13 @@ +Value Filldown Member (\d) +Value Required CPU (\d+) +Value MemTotal (.{5,}) +Value MemFree (.{5,}) + +Start + ^.*General System -> System + +System + ^\s+Member\s+:${Member} + ^.*Total\s+:\s${MemTotal} + ^.*CPU\sUtil\s\(%\)\s+:\s${CPU} -> Continue + ^.*Free\s+:\s${MemFree} -> Record \ No newline at end of file diff --git a/napalm_arubaoss/utils/textfsm_templates/show_system_fans.tpl b/napalm_arubaoss/utils/textfsm_templates/show_system_fans.tpl new file mode 100644 index 0000000..24692b9 --- /dev/null +++ b/napalm_arubaoss/utils/textfsm_templates/show_system_fans.tpl @@ -0,0 +1,12 @@ +Value Filldown Member (\d) +Value Required NUM (\S+) +Value STATE (\S+\s+\S+) +Value FAILURES (\d+) +Value LOCATION (\S+) + +Start + ^.*Fan Information -> Fans + +Fans + ^Member\s+${Member} + ^${NUM}\s+\|\s+${STATE}\s+\|\s+${FAILURES}\s+\|\s+${LOCATION} -> Record diff --git a/napalm_arubaoss/utils/textfsm_templates/show_system_power-supply.tpl b/napalm_arubaoss/utils/textfsm_templates/show_system_power-supply.tpl new file mode 100644 index 0000000..e1d4cf9 --- /dev/null +++ b/napalm_arubaoss/utils/textfsm_templates/show_system_power-supply.tpl @@ -0,0 +1,15 @@ +Value Member (\d) +Value PS (\d) +Value State (\S+) +Value Wattage (\d+) +Value Max (\d+) + +Start + ^.*Member\s+PS#\s+Model\s+Serial\s+State\s+AC\/DC\s+\+\sV\s+Wattage\s+Max -> Member + ^.*PS#\s+Model\s+Serial\s+State\s+AC\/DC\s+\+\sV\s+Wattage\s+Max -> Standalone + +Standalone + ^ ${PS}\s+\S+\s+\S+\s+${State}\s+\S\S\s\d+\S+\d+\S\s+${Wattage}\s+${Max} -> Record + +Member + ^ ${Member}\s+${PS}\s+\S+\s+\S+\s+${State}\s+\S\S\s\d+\S+\d+\S\s+${Wattage}\s+${Max} -> Record diff --git a/napalm_arubaoss/utils/textfsm_templates/show_system_temperature.tpl b/napalm_arubaoss/utils/textfsm_templates/show_system_temperature.tpl new file mode 100644 index 0000000..a858845 --- /dev/null +++ b/napalm_arubaoss/utils/textfsm_templates/show_system_temperature.tpl @@ -0,0 +1,11 @@ +Value Filldown Member (\d) +Value Required Sensor (\S+) +Value Temperature (\d+) +Value OverTemp (YES|NO) + +Start + ^.*Air -> Temperature + +Temperature + ^ Member ${Member} + ^ ${Sensor}\s+${Temperature}\S\s+\d+\S\s+\d+\S\s+\d+\S\s+${OverTemp} -> Record \ No newline at end of file diff --git a/test/unit/mocked_data/test_get_environment/normal/cli_mapping.json b/test/unit/mocked_data/test_get_environment/normal/cli_mapping.json new file mode 100644 index 0000000..865e0b7 --- /dev/null +++ b/test/unit/mocked_data/test_get_environment/normal/cli_mapping.json @@ -0,0 +1,6 @@ +{ + "show system": "\n Status and Counters - General System Information\n\n System Name : Name\n System Contact : Contact\n System Location : Location\n\n MAC Age Time (sec) : 300\n\n Time Zone : 0\n Daylight Time Rule : None\n\n Software revision : WC.16.11.0001 Base MAC Addr : 1a3b3c-4d5e6f\n ROM Version : WC.17.02.0007 Serial Number : NANANANANA\n\n Up Time : 68 days Memory - Total : 338,190,848\n CPU Util (%) : 0 Free : 177,716,208\n\n IP Mgmt - Pkts Rx : 260,263 Packet - Total : 6600\n Pkts Tx : 263,776 Buffers Free : 4347\n Lowest : 4216\n Missed : 0\n\n", + "show system fans": "\nFan Information\n Num | State | Failures | Location\n-------+-------------+----------+----------\nFan-1 | Fan OK | 0 | Chassis\nFan-2 | Fan OK | 0 | Chassis\nFan-3 | Fan OK | 0 | Chassis\nFan-4 | Fan OK | 0 | PS 1\nFan-5 | Fan OK | 0 | PS 2\n\n0 / 5 Fans in Failure State\n0 / 5 Fans have been in Failure State\n\n", + "show system temperature": "\n System Air Temperature\n Temp Current Max Min\n Sensor Temp Temp Temp Threshold OverTemp\n ------- -------- ----- ----- ---------- ---------\n Chassis 12C 17C 10C 50C NO\n\n", + "show system power-supply": "\nPower Supply Status:\n\n PS# Model Serial State AC/DC + V Wattage Max\n ----- --------- ----------- --------------- ----------------- --------- ------\n 1 JL086A NANANANANA Powered AC 120V/240V 14 680\n 2 JL086A NANANANANA Powered AC 120V/240V 19 680\n\n\n 2 / 2 supply bays delivering power.\n Currently supplying 33 W / 1360 W total power.\n\n" +} \ No newline at end of file diff --git a/test/unit/mocked_data/test_get_environment/normal/expected_result.json b/test/unit/mocked_data/test_get_environment/normal/expected_result.json new file mode 100644 index 0000000..78f156f --- /dev/null +++ b/test/unit/mocked_data/test_get_environment/normal/expected_result.json @@ -0,0 +1,47 @@ +{ + "fans": { + "Chassis Fan-1": { + "status": true + }, + "Chassis Fan-2": { + "status": true + }, + "Chassis Fan-3": { + "status": true + }, + "PS Fan-4": { + "status": true + }, + "PS Fan-5": { + "status": true + } + }, + "temperature": { + "Chassis": { + "temperature": 12, + "is_alert": false, + "is_critical": false + } + }, + "power": { + "1": { + "status": true, + "capacity": 680, + "output": 14 + }, + "2": { + "status": true, + "capacity": 680, + "output": 19 + } + }, + "cpu": { + "0": { + "%usage": 0 + } + }, + "memory": { + "available_ram": 338190848, + "used_ram": 177716208 + } +} diff --git a/test/unit/mocked_data/test_get_environment/stack/cli_mapping.json b/test/unit/mocked_data/test_get_environment/stack/cli_mapping.json new file mode 100644 index 0000000..62be71b --- /dev/null +++ b/test/unit/mocked_data/test_get_environment/stack/cli_mapping.json @@ -0,0 +1,6 @@ +{ + "show system": "\n Status and Counters - General System Information\n\n System Name : Switch101\n System Contact : Contact\n System Location : Location\n MAC Age Time (sec) : 300\n Time Zone : 0\n Daylight Time Rule : None\n\n Software revision : WC.16.11.0014\n Base MAC Addr : 1a3b3c-4d5e6f\n\n Member :1\n\n ROM Version : WC.17.02.0007\n Up Time : 119 days\n CPU Util (%) : 2\n MAC Addr : 1a3b3c-4d5e6f\n Serial Number : NANANANANA\n Memory - Total : 333,533,696\n Free : 169,758,520\n\n\n\n Member :2\n\n ROM Version : WC.17.02.0007\n Up Time : 11 days\n CPU Util (%) : 0\n MAC Addr : 1a3b3c-4d5e6f\n Serial Number : NANANANANA\n Memory - Total : 333,533,696\n Free : 186,152,132\n", + "show system fans": "\nFan Information\n\nMember 1\n\n Num | State | Failures | Location\n-------+-------------+----------+----------\nSys-1 | Fan OK | 0 | Chassis\nSys-2 | Fan OK | 0 | Chassis\nSys-3 | Fan OK | 0 | Chassis\nSys-4 | Fan OK | 0 | PS 1\nSys-5 | Fan OK | 0 | PS 2\n\n0 / 5 Fans in Failure State\n0 / 5 Fans have been in Failure State\n\nMember 2\n\n Num | State | Failures | Location\n-------+-------------+----------+----------\nSys-1 | Fan OK | 0 | Chassis\nSys-2 | Fan OK | 0 | Chassis\nSys-3 | Fan OK | 0 | Chassis\nSys-4 | Fan OK | 0 | PS 1\nSys-5 | Fan OK | 0 | PS 2\n\n0 / 5 Fans in Failure State\n0 / 5 Fans have been in Failure State\n", + "show system temperature": "\n System Air Temperatures\n\n Member 1\n\n Temp Current Max Min\n Sensor Temp Temp Temp Threshold OverTemp\n ------- -------- ----- ----- ---------- ---------\n Chassis 26C 26C 19C 55C NO\n\n\n Member 2\n\n Temp Current Max Min\n Sensor Temp Temp Temp Threshold OverTemp\n ------- -------- ----- ----- ---------- ---------\n Chassis 27C 27C 20C 50C NO\n\n\n", + "show system power-supply": "\nPower Supply Status:\n\n Member PS# Model Serial State AC/DC + V Wattage Max\n ------- ----- --------- ----------- --------------- ----------------- --------- ------\n 1 1 JL086A NANANANANA Powered AC 120V/240V 79 680\n 1 2 JL086A NANANANANA Powered AC 120V/240V 66 680\n 2 1 JL086A NANANANANA Powered AC 120V/240V 29 680\n 2 2 JL086A NANANANANA Powered AC 120V/240V 38 680" +} \ No newline at end of file diff --git a/test/unit/mocked_data/test_get_environment/stack/expected_result.json b/test/unit/mocked_data/test_get_environment/stack/expected_result.json new file mode 100644 index 0000000..042203d --- /dev/null +++ b/test/unit/mocked_data/test_get_environment/stack/expected_result.json @@ -0,0 +1,80 @@ +{ + "fans": { + "Member 1 Chassis Sys-1": { + "status": true + }, + "Member 1 Chassis Sys-2": { + "status": true + }, + "Member 1 Chassis Sys-3": { + "status": true + }, + "Member 1 PS Sys-4": { + "status": true + }, + "Member 1 PS Sys-5": { + "status": true + }, + "Member 2 Chassis Sys-1": { + "status": true + }, + "Member 2 Chassis Sys-2": { + "status": true + }, + "Member 2 Chassis Sys-3": { + "status": true + }, + "Member 2 PS Sys-4": { + "status": true + }, + "Member 2 PS Sys-5": { + "status": true + } + }, + "temperature": { + "Member 1 Chassis": { + "temperature": 26, + "is_alert": false, + "is_critical": false + }, + "Member 2 Chassis": { + "temperature": 27, + "is_alert": false, + "is_critical": false + } + }, + "power": { + "Member 1 1": { + "status": true, + "capacity": 680, + "output": 79 + }, + "Member 1 2": { + "status": true, + "capacity": 680, + "output": 66 + }, + "Member 2 1": { + "status": true, + "capacity": 680, + "output": 29 + }, + "Member 2 2": { + "status": true, + "capacity": 680, + "output": 38 + } + }, + "cpu": { + "Member 1": { + "%usage": 2 + }, + "Member 2": { + "%usage": 0 + } + }, + "memory": { + "available_ram": 667067392, + "used_ram": 355910652 + } +} diff --git a/test/unit/utils/textfsm_templates/show_system.tpl b/test/unit/utils/textfsm_templates/show_system.tpl new file mode 100644 index 0000000..2f0a61a --- /dev/null +++ b/test/unit/utils/textfsm_templates/show_system.tpl @@ -0,0 +1,13 @@ +Value Filldown Member (\d) +Value Required CPU (\d+) +Value MemTotal (.{5,}) +Value MemFree (.{5,}) + +Start + ^.*General System -> System + +System + ^\s+Member\s+:${Member} + ^.*Total\s+:\s${MemTotal} + ^.*CPU\sUtil\s\(%\)\s+:\s${CPU} -> Continue + ^.*Free\s+:\s${MemFree} -> Record \ No newline at end of file diff --git a/test/unit/utils/textfsm_templates/show_system_fans.tpl b/test/unit/utils/textfsm_templates/show_system_fans.tpl new file mode 100644 index 0000000..24692b9 --- /dev/null +++ b/test/unit/utils/textfsm_templates/show_system_fans.tpl @@ -0,0 +1,12 @@ +Value Filldown Member (\d) +Value Required NUM (\S+) +Value STATE (\S+\s+\S+) +Value FAILURES (\d+) +Value LOCATION (\S+) + +Start + ^.*Fan Information -> Fans + +Fans + ^Member\s+${Member} + ^${NUM}\s+\|\s+${STATE}\s+\|\s+${FAILURES}\s+\|\s+${LOCATION} -> Record diff --git a/test/unit/utils/textfsm_templates/show_system_power-supply.tpl b/test/unit/utils/textfsm_templates/show_system_power-supply.tpl new file mode 100644 index 0000000..e1d4cf9 --- /dev/null +++ b/test/unit/utils/textfsm_templates/show_system_power-supply.tpl @@ -0,0 +1,15 @@ +Value Member (\d) +Value PS (\d) +Value State (\S+) +Value Wattage (\d+) +Value Max (\d+) + +Start + ^.*Member\s+PS#\s+Model\s+Serial\s+State\s+AC\/DC\s+\+\sV\s+Wattage\s+Max -> Member + ^.*PS#\s+Model\s+Serial\s+State\s+AC\/DC\s+\+\sV\s+Wattage\s+Max -> Standalone + +Standalone + ^ ${PS}\s+\S+\s+\S+\s+${State}\s+\S\S\s\d+\S+\d+\S\s+${Wattage}\s+${Max} -> Record + +Member + ^ ${Member}\s+${PS}\s+\S+\s+\S+\s+${State}\s+\S\S\s\d+\S+\d+\S\s+${Wattage}\s+${Max} -> Record diff --git a/test/unit/utils/textfsm_templates/show_system_temperature.tpl b/test/unit/utils/textfsm_templates/show_system_temperature.tpl new file mode 100644 index 0000000..a858845 --- /dev/null +++ b/test/unit/utils/textfsm_templates/show_system_temperature.tpl @@ -0,0 +1,11 @@ +Value Filldown Member (\d) +Value Required Sensor (\S+) +Value Temperature (\d+) +Value OverTemp (YES|NO) + +Start + ^.*Air -> Temperature + +Temperature + ^ Member ${Member} + ^ ${Sensor}\s+${Temperature}\S\s+\d+\S\s+\d+\S\s+\d+\S\s+${OverTemp} -> Record \ No newline at end of file