export: align reanimator contract v2.7

This commit is contained in:
Mikhail Chusavitin
2026-03-15 23:27:32 +03:00
parent 9007f1b360
commit 476630190d
31 changed files with 3502 additions and 689 deletions
+60 -15
View File
@@ -93,12 +93,12 @@ func ReplayRedfishFromRawPayloads(rawPayloads map[string]any, emit ProgressFn) (
collectedAt, sourceTimezone := inferRedfishCollectionTime(managerDoc, rawPayloads)
result := &models.AnalysisResult{
CollectedAt: collectedAt,
CollectedAt: collectedAt,
SourceTimezone: sourceTimezone,
Events: append(append(append(make([]models.Event, 0, len(discreteEvents)+len(healthEvents)+len(driveFetchWarningEvents)+1), healthEvents...), discreteEvents...), driveFetchWarningEvents...),
FRU: assemblyFRU,
Sensors: dedupeSensorReadings(append(append(thresholdSensors, thermalSensors...), powerSensors...)),
RawPayloads: cloneRawPayloads(rawPayloads),
Events: append(append(append(make([]models.Event, 0, len(discreteEvents)+len(healthEvents)+len(driveFetchWarningEvents)+1), healthEvents...), discreteEvents...), driveFetchWarningEvents...),
FRU: assemblyFRU,
Sensors: dedupeSensorReadings(append(append(thresholdSensors, thermalSensors...), powerSensors...)),
RawPayloads: cloneRawPayloads(rawPayloads),
Hardware: &models.HardwareConfig{
BoardInfo: boardInfo,
CPUs: processors,
@@ -273,11 +273,7 @@ func (r redfishSnapshotReader) collectFirmwareInventory() []models.FirmwareInfo
if strings.TrimSpace(version) == "" {
continue
}
name := firstNonEmpty(
asString(doc["DeviceName"]),
asString(doc["Name"]),
asString(doc["Id"]),
)
name := firmwareInventoryDeviceName(doc)
name = strings.TrimSpace(name)
if name == "" {
continue
@@ -291,6 +287,25 @@ func (r redfishSnapshotReader) collectFirmwareInventory() []models.FirmwareInfo
return out
}
func firmwareInventoryDeviceName(doc map[string]interface{}) string {
name := strings.TrimSpace(asString(doc["DeviceName"]))
if name != "" {
return name
}
id := strings.TrimSpace(asString(doc["Id"]))
rawName := strings.TrimSpace(asString(doc["Name"]))
if strings.EqualFold(rawName, "Software Inventory") || strings.EqualFold(rawName, "Firmware Inventory") {
if id != "" {
return id
}
}
if rawName != "" {
return rawName
}
return id
}
func dedupeFirmwareInfo(items []models.FirmwareInfo) []models.FirmwareInfo {
seen := make(map[string]struct{}, len(items))
out := make([]models.FirmwareInfo, 0, len(items))
@@ -1094,6 +1109,9 @@ func (r redfishSnapshotReader) collectStorage(systemPath string) []models.Storag
continue
}
if looksLikeDrive(member) {
if isVirtualStorageDrive(member) {
continue
}
supplementalDocs := r.getLinkedSupplementalDocs(member, "DriveMetrics", "EnvironmentMetrics", "Metrics")
out = append(out, parseDriveWithSupplementalDocs(member, supplementalDocs...))
}
@@ -1102,13 +1120,16 @@ func (r redfishSnapshotReader) collectStorage(systemPath string) []models.Storag
driveDocs, err := r.getCollectionMembers(joinPath(enclosurePath, "/Drives"))
if err == nil {
for _, driveDoc := range driveDocs {
if looksLikeDrive(driveDoc) {
if looksLikeDrive(driveDoc) && !isVirtualStorageDrive(driveDoc) {
supplementalDocs := r.getLinkedSupplementalDocs(driveDoc, "DriveMetrics", "EnvironmentMetrics", "Metrics")
out = append(out, parseDriveWithSupplementalDocs(driveDoc, supplementalDocs...))
}
}
if len(driveDocs) == 0 {
for _, driveDoc := range r.probeDirectDiskBayChildren(joinPath(enclosurePath, "/Drives")) {
if isVirtualStorageDrive(driveDoc) {
continue
}
out = append(out, parseDrive(driveDoc))
}
}
@@ -1120,7 +1141,7 @@ func (r redfishSnapshotReader) collectStorage(systemPath string) []models.Storag
"/Storage/IntelVROC/Drives",
"/Storage/IntelVROC/Controllers/1/Drives",
}) {
if looksLikeDrive(driveDoc) {
if looksLikeDrive(driveDoc) && !isVirtualStorageDrive(driveDoc) {
supplementalDocs := r.getLinkedSupplementalDocs(driveDoc, "DriveMetrics", "EnvironmentMetrics", "Metrics")
out = append(out, parseDriveWithSupplementalDocs(driveDoc, supplementalDocs...))
}
@@ -1134,7 +1155,7 @@ func (r redfishSnapshotReader) collectStorage(systemPath string) []models.Storag
}
for _, devAny := range devices {
devDoc, ok := devAny.(map[string]interface{})
if !ok || !looksLikeDrive(devDoc) {
if !ok || !looksLikeDrive(devDoc) || isVirtualStorageDrive(devDoc) {
continue
}
out = append(out, parseDrive(devDoc))
@@ -1148,7 +1169,7 @@ func (r redfishSnapshotReader) collectStorage(systemPath string) []models.Storag
continue
}
for _, driveDoc := range driveDocs {
if !looksLikeDrive(driveDoc) {
if !looksLikeDrive(driveDoc) || isVirtualStorageDrive(driveDoc) {
continue
}
out = append(out, parseDrive(driveDoc))
@@ -1159,7 +1180,7 @@ func (r redfishSnapshotReader) collectStorage(systemPath string) []models.Storag
continue
}
for _, driveDoc := range r.probeSupermicroNVMeDiskBays(chassisPath) {
if !looksLikeDrive(driveDoc) {
if !looksLikeDrive(driveDoc) || isVirtualStorageDrive(driveDoc) {
continue
}
out = append(out, parseDrive(driveDoc))
@@ -1353,6 +1374,7 @@ func (r redfishSnapshotReader) collectPCIeDevices(systemPaths, chassisPaths []st
continue
}
supplementalDocs := r.getLinkedSupplementalDocs(doc, "EnvironmentMetrics", "Metrics")
supplementalDocs = append(supplementalDocs, r.getChassisScopedPCIeSupplementalDocs(doc)...)
for _, fn := range functionDocs {
supplementalDocs = append(supplementalDocs, r.getLinkedSupplementalDocs(fn, "EnvironmentMetrics", "Metrics")...)
}
@@ -1377,6 +1399,29 @@ func (r redfishSnapshotReader) collectPCIeDevices(systemPaths, chassisPaths []st
return dedupePCIeDevices(out)
}
func (r redfishSnapshotReader) getChassisScopedPCIeSupplementalDocs(doc map[string]interface{}) []map[string]interface{} {
if !looksLikeNVSwitchPCIeDoc(doc) {
return nil
}
docPath := normalizeRedfishPath(asString(doc["@odata.id"]))
chassisPath := chassisPathForPCIeDoc(docPath)
if chassisPath == "" {
return nil
}
out := make([]map[string]interface{}, 0, 4)
for _, path := range []string{
joinPath(chassisPath, "/EnvironmentMetrics"),
joinPath(chassisPath, "/ThermalSubsystem/ThermalMetrics"),
} {
supplementalDoc, err := r.getJSON(path)
if err != nil || len(supplementalDoc) == 0 {
continue
}
out = append(out, supplementalDoc)
}
return out
}
func stringsTrimTrailingSlash(s string) string {
for len(s) > 1 && s[len(s)-1] == '/' {
s = s[:len(s)-1]