feat: improve inspur parsing and pci.ids integration
This commit is contained in:
@@ -309,6 +309,23 @@ func (s *Server) handleGetSerials(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
var serials []SerialEntry
|
||||
seenByLocationSerial := make(map[string]bool)
|
||||
markSeen := func(location, serial string) {
|
||||
loc := strings.ToLower(strings.TrimSpace(location))
|
||||
sn := strings.ToLower(strings.TrimSpace(serial))
|
||||
if loc == "" || sn == "" {
|
||||
return
|
||||
}
|
||||
seenByLocationSerial[loc+"|"+sn] = true
|
||||
}
|
||||
alreadySeen := func(location, serial string) bool {
|
||||
loc := strings.ToLower(strings.TrimSpace(location))
|
||||
sn := strings.ToLower(strings.TrimSpace(serial))
|
||||
if loc == "" || sn == "" {
|
||||
return false
|
||||
}
|
||||
return seenByLocationSerial[loc+"|"+sn]
|
||||
}
|
||||
|
||||
// From FRU
|
||||
for _, fru := range result.FRU {
|
||||
@@ -403,6 +420,7 @@ func (s *Server) handleGetSerials(w http.ResponseWriter, r *http.Request) {
|
||||
Manufacturer: gpu.Manufacturer,
|
||||
Category: "GPU",
|
||||
})
|
||||
markSeen(gpu.Slot, gpu.SerialNumber)
|
||||
}
|
||||
|
||||
// PCIe devices
|
||||
@@ -410,7 +428,10 @@ func (s *Server) handleGetSerials(w http.ResponseWriter, r *http.Request) {
|
||||
if !hasUsableSerial(pcie.SerialNumber) {
|
||||
continue
|
||||
}
|
||||
component := pcie.DeviceClass
|
||||
if alreadySeen(pcie.Slot, pcie.SerialNumber) {
|
||||
continue
|
||||
}
|
||||
component := normalizePCIeSerialComponentName(pcie)
|
||||
if strings.EqualFold(strings.TrimSpace(pcie.DeviceClass), "NVSwitch") && strings.TrimSpace(pcie.PartNumber) != "" {
|
||||
component = strings.TrimSpace(pcie.PartNumber)
|
||||
}
|
||||
@@ -422,6 +443,7 @@ func (s *Server) handleGetSerials(w http.ResponseWriter, r *http.Request) {
|
||||
PartNumber: pcie.PartNumber,
|
||||
Category: "PCIe",
|
||||
})
|
||||
markSeen(pcie.Slot, pcie.SerialNumber)
|
||||
}
|
||||
|
||||
// Network cards
|
||||
@@ -431,9 +453,11 @@ func (s *Server) handleGetSerials(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
serials = append(serials, SerialEntry{
|
||||
Component: nic.Model,
|
||||
Location: nic.Name,
|
||||
SerialNumber: strings.TrimSpace(nic.SerialNumber),
|
||||
Category: "Network",
|
||||
})
|
||||
markSeen(nic.Name, nic.SerialNumber)
|
||||
}
|
||||
|
||||
// Power supplies
|
||||
@@ -454,6 +478,28 @@ func (s *Server) handleGetSerials(w http.ResponseWriter, r *http.Request) {
|
||||
jsonResponse(w, serials)
|
||||
}
|
||||
|
||||
func normalizePCIeSerialComponentName(p models.PCIeDevice) string {
|
||||
className := strings.TrimSpace(p.DeviceClass)
|
||||
part := strings.TrimSpace(p.PartNumber)
|
||||
if part != "" && !strings.EqualFold(part, className) {
|
||||
return part
|
||||
}
|
||||
lowerClass := strings.ToLower(className)
|
||||
switch lowerClass {
|
||||
case "display", "display controller", "3d controller", "vga", "network", "network controller", "pcie device", "other", "unknown", "":
|
||||
if part != "" {
|
||||
return part
|
||||
}
|
||||
}
|
||||
if className != "" {
|
||||
return className
|
||||
}
|
||||
if part != "" {
|
||||
return part
|
||||
}
|
||||
return "PCIe device"
|
||||
}
|
||||
|
||||
func hasUsableSerial(serial string) bool {
|
||||
s := strings.TrimSpace(serial)
|
||||
if s == "" {
|
||||
@@ -474,33 +520,70 @@ func (s *Server) handleGetFirmware(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(w, buildFirmwareEntries(result.Hardware))
|
||||
}
|
||||
|
||||
type firmwareEntry struct {
|
||||
Component string `json:"component"`
|
||||
Model string `json:"model"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
func buildFirmwareEntries(hw *models.HardwareConfig) []firmwareEntry {
|
||||
if hw == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deduplicate firmware by extracting model name and version
|
||||
// E.g., "PSU0 (AP-CR3000F12BY)" and "PSU1 (AP-CR3000F12BY)" with same version -> one entry
|
||||
type FirmwareEntry struct {
|
||||
Component string `json:"component"`
|
||||
Model string `json:"model"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
seen := make(map[string]bool)
|
||||
var deduplicated []FirmwareEntry
|
||||
var deduplicated []firmwareEntry
|
||||
|
||||
for _, fw := range result.Hardware.Firmware {
|
||||
// Extract component type and model from device name
|
||||
component, model := extractFirmwareComponentAndModel(fw.DeviceName)
|
||||
key := component + "|" + model + "|" + fw.Version
|
||||
|
||||
if !seen[key] {
|
||||
seen[key] = true
|
||||
deduplicated = append(deduplicated, FirmwareEntry{
|
||||
Component: component,
|
||||
Model: model,
|
||||
Version: fw.Version,
|
||||
})
|
||||
appendEntry := func(component, model, version string) {
|
||||
component = strings.TrimSpace(component)
|
||||
model = strings.TrimSpace(model)
|
||||
version = strings.TrimSpace(version)
|
||||
if component == "" || version == "" {
|
||||
return
|
||||
}
|
||||
if model == "" {
|
||||
model = "-"
|
||||
}
|
||||
key := component + "|" + model + "|" + version
|
||||
if seen[key] {
|
||||
return
|
||||
}
|
||||
seen[key] = true
|
||||
deduplicated = append(deduplicated, firmwareEntry{
|
||||
Component: component,
|
||||
Model: model,
|
||||
Version: version,
|
||||
})
|
||||
}
|
||||
|
||||
jsonResponse(w, deduplicated)
|
||||
for _, fw := range hw.Firmware {
|
||||
component, model := extractFirmwareComponentAndModel(fw.DeviceName)
|
||||
appendEntry(component, model, fw.Version)
|
||||
}
|
||||
|
||||
// Fallback for parsers that fill GPU firmware on device inventory only
|
||||
// (e.g. runtime enrichment from redis/HGX) without explicit Hardware.Firmware entries.
|
||||
for _, gpu := range hw.GPUs {
|
||||
version := strings.TrimSpace(gpu.Firmware)
|
||||
if version == "" {
|
||||
continue
|
||||
}
|
||||
model := strings.TrimSpace(gpu.PartNumber)
|
||||
if model == "" {
|
||||
model = strings.TrimSpace(gpu.Model)
|
||||
}
|
||||
if model == "" {
|
||||
model = strings.TrimSpace(gpu.Slot)
|
||||
}
|
||||
appendEntry("GPU", model, version)
|
||||
}
|
||||
|
||||
return deduplicated
|
||||
}
|
||||
|
||||
// extractFirmwareComponentAndModel extracts the component type and model from firmware device name
|
||||
|
||||
Reference in New Issue
Block a user