Skip to content

[psushow] Add more output columns; Add option to output in JSON format #1416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Feb 25, 2021
147 changes: 104 additions & 43 deletions scripts/psushow
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
#!/usr/bin/env python3

import argparse
import json
import sys
import os

from swsscommon.swsscommon import SonicV2Connector
from tabulate import tabulate

# mock the redis for unit test purposes #
try:
if os.environ["UTILITIES_UNIT_TESTING"] == "1":
modules_path = os.path.join(os.path.dirname(__file__), "..")
test_path = os.path.join(modules_path, "tests")
sys.path.insert(0, modules_path)
sys.path.insert(0, test_path)
import mock_tables.dbconnector
except KeyError:
pass
VERSION = '1.0'

from swsscommon.swsscommon import SonicV2Connector

def psu_status_show(index):

def get_psu_status_list():
psu_status_list = []

db = SonicV2Connector(host="127.0.0.1")
db.connect(db.STATE_DB)

Expand All @@ -27,59 +22,125 @@ def psu_status_show(index):
chassis_name = "chassis {}".format(chassis_num)
num_psus = db.get(db.STATE_DB, 'CHASSIS_INFO|{}'.format(chassis_name), 'psu_num')
if not num_psus:
print("Error! Failed to get the number of PSUs!")
return -1
print('Error: Failed to get the number of PSUs')
return None

supported_psu = range(1, int(num_psus) + 1)
if (index < 0):
psu_ids = supported_psu
else:
psu_ids = [index]
for psu_idx in range(1, int(num_psus) + 1):
psu_status = {}

header = ['PSU', 'Status', 'LED']
status_table = []
psu_status['index'] = str(psu_idx)

psu_name = 'PSU {}'.format(psu_idx)
psu_status['name'] = psu_name

for psu in psu_ids:
msg = ""
psu_name = "PSU {}".format(psu)
if psu not in supported_psu:
print("Error! The {} is not available on the platform.\n"
"Number of supported PSU - {}.".format(psu_name, num_psus))
continue
presence = db.get(db.STATE_DB, 'PSU_INFO|{}'.format(psu_name), 'presence')
psu_status['presence'] = presence

if presence == 'true':
oper_status = db.get(db.STATE_DB, 'PSU_INFO|{}'.format(psu_name), 'status')
msg = 'OK' if oper_status == 'true' else "NOT OK"
status = 'OK' if oper_status == 'true' else "NOT OK"
else:
msg = 'NOT PRESENT'
led_status = db.get(db.STATE_DB, 'PSU_INFO|{}'.format(psu_name), 'led_status')
status_table.append([psu_name, msg, led_status])
status = 'NOT PRESENT'
psu_status['status'] = status

psu_status['led_status'] = db.get(db.STATE_DB, 'PSU_INFO|{}'.format(psu_name), 'led_status')

psu_status['model'] = db.get(db.STATE_DB, 'PSU_INFO|{}'.format(psu_name), 'model') if presence else 'N/A'
psu_status['serial'] = db.get(db.STATE_DB, 'PSU_INFO|{}'.format(psu_name), 'serial') if presence else 'N/A'
psu_status['voltage'] = db.get(db.STATE_DB, 'PSU_INFO|{}'.format(psu_name), 'voltage') if presence else 'N/A'
psu_status['current'] = db.get(db.STATE_DB, 'PSU_INFO|{}'.format(psu_name), 'current') if presence else 'N/A'
psu_status['power'] = db.get(db.STATE_DB, 'PSU_INFO|{}'.format(psu_name), 'power') if presence else 'N/A'

psu_status_list.append(psu_status)

return psu_status_list


def psu_status_show_table(index):
psu_status_list = get_psu_status_list()

if not psu_status_list:
print('Error: Failed to get PSU status')
return None

header = ['PSU', 'Model', 'Serial', 'Voltage (V)', 'Current (A)', 'Power (W)', 'Status', 'LED']
status_table = []

if index > 0:
if index > len(psu_status_list):
print("Error: PSU {} is not available. Number of supported PSUs: {}".format(index, len(psu_status_list)))
return -1

# Trim the list down to contain only the requested PSU
psu_status_list = [psu_status_list[index-1]]

for psu_status in psu_status_list:
status_table.append([psu_status['name'],
psu_status['model'],
psu_status['serial'],
psu_status['voltage'],
psu_status['current'],
psu_status['power'],
psu_status['status'],
psu_status['led_status']])

if status_table:
print(tabulate(status_table, header, tablefmt="simple"))
print(tabulate(status_table, header, tablefmt="simple", floatfmt='.2f'))

return 0


def psu_status_show_json(index):
psu_status_list = get_psu_status_list()

if not psu_status_list:
print('Error: Failed to get PSU status')
return None

if index > 0:
if index > len(psu_status_list):
print("Error: PSU {} is not available. Number of supported PSUs: {}".format(index, len(psu_status_list)))
return -1

# Trim the list down to contain only the requested PSU
psu_status_list = [psu_status_list[index-1]]

print(json.dumps(psu_status_list, indent=4))
return 0


def main():
parser = argparse.ArgumentParser(description='Display the psu status information',
formatter_class=argparse.RawTextHelpFormatter,
epilog="""
Examples:
psushow -s
psushow -s -j
psushow -s -i 1
""")

parser.add_argument('-s', '--status', action='store_true', help='show the status information')
parser.add_argument('-i', '--index', type=int, default=-1, help='the index of psu')
parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.0')
parser.add_argument('-s', '--status', action='store_true', help='Show PSU status information')
parser.add_argument('-i', '--index', type=int, default=-1, help='The index of PSU to display')
parser.add_argument('-j', '--json', action='store_true', help='Display output in JSON format')
parser.add_argument('-v', '--version', action='version', version='%(prog)s {}'.format(VERSION))
args = parser.parse_args()

status_show = args.status
psu_index = args.index
output_json = args.json

if status_show:
err = psu_status_show(psu_index)
if err:
print("Error: fail to get psu status from state DB")
sys.exit(1)
if output_json:
ret = psu_status_show_json(psu_index)
else:
ret = psu_status_show_table(psu_index)

if __name__ == "__main__":
main()
if ret != 0:
print("Error: failed to get PSU status from state DB")
return 1

return 0


if __name__ == "__main__":
sys.exit(main())
8 changes: 6 additions & 2 deletions show/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def platform():

# 'summary' subcommand ("show platform summary")
@platform.command()
@click.option('--json', is_flag=True, help="JSON output")
@click.option('--json', is_flag=True, help="Output in JSON format")
def summary(json):
"""Show hardware platform information"""

Expand Down Expand Up @@ -69,14 +69,18 @@ def syseeprom(verbose):
# 'psustatus' subcommand ("show platform psustatus")
@platform.command()
@click.option('-i', '--index', default=-1, type=int, help="the index of PSU")
@click.option('--json', is_flag=True, help="Output in JSON format")
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def psustatus(index, verbose):
def psustatus(index, json, verbose):
"""Show PSU status information"""
cmd = "psushow -s"

if index >= 0:
cmd += " -i {}".format(index)

if json:
cmd += " -j"

clicommon.run_command(cmd, display_cmd=verbose)


Expand Down
20 changes: 20 additions & 0 deletions tests/mock_tables/state_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,31 @@
"PSU_INFO|PSU 1": {
"presence": "true",
"status": "true",
"model": "0J6J4K",
"serial": "CN-0J6J4K-17972-5AF-0086-A00",
"temp": "None",
"temp_threshold": "None",
"voltage": "12.19",
"voltage_min_threshold": "None",
"voltage_max_threshold": "None",
"current": "8.37",
"power": "102.7",
"is_replaceable": "False",
"led_status": "green"
},
"PSU_INFO|PSU 2": {
"presence": "true",
"status": "true",
"model": "0J6J4K",
"serial": "CN-0J6J4K-17972-5AF-008M-A00",
"temp": "None",
"temp_threshold": "None",
"voltage": "12.18",
"voltage_min_threshold": "None",
"voltage_max_threshold": "None",
"current": "10.07",
"power": "122.0",
"is_replaceable": "False",
"led_status": "green"
},

Expand Down
51 changes: 0 additions & 51 deletions tests/psu_test.py

This file was deleted.

Loading