package inspur import ( "bufio" "regexp" "strings" "git.mchus.pro/mchus/logpile/internal/models" ) var ( fruDeviceRegex = regexp.MustCompile(`^FRU Device Description\s*:\s*(.+)$`) fruFieldRegex = regexp.MustCompile(`^\s+(.+?)\s*:\s*(.*)$`) ) // ParseFRU parses BMC FRU (Field Replaceable Unit) output func ParseFRU(content []byte) []models.FRUInfo { var fruList []models.FRUInfo var current *models.FRUInfo scanner := bufio.NewScanner(strings.NewReader(string(content))) for scanner.Scan() { line := scanner.Text() // Check for new FRU device if matches := fruDeviceRegex.FindStringSubmatch(line); matches != nil { if current != nil && current.Description != "" { fruList = append(fruList, *current) } current = &models.FRUInfo{ Description: strings.TrimSpace(matches[1]), } continue } // Skip if no current FRU device if current == nil { continue } // Skip "Device not present" entries if strings.Contains(line, "Device not present") { current = nil continue } // Parse FRU fields if matches := fruFieldRegex.FindStringSubmatch(line); matches != nil { fieldName := strings.TrimSpace(matches[1]) fieldValue := strings.TrimSpace(matches[2]) switch fieldName { case "Chassis Type": current.ChassisType = fieldValue case "Chassis Part Number": if fieldValue != "0" { current.PartNumber = fieldValue } case "Chassis Serial": if fieldValue != "0" { current.SerialNumber = fieldValue } case "Board Mfg Date": current.MfgDate = fieldValue case "Board Mfg", "Product Manufacturer": if fieldValue != "NULL" { current.Manufacturer = fieldValue } case "Board Product", "Product Name": if fieldValue != "NULL" { current.ProductName = fieldValue } case "Board Serial", "Product Serial": current.SerialNumber = fieldValue case "Board Part Number", "Product Part Number": if fieldValue != "0" { current.PartNumber = fieldValue } case "Product Version": if fieldValue != "0" { current.Version = fieldValue } case "Product Asset Tag": if fieldValue != "NULL" { current.AssetTag = fieldValue } } } } // Don't forget the last one if current != nil && current.Description != "" { fruList = append(fruList, *current) } return fruList }