fix(collector): surface RAID/HBA controller cards from Storage.StorageControllers[]
The RAID controller (XFusion XC170-M-8i / Broadcom SAS3808) never appeared in inventory at all: it isn't listed in any Chassis/Systems PCIeDevices collection on this BMC, and its dedicated Board resource link 404s (id contains parentheses, same class of bug as the OCP NIC fixed earlier). Its full identity -- model, firmware, BDF, vendor/device IDs -- was sitting unread in the Storage resource's embedded StorageControllers[] array the whole time. Added parseStorageControllerPCIeDevice + collectStorageControllers to read that array and surface the controller as a PCIeDevice entry, merged into the existing pcie_devices list. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
1e4ec513e1
commit
6599ab49c2
@@ -4552,6 +4552,52 @@ func parsePCIeFunctionWithSupplementalDocs(doc map[string]interface{}, supplemen
|
||||
return dev
|
||||
}
|
||||
|
||||
// parseStorageControllerPCIeDevice builds a PCIeDevice entry from a
|
||||
// Storage.StorageControllers[] array member (Redfish's dedicated RAID/HBA
|
||||
// controller resource). Some BMCs (e.g. xFusion) never expose this
|
||||
// controller as a standalone PCIeDevice/Board resource — its Board link can
|
||||
// even 404 (id containing parentheses) — so without reading this embedded
|
||||
// array the RAID controller card never appears in inventory at all, even
|
||||
// though its identity (model, firmware, BDF, vendor/device IDs) is fully
|
||||
// present right here.
|
||||
func parseStorageControllerPCIeDevice(ctrl map[string]interface{}) models.PCIeDevice {
|
||||
oem := redfishOEMxFusionSection(ctrl)
|
||||
|
||||
dev := models.PCIeDevice{
|
||||
Slot: firstNonEmpty(
|
||||
asString(ctrl["CardModel"]),
|
||||
asString(ctrl["Name"]),
|
||||
asString(ctrl["MemberId"]),
|
||||
),
|
||||
BDF: sanitizeRedfishBDF(asString(oem["BDF"])),
|
||||
DeviceClass: "RAIDController",
|
||||
Manufacturer: firstNonEmpty(asString(ctrl["Manufacturer"]), asString(ctrl["CardManufacturer"])),
|
||||
Model: firstNonEmpty(asString(ctrl["CardModel"]), asString(oem["Type"])),
|
||||
Firmware: asString(ctrl["FirmwareVersion"]),
|
||||
PartNumber: normalizeRedfishIdentityField(asString(ctrl["PartNumber"])),
|
||||
SerialNumber: findFirstNormalizedStringByKeys(ctrl, "SerialNumber"),
|
||||
VendorID: asHexOrInt(oem["VenderID"]),
|
||||
DeviceID: asHexOrInt(oem["DeviceID"]),
|
||||
Status: mapStatus(ctrl["Status"]),
|
||||
}
|
||||
if dev.Slot == "" {
|
||||
dev.Slot = "RAIDController"
|
||||
}
|
||||
return dev
|
||||
}
|
||||
|
||||
func redfishOEMxFusionSection(doc map[string]interface{}) map[string]interface{} {
|
||||
oem, ok := doc["Oem"].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
xfusion, ok := oem["xFusion"].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return xfusion
|
||||
}
|
||||
|
||||
func isMissingOrRawPCIModel(model string) bool {
|
||||
model = strings.TrimSpace(model)
|
||||
if model == "" {
|
||||
|
||||
Reference in New Issue
Block a user