2f09cf8d42
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.
115 lines
4.1 KiB
Python
115 lines
4.1 KiB
Python
import netbox_agent.dmidecode as dmidecode
|
|
from netbox_agent.server import ServerBase
|
|
|
|
|
|
class HPHost(ServerBase):
|
|
def __init__(self, *args, **kwargs):
|
|
super(HPHost, self).__init__(*args, **kwargs)
|
|
self.manufacturer = "HP"
|
|
self.product = self.get_product_name()
|
|
if self.is_blade():
|
|
self.hp_rack_locator = self._find_rack_locator()
|
|
|
|
def is_blade(self):
|
|
blade = self.product.startswith("ProLiant BL")
|
|
blade |= (self.product.startswith("ProLiant m")
|
|
and self.product.endswith("Server Cartridge"))
|
|
return blade
|
|
|
|
def _find_rack_locator(self):
|
|
"""
|
|
Depending on the server, the type of the `HP ProLiant System/Rack Locator`
|
|
can change.
|
|
So we need to find it every time
|
|
"""
|
|
# FIXME: make a dmidecode function get_by_dminame() ?
|
|
if self.is_blade():
|
|
locator = dmidecode.get_by_type(self.dmi, 204)
|
|
if self.product.startswith("ProLiant BL460c Gen10"):
|
|
locator = locator[0]["Strings"]
|
|
return {
|
|
"Enclosure Model": locator[2].strip(),
|
|
"Enclosure Name": locator[0].strip(),
|
|
"Server Bay": locator[3].strip(),
|
|
"Enclosure Serial": locator[4].strip(),
|
|
}
|
|
|
|
# HP ProLiant m750, m710x, m510 Server Cartridge
|
|
if self.product.startswith("ProLiant m") and self.product.endswith("Server Cartridge"):
|
|
locator = dmidecode.get_by_type(self.dmi, 2)
|
|
chassis = dmidecode.get_by_type(self.dmi, 3)
|
|
return {
|
|
"Enclosure Model": "Moonshot 1500 Chassis",
|
|
"Enclosure Name": "Unknown",
|
|
"Server Bay": locator[0]["Location In Chassis"].strip(),
|
|
"Enclosure Serial": chassis[0]["Serial Number"].strip(),
|
|
}
|
|
|
|
return locator[0]
|
|
|
|
def get_blade_slot(self):
|
|
if self.is_blade():
|
|
return "Bay {}".format(str(self.hp_rack_locator["Server Bay"].strip()))
|
|
return None
|
|
|
|
def get_chassis(self):
|
|
if self.is_blade():
|
|
return self.hp_rack_locator["Enclosure Model"].strip()
|
|
return self.get_product_name()
|
|
|
|
def get_chassis_name(self):
|
|
if not self.is_blade():
|
|
return None
|
|
return self.hp_rack_locator["Enclosure Name"].strip()
|
|
|
|
def get_chassis_service_tag(self):
|
|
if self.is_blade():
|
|
return self.hp_rack_locator["Enclosure Serial"].strip()
|
|
return self.get_service_tag()
|
|
|
|
def get_blade_expansion_slot(self):
|
|
"""
|
|
Expansion slot are always the compute bay number + 1
|
|
"""
|
|
if self.is_blade() and self.own_gpu_expansion_slot() or \
|
|
self.own_disk_expansion_slot() or True:
|
|
return 'Bay {}'.format(
|
|
str(int(self.hp_rack_locator['Server Bay'].strip()) + 1)
|
|
)
|
|
return None
|
|
|
|
def get_expansion_product(self):
|
|
"""
|
|
Get the extension slot that is on a pair slot number
|
|
next to the compute slot that is on an odd slot number
|
|
I only know on model of slot GPU extension card that.
|
|
"""
|
|
if self.own_gpu_expansion_slot():
|
|
return "ProLiant BL460c Graphics Expansion Blade"
|
|
elif self.own_disk_expansion_slot():
|
|
return "ProLiant BL460c Disk Expansion Blade"
|
|
return None
|
|
|
|
def own_expansion_slot(self):
|
|
"""
|
|
Say if the device can host an extension card based
|
|
on the product name
|
|
"""
|
|
return self.own_gpu_expansion_slot() or self.own_disk_expansion_slot()
|
|
|
|
def own_gpu_expansion_slot(self):
|
|
"""
|
|
Say if the device can host an extension card based
|
|
on the product name
|
|
"""
|
|
return self.get_product_name().endswith('Graphics Exp')
|
|
|
|
def own_disk_expansion_slot(self):
|
|
"""
|
|
Say if the device can host an extension card based
|
|
on the product name
|
|
"""
|
|
for raid_card in self.inventory.get_raid_cards():
|
|
if self.is_blade() and raid_card.is_external():
|
|
return True
|
|
return False
|