diff --git a/netbox_agent/inventory.py b/netbox_agent/inventory.py index 173393a..ae2e785 100644 --- a/netbox_agent/inventory.py +++ b/netbox_agent/inventory.py @@ -4,6 +4,7 @@ import pynetbox from netbox_agent.config import netbox_instance as nb, config from netbox_agent.misc import is_tool, get_vendor from netbox_agent.raid.hp import HPRaid +from netbox_agent.raid.omreport import OmreportRaid from netbox_agent.raid.storcli import StorcliRaid from netbox_agent.lshw import LSHW @@ -216,6 +217,8 @@ class Inventory(): def get_raid_cards(self): if self.server.manufacturer == 'Dell': + if is_tool('omreport'): + self.raid = OmreportRaid() if is_tool('storcli'): self.raid = StorcliRaid() elif self.server.manufacturer == 'HP': diff --git a/netbox_agent/misc.py b/netbox_agent/misc.py index fe36410..f1345bb 100644 --- a/netbox_agent/misc.py +++ b/netbox_agent/misc.py @@ -8,6 +8,7 @@ def is_tool(name): def get_vendor(name): vendors = { + 'DELL': 'Dell', 'ST': 'Seagate', 'CRUCIAL': 'Crucial', 'MICRON': 'Micron', diff --git a/netbox_agent/raid/omreport.py b/netbox_agent/raid/omreport.py new file mode 100644 index 0000000..c26e1d6 --- /dev/null +++ b/netbox_agent/raid/omreport.py @@ -0,0 +1,77 @@ +import re +import subprocess +import xml.etree.ElementTree as ET # NOQA + +from netbox_agent.misc import get_vendor +from netbox_agent.raid.base import Raid, RaidController + +# Inspiration from https://github.com/asciiphil/perc-status/blob/master/perc-status + + +def get_field(obj, fieldname): + f = obj.find(fieldname) + if f is None: + return None + if f.attrib['type'] in ['u32', 'u64']: + if re.search('Mask$', fieldname): + return int(f.text, 2) + else: + return int(f.text) + if f.attrib['type'] == 'astring': + return f.text + return f.text + + +class OmreportController(RaidController): + def __init__(self, controller_index, data): + self.data = data + self.controller_index = controller_index + + def get_product_name(self): + return get_field(self.data, 'Name') + + def get_manufacturer(self): + return None + + def get_serial_number(self): + return get_field(self.data, 'DeviceSerialNumber') + + def get_firmware_version(self): + return get_field(self.data, 'Firmware Version') + + def get_physical_disks(self): + ret = [] + output = subprocess.getoutput( + 'omreport storage controller controller={} -fmt xml'.format(self.controller_index) + ) + root = ET.fromstring(output) + et_array_disks = root.find('ArrayDisks') + if et_array_disks is not None: + for obj in et_array_disks.findall('DCStorageObject'): + ret.append({ + 'Vendor': get_vendor(get_field(obj, 'Vendor')), + 'Model': get_field(obj, 'ProductID'), + 'SN': get_field(obj, 'DeviceSerialNumber'), + 'Size': '{:.0f}GB'.format( + int(get_field(obj, 'Length')) / 1024 / 1024 / 1024 + ), + 'Type': 'HDD' if int(get_field(obj, 'MediaType')) == 1 else 'SSD', + '_src': self.__class__.__name__, + }) + return ret + + +class OmreportRaid(Raid): + def __init__(self): + output = subprocess.getoutput('omreport storage controller -fmt xml') + controller_xml = ET.fromstring(output) + self.controllers = [] + + for obj in controller_xml.find('Controllers').findall('DCStorageObject'): + ctrl_index = get_field(obj, 'ControllerNum') + self.controllers.append( + OmreportController(ctrl_index, obj) + ) + + def get_controllers(self): + return self.controllers