2020-02-02 20:08:56 +01:00
|
|
|
from netbox_agent.raid.base import Raid, RaidController
|
2022-02-25 18:43:09 +01:00
|
|
|
from netbox_agent.misc import get_vendor
|
|
|
|
from netbox_agent.config import config
|
|
|
|
import subprocess
|
|
|
|
import logging
|
|
|
|
import re
|
2019-08-26 16:54:48 +02:00
|
|
|
|
|
|
|
REGEXP_CONTROLLER_HP = re.compile(r'Smart Array ([a-zA-Z0-9- ]+) in Slot ([0-9]+)')
|
|
|
|
|
|
|
|
|
2022-02-25 18:43:09 +01:00
|
|
|
def ssacli(command):
|
|
|
|
output = subprocess.getoutput('ssacli {}'.format(command) )
|
|
|
|
lines = output.split('\n')
|
|
|
|
lines = list(filter(None, lines))
|
|
|
|
return lines
|
|
|
|
|
|
|
|
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
def _parse_ctrl_output(lines):
|
|
|
|
controllers = {}
|
|
|
|
current_ctrl = None
|
2019-08-26 16:54:48 +02:00
|
|
|
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
for line in lines:
|
|
|
|
if not line or line.startswith('Note:'):
|
|
|
|
continue
|
|
|
|
ctrl = REGEXP_CONTROLLER_HP.search(line)
|
|
|
|
if ctrl is not None:
|
|
|
|
current_ctrl = ctrl.group(1)
|
2022-02-25 18:43:09 +01:00
|
|
|
controllers[current_ctrl] = {'Slot': ctrl.group(2)}
|
|
|
|
if 'Embedded' not in line:
|
|
|
|
controllers[current_ctrl]['External'] = True
|
2020-06-10 15:24:43 +02:00
|
|
|
continue
|
2022-02-25 18:43:09 +01:00
|
|
|
attr, val = line.split(': ', 1)
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
attr = attr.strip()
|
|
|
|
val = val.strip()
|
|
|
|
controllers[current_ctrl][attr] = val
|
|
|
|
return controllers
|
2020-06-10 15:24:43 +02:00
|
|
|
|
2019-08-26 16:54:48 +02:00
|
|
|
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
def _parse_pd_output(lines):
|
|
|
|
drives = {}
|
|
|
|
current_array = None
|
|
|
|
current_drv = None
|
2019-08-26 16:54:48 +02:00
|
|
|
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
for line in lines:
|
|
|
|
line = line.strip()
|
|
|
|
if not line or line.startswith('Note:'):
|
|
|
|
continue
|
|
|
|
# Parses the Array the drives are in
|
2022-02-25 18:43:09 +01:00
|
|
|
if line.startswith('Array'):
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
current_array = line.split(None, 1)[1]
|
|
|
|
# Detects new physical drive
|
2022-02-25 18:43:09 +01:00
|
|
|
if line.startswith('physicaldrive'):
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
current_drv = line.split(None, 1)[1]
|
|
|
|
drives[current_drv] = {}
|
|
|
|
if current_array is not None:
|
2022-02-25 18:43:09 +01:00
|
|
|
drives[current_drv]['Array'] = current_array
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
continue
|
2022-02-25 18:43:09 +01:00
|
|
|
if ': ' not in line:
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
continue
|
2022-02-25 18:43:09 +01:00
|
|
|
attr, val = line.split(': ', 1)
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
drives.setdefault(current_drv, {})[attr] = val
|
|
|
|
return drives
|
2019-08-26 16:54:48 +02:00
|
|
|
|
|
|
|
|
2022-02-25 18:43:09 +01:00
|
|
|
def _parse_ld_output(lines):
|
|
|
|
drives = {}
|
|
|
|
current_array = None
|
|
|
|
current_drv = None
|
|
|
|
|
|
|
|
for line in lines:
|
|
|
|
line = line.strip()
|
|
|
|
if not line or line.startswith('Note:'):
|
|
|
|
continue
|
|
|
|
# Parses the Array the drives are in
|
|
|
|
if line.startswith('Array'):
|
|
|
|
current_array = line.split(None, 1)[1]
|
|
|
|
drives[current_array] = {}
|
|
|
|
# Detects new physical drive
|
|
|
|
if line.startswith('Logical Drive'):
|
|
|
|
current_drv = line.split(': ', 1)[1]
|
|
|
|
drives.setdefault(current_array, {})['LogicalDrive'] = current_drv
|
|
|
|
continue
|
|
|
|
if ': ' not in line:
|
|
|
|
continue
|
|
|
|
attr, val = line.split(': ', 1)
|
|
|
|
drives.setdefault(current_array, {})[attr] = val
|
|
|
|
return drives
|
|
|
|
|
|
|
|
|
2019-08-26 16:54:48 +02:00
|
|
|
class HPRaidController(RaidController):
|
|
|
|
def __init__(self, controller_name, data):
|
|
|
|
self.controller_name = controller_name
|
|
|
|
self.data = data
|
2022-02-25 18:43:09 +01:00
|
|
|
self.pdrives = self._get_physical_disks()
|
|
|
|
self.ldrives = self._get_logical_drives()
|
|
|
|
self._get_virtual_drives_map()
|
2019-08-26 16:54:48 +02:00
|
|
|
|
|
|
|
def get_product_name(self):
|
|
|
|
return self.controller_name
|
|
|
|
|
|
|
|
def get_manufacturer(self):
|
|
|
|
return 'HP'
|
|
|
|
|
|
|
|
def get_serial_number(self):
|
|
|
|
return self.data['Serial Number']
|
|
|
|
|
|
|
|
def get_firmware_version(self):
|
|
|
|
return self.data['Firmware Version']
|
|
|
|
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
def is_external(self):
|
|
|
|
return self.data.get('External', False)
|
|
|
|
|
|
|
|
def _get_physical_disks(self):
|
2022-02-25 18:43:09 +01:00
|
|
|
lines = ssacli('ctrl slot={} pd all show detail'.format(self.data['Slot']))
|
|
|
|
pdrives = _parse_pd_output(lines)
|
|
|
|
ret = {}
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
|
2022-02-25 18:43:09 +01:00
|
|
|
for name, attrs in pdrives.items():
|
|
|
|
array = attrs.get('Array', '')
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
model = attrs.get('Model', '').strip()
|
|
|
|
vendor = None
|
|
|
|
if model.startswith('HP'):
|
|
|
|
vendor = 'HP'
|
|
|
|
elif len(model.split()) > 1:
|
|
|
|
vendor = get_vendor(model.split()[1])
|
|
|
|
else:
|
|
|
|
vendor = get_vendor(model)
|
|
|
|
|
2022-02-25 18:43:09 +01:00
|
|
|
ret[name] = {
|
|
|
|
'Array': array,
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
'Model': model,
|
|
|
|
'Vendor': vendor,
|
|
|
|
'SN': attrs.get('Serial Number', '').strip(),
|
|
|
|
'Size': attrs.get('Size', '').strip(),
|
|
|
|
'Type': 'SSD' if attrs.get('Interface Type') == 'Solid State SATA'
|
|
|
|
else 'HDD',
|
|
|
|
'_src': self.__class__.__name__,
|
2022-02-25 18:43:09 +01:00
|
|
|
}
|
2019-08-26 16:54:48 +02:00
|
|
|
return ret
|
|
|
|
|
2022-02-25 18:43:09 +01:00
|
|
|
def _get_logical_drives(self):
|
|
|
|
lines = ssacli('ctrl slot={} ld all show detail'.format(self.data['Slot']))
|
|
|
|
ldrives = _parse_ld_output(lines)
|
|
|
|
ret = {}
|
|
|
|
|
|
|
|
for array, attrs in ldrives.items():
|
|
|
|
ret[array] = {
|
|
|
|
'vd_array': array,
|
|
|
|
'vd_size': attrs['Size'],
|
|
|
|
'vd_consistency': attrs['Status'],
|
|
|
|
'vd_raid_type': 'RAID {}'.format(attrs['Fault Tolerance']),
|
|
|
|
'vd_device': attrs['LogicalDrive'],
|
|
|
|
'mount_point': attrs['Mount Points']
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
|
|
|
|
def _get_virtual_drives_map(self):
|
|
|
|
for name, attrs in self.pdrives.items():
|
|
|
|
array = attrs["Array"]
|
|
|
|
ld = self.ldrives.get(array)
|
|
|
|
if ld is None:
|
|
|
|
logging.error(
|
|
|
|
"Failed to find array information for physical drive {}."
|
|
|
|
" Ignoring.".format(name)
|
|
|
|
)
|
|
|
|
continue
|
|
|
|
attrs['custom_fields'] = ld
|
|
|
|
attrs['custom_fields']['pd_identifier'] = name
|
|
|
|
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
def get_physical_disks(self):
|
2022-02-25 18:43:09 +01:00
|
|
|
return list(self.pdrives.values())
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
|
2019-08-26 16:54:48 +02:00
|
|
|
|
|
|
|
class HPRaid(Raid):
|
|
|
|
def __init__(self):
|
|
|
|
self.output = subprocess.getoutput('ssacli ctrl all show detail')
|
|
|
|
self.controllers = []
|
|
|
|
self.convert_to_dict()
|
|
|
|
|
|
|
|
def convert_to_dict(self):
|
|
|
|
lines = self.output.split('\n')
|
|
|
|
lines = list(filter(None, lines))
|
Manage blade expansions as independent devices
This patch adds the ability to detect and manage GPU and Disk expansion
bays, and either add their internal components into the device
corresponding to the blade server, or into a dedicated device.
It takes advantage of the work made by @cyrinux on GPU bays management, and
applies the same principle to the external disk bays, but harmonize the
inventory management:
- If no argument is specified on the command line, the GPU cards, RAID
controllers and their attached disks are added in the blade device,
and the device corresponding to an expansion device is deleted.
- If the `--expansion-as-device` option is specified on the command
line, a dedicated device corresponding to the expansion bay is
created, and the GPUs, RAID card and attached disks are removed from
the blade device and added to the expansion device.
2022-02-11 18:22:13 +01:00
|
|
|
controllers = _parse_ctrl_output(lines)
|
|
|
|
for controller, attrs in controllers.items():
|
|
|
|
self.controllers.append(
|
|
|
|
HPRaidController(controller, attrs)
|
|
|
|
)
|
2019-08-26 16:54:48 +02:00
|
|
|
|
|
|
|
def get_controllers(self):
|
|
|
|
return self.controllers
|