feat: improve inspur parsing and pci.ids integration

This commit is contained in:
2026-02-17 18:09:36 +03:00
parent b33cca5fcc
commit 758fa66282
26 changed files with 43567 additions and 247 deletions

View File

@@ -17,6 +17,7 @@ import (
"time"
"git.mchus.pro/mchus/logpile/internal/models"
"git.mchus.pro/mchus/logpile/internal/parser/vendors/pciids"
)
type RedfishConnector struct {
@@ -725,12 +726,27 @@ func parseDrive(doc map[string]interface{}) models.Storage {
}
func parseNIC(doc map[string]interface{}) models.NetworkAdapter {
vendorID := asHexOrInt(doc["VendorId"])
deviceID := asHexOrInt(doc["DeviceId"])
model := firstNonEmpty(asString(doc["Model"]), asString(doc["Name"]))
if isMissingOrRawPCIModel(model) {
if resolved := pciids.DeviceName(vendorID, deviceID); resolved != "" {
model = resolved
}
}
vendor := asString(doc["Manufacturer"])
if strings.TrimSpace(vendor) == "" {
vendor = pciids.VendorName(vendorID)
}
return models.NetworkAdapter{
Slot: firstNonEmpty(asString(doc["Id"]), asString(doc["Name"])),
Location: asString(doc["Location"]),
Present: !strings.EqualFold(mapStatus(doc["Status"]), "Absent"),
Model: firstNonEmpty(asString(doc["Model"]), asString(doc["Name"])),
Vendor: asString(doc["Manufacturer"]),
Model: strings.TrimSpace(model),
Vendor: strings.TrimSpace(vendor),
VendorID: vendorID,
DeviceID: deviceID,
SerialNumber: asString(doc["SerialNumber"]),
PartNumber: asString(doc["PartNumber"]),
Status: mapStatus(doc["Status"]),
@@ -824,6 +840,15 @@ func parseGPU(doc map[string]interface{}, functionDocs []map[string]interface{},
}
}
if isMissingOrRawPCIModel(gpu.Model) {
if resolved := pciids.DeviceName(gpu.VendorID, gpu.DeviceID); resolved != "" {
gpu.Model = resolved
}
}
if strings.TrimSpace(gpu.Manufacturer) == "" {
gpu.Manufacturer = pciids.VendorName(gpu.VendorID)
}
return gpu
}
@@ -869,6 +894,17 @@ func parsePCIeDevice(doc map[string]interface{}, functionDocs []map[string]inter
if dev.DeviceClass == "" {
dev.DeviceClass = "PCIe device"
}
if isGenericPCIeClassLabel(dev.DeviceClass) {
if resolved := pciids.DeviceName(dev.VendorID, dev.DeviceID); resolved != "" {
dev.DeviceClass = resolved
}
}
if strings.TrimSpace(dev.Manufacturer) == "" {
dev.Manufacturer = pciids.VendorName(dev.VendorID)
}
if strings.TrimSpace(dev.PartNumber) == "" {
dev.PartNumber = pciids.DeviceName(dev.VendorID, dev.DeviceID)
}
return dev
}
@@ -878,7 +914,7 @@ func parsePCIeFunction(doc map[string]interface{}, idx int) models.PCIeDevice {
slot = fmt.Sprintf("PCIeFn%d", idx)
}
return models.PCIeDevice{
dev := models.PCIeDevice{
Slot: slot,
BDF: asString(doc["FunctionId"]),
VendorID: asHexOrInt(doc["VendorId"]),
@@ -891,6 +927,54 @@ func parsePCIeFunction(doc map[string]interface{}, idx int) models.PCIeDevice {
MaxLinkWidth: asInt(doc["MaxLinkWidth"]),
MaxLinkSpeed: firstNonEmpty(asString(doc["MaxLinkSpeedGTs"]), asString(doc["MaxLinkSpeed"])),
}
if isGenericPCIeClassLabel(dev.DeviceClass) {
if resolved := pciids.DeviceName(dev.VendorID, dev.DeviceID); resolved != "" {
dev.DeviceClass = resolved
}
}
if strings.TrimSpace(dev.Manufacturer) == "" {
dev.Manufacturer = pciids.VendorName(dev.VendorID)
}
if strings.TrimSpace(dev.PartNumber) == "" {
dev.PartNumber = pciids.DeviceName(dev.VendorID, dev.DeviceID)
}
return dev
}
func isMissingOrRawPCIModel(model string) bool {
model = strings.TrimSpace(model)
if model == "" {
return true
}
l := strings.ToLower(model)
if l == "unknown" || l == "n/a" || l == "na" || l == "none" {
return true
}
if strings.HasPrefix(l, "0x") && len(l) <= 6 {
return true
}
if len(model) <= 4 {
isHex := true
for _, c := range l {
if (c < '0' || c > '9') && (c < 'a' || c > 'f') {
isHex = false
break
}
}
if isHex {
return true
}
}
return false
}
func isGenericPCIeClassLabel(v string) bool {
switch strings.ToLower(strings.TrimSpace(v)) {
case "", "pcie device", "display", "display controller", "vga", "3d controller", "network", "network controller", "storage", "storage controller", "other", "unknown":
return true
default:
return strings.HasPrefix(strings.ToLower(strings.TrimSpace(v)), "0x")
}
}
func looksLikeGPU(doc map[string]interface{}, functionDocs []map[string]interface{}) bool {