Skip to content

Instantly share code, notes, and snippets.

@pcuzner
Created May 8, 2019 01:56
Show Gist options
  • Save pcuzner/6d76e5a4917744f3130d347bfb3971e5 to your computer and use it in GitHub Desktop.
Save pcuzner/6d76e5a4917744f3130d347bfb3971e5 to your computer and use it in GitHub Desktop.
redfish example getting host and low level disk information from a server (tested on iDRAC9)
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
import os
import sys
import json
import time
import humanize
import progressbar
# turn off insecure warnings since BMC is self signed
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# How to run;
# USER=root PASSWORD=mysecret URL=https://myservers-bmc.mydomain.com python fetch_disks.py
#
# Output will be something like this;
# USER=root PASSWORD=mysecret URL=https://myserver python fetch_disks.py
# Processing host redfish URL : https://myserver
# Fetching System state (2.55s)
# Fetching storage controller list (1.82s)
# Walking 6 storage controllers 100% |#################################################################| Time: 0:00:10
# Walking 12 disk drives 100% |#################################################################| Time: 0:00:22
# Processing complete @ Wed May 8 13:50:53 2019, elapsed time 37s
# Host:
# - Model: PowerEdge R640
# - LED: Off
# - CPUs: 2 - Intel(R) Xeon(R) Gold 6130 CPU @ 2.10GHz
# - PSUs: 2
# - Power state: On
# Drive Status
# Drive Controller Health Type Capacity RPM Life Pred. Fail Vendor Model Firmware Part#
# bla!
USER = os.environ.get("USER", 'root')
PASSWORD = os.environ.get("PASSWORD", "MYSECRET")
baseURL = os.environ.get("URL")
system = "/redfish/v1/Systems/System.Embedded.1"
storage = "/redfish/v1/Systems/System.Embedded.1/Storage"
pbar_widgets = ["dummy",
progressbar.Percentage(), " ",
progressbar.Bar(), " ",
progressbar.ETA()]
def api_call(url, description=None):
start = time.time()
if description:
sys.stdout.write("{}\r".format(description))
sys.stdout.flush()
response = requests.get(url, verify=False, auth=(USER, PASSWORD))
if description:
print("{} ({:.2f}s)".format(description, time.time() - start))
return response.json()
start_time = time.time()
print("\nProcessing host redfish URL : {}\n".format(baseURL))
raw_system_state = api_call(baseURL+system, "Fetching System state")
raw_storage_links = api_call(baseURL+storage, "Fetching storage controller list")
drive_list = []
controller_list = raw_storage_links.get(u'Members')
num_controllers = len(controller_list)
# walking storage controllers
pbar_widgets[0] = "Walking {} storage controllers ".format(num_controllers).ljust(30)
pbar = progressbar.ProgressBar(widgets=pbar_widgets)
for cntlr in pbar(controller_list):
url = baseURL + cntlr[u'@odata.id']
response = api_call(url)
controller = response[u'Name']
if response.get(u'Drives'):
for drive in response.get(u'Drives'):
drive_list.append((controller, drive))
# get Drives
drive_data = {}
keys = [u'SerialNumber', u'PartNumber', u'Manufacturer', u'MediaType', u'Model', u'FailurePredicted', u'CapacityBytes', u'RotationSpeedRPM', u'Status', u'PredictedMediaLifeLeftPercent', u'Revision']
pbar_widgets[0] = "Walking {} disk drives ".format(len(drive_list)).ljust(30)
pbar = progressbar.ProgressBar(widgets=pbar_widgets)
for controller, drive in pbar(drive_list):
metadata = api_call(baseURL + drive[u'@odata.id'])
drive_data[metadata[u'Name']] = {_k:metadata[_k] for _k in keys}
drive_data[metadata[u'Name']][u'Controller'] = controller
elapsed = int(time.time() - start_time)
print("\nProcessing complete @ {}, elapsed time {}s".format(time.asctime(), elapsed))
# Show the results
print("\nHost:")
print(" - Model: {}".format(raw_system_state.get('Model')))
print(" - LED: {}".format(raw_system_state.get('IndicatorLED')))
print(" - CPUs: {} - {}".format(raw_system_state.get('ProcessorSummary')['Count'],
raw_system_state.get('ProcessorSummary')['Model']))
print(" - PSUs: {}".format(raw_system_state.get('Links')['PoweredBy@odata.count']))
print(" - Power state: {}".format(raw_system_state.get('PowerState')))
print("\nDrive Status")
fmt = "{0:<32} {1:<20} {2:^8} {3:^4} {4:>10} {5:>5} {6:>4} {7:^10} {8:<12} {9:<42} {10:>10} {11:>32}"
print(fmt.format("Drive", "Controller", "Health", "Type", "Capacity", "RPM", "Life", "Pred. Fail", "Vendor", "Model", "Firmware", "Part#"))
for k in sorted(drive_data):
_d = drive_data[k]
print(fmt.format(k,
_d[u'Controller'],
_d[u'Status'][u'Health'],
_d[u'MediaType'],
humanize.naturalsize(_d[u'CapacityBytes']),
_d[u'RotationSpeedRPM'],
("N/A" if _d[u'MediaType'] == 'HDD' else _d[u'PredictedMediaLifeLeftPercent']),
("YES" if _d[u'FailurePredicted'] else "NO"),
_d[u'Manufacturer'],
_d[u'Model'],
_d[u'Revision'],
_d[u'PartNumber']))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment