From 83378fa7618053c57baca9414153ed6f51d41253 Mon Sep 17 00:00:00 2001 From: Michael Chus Date: Sun, 25 Jan 2026 09:24:36 +0300 Subject: [PATCH] Add firmware versions for all components Extract firmware from: - asset.json: BIOS, ME, BKC, CPU Microcode, HDD/SSD/NVMe - component.log: PSU firmware, Network adapter firmware Deduplicate entries to avoid showing same firmware twice. Co-Authored-By: Claude Opus 4.5 --- internal/parser/vendors/inspur/asset.go | 27 ++++++++++ internal/parser/vendors/inspur/component.go | 57 +++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/internal/parser/vendors/inspur/asset.go b/internal/parser/vendors/inspur/asset.go index e4d470b..f66829d 100644 --- a/internal/parser/vendors/inspur/asset.go +++ b/internal/parser/vendors/inspur/asset.go @@ -109,6 +109,7 @@ func ParseAssetJSON(content []byte) (*models.HardwareConfig, error) { } // Parse CPU info + seenMicrocode := make(map[string]bool) for i, cpu := range asset.CpuInfo { config.CPUs = append(config.CPUs, models.CPU{ Socket: i, @@ -123,6 +124,15 @@ func ParseAssetJSON(content []byte) (*models.HardwareConfig, error) { TDP: cpu.CpuTdp, PPIN: cpu.PPIN, }) + + // Add CPU microcode to firmware list (deduplicated) + if cpu.MicroCodeVer != "" && !seenMicrocode[cpu.MicroCodeVer] { + config.Firmware = append(config.Firmware, models.FirmwareInfo{ + DeviceName: fmt.Sprintf("CPU%d Microcode", i), + Version: cpu.MicroCodeVer, + }) + seenMicrocode[cpu.MicroCodeVer] = true + } } // Memory info is parsed from component.log (RESTful Memory info) which has more details @@ -148,6 +158,7 @@ func ParseAssetJSON(content []byte) (*models.HardwareConfig, error) { } // Parse storage info + seenHDDFW := make(map[string]bool) for _, hdd := range asset.HddInfo { storageType := "HDD" if hdd.DiskInterfaceType == 5 { @@ -170,6 +181,22 @@ func ParseAssetJSON(content []byte) (*models.HardwareConfig, error) { Firmware: hdd.FirmwareVersion, Interface: diskInterfaceToString(hdd.DiskInterfaceType), }) + + // Add HDD firmware to firmware list (deduplicated by model+version) + if hdd.FirmwareVersion != "" { + fwKey := modelName + ":" + hdd.FirmwareVersion + if !seenHDDFW[fwKey] { + slot := hdd.LocationString + if slot == "" { + slot = fmt.Sprintf("%s %dGB", storageType, hdd.Capacity) + } + config.Firmware = append(config.Firmware, models.FirmwareInfo{ + DeviceName: fmt.Sprintf("%s (%s)", modelName, slot), + Version: hdd.FirmwareVersion, + }) + seenHDDFW[fwKey] = true + } + } } // Parse PCIe info diff --git a/internal/parser/vendors/inspur/component.go b/internal/parser/vendors/inspur/component.go index f126567..3620f3c 100644 --- a/internal/parser/vendors/inspur/component.go +++ b/internal/parser/vendors/inspur/component.go @@ -29,6 +29,9 @@ func ParseComponentLog(content []byte, hw *models.HardwareConfig) { // Parse RESTful Network Adapter info parseNetworkAdapterInfo(text, hw) + + // Extract firmware from all components + extractComponentFirmware(text, hw) } // ParseComponentLogEvents extracts events from component.log (memory errors, etc.) @@ -363,3 +366,57 @@ func parseMemoryEvents(text string) []models.Event { return events } + +// extractComponentFirmware extracts firmware versions from all component data +func extractComponentFirmware(text string, hw *models.HardwareConfig) { + // Create a map to track existing firmware entries (avoid duplicates) + existingFW := make(map[string]bool) + for _, fw := range hw.Firmware { + existingFW[fw.DeviceName] = true + } + + // HDD firmware is already extracted from asset.json with better names + // Skip extracting from component.log to avoid duplicates + + // Extract PSU firmware from RESTful PSU info + rePSU := regexp.MustCompile(`RESTful PSU info:\s*(\{[\s\S]*?\})\s*RESTful Network`) + if match := rePSU.FindStringSubmatch(text); match != nil { + jsonStr := strings.ReplaceAll(match[1], "\n", "") + var psuInfo PSURESTInfo + if err := json.Unmarshal([]byte(jsonStr), &psuInfo); err == nil { + for _, psu := range psuInfo.PowerSupplies { + if psu.Present == 1 && psu.FwVer != "" { + fwName := fmt.Sprintf("PSU%d (%s)", psu.ID, psu.Model) + if !existingFW[fwName] { + hw.Firmware = append(hw.Firmware, models.FirmwareInfo{ + DeviceName: fwName, + Version: psu.FwVer, + }) + existingFW[fwName] = true + } + } + } + } + } + + // Extract Network Adapter firmware from RESTful Network Adapter info + reNet := regexp.MustCompile(`RESTful Network Adapter info:\s*(\{[\s\S]*?\})\s*RESTful fan`) + if match := reNet.FindStringSubmatch(text); match != nil { + jsonStr := strings.ReplaceAll(match[1], "\n", "") + var netInfo NetworkAdapterRESTInfo + if err := json.Unmarshal([]byte(jsonStr), &netInfo); err == nil { + for _, adapter := range netInfo.SysAdapters { + if adapter.Present == 1 && adapter.FwVer != "" && adapter.FwVer != "NA" { + fwName := fmt.Sprintf("NIC %s (%s)", adapter.Location, adapter.Model) + if !existingFW[fwName] { + hw.Firmware = append(hw.Firmware, models.FirmwareInfo{ + DeviceName: fwName, + Version: adapter.FwVer, + }) + existingFW[fwName] = true + } + } + } + } + } +}