feat(exporter): collect and export storage.vendor_id/device_id (contract v2.13)

Add PCI Vendor ID / Device ID to hardware.storage[] per the updated Reanimator
ingest contract, mirroring the existing pcie_devices[] fields. Populated for
Redfish-collected NVMe drives (live + TSR replay, via linked PCIeFunctions)
and for Inspur (from asset.json's own PcieInfo[], joined by PcieSlot). Also
fixes canonicalDevicesForExport dropping the fields when converting Storage
into the canonical HardwareDevice list used by the actual export path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-08-11 16:04:54 +03:00
co-authored by Claude Sonnet 5
parent 063587958e
commit 399eca5f49
11 changed files with 221 additions and 4 deletions
@@ -16,6 +16,7 @@ func (r redfishSnapshotReader) collectStorage(systemPath string, plan redfishpro
for _, driveDoc := range driveDocs {
if !isAbsentDriveDoc(driveDoc) && !isVirtualStorageDrive(driveDoc) {
supplementalDocs := r.getLinkedSupplementalDocs(driveDoc, "DriveMetrics", "EnvironmentMetrics", "Metrics")
supplementalDocs = append(supplementalDocs, r.getLinkedPCIeFunctions(driveDoc)...)
out = append(out, parseDriveWithSupplementalDocs(driveDoc, supplementalDocs...))
}
}
@@ -25,6 +26,7 @@ func (r redfishSnapshotReader) collectStorage(systemPath string, plan redfishpro
continue
}
supplementalDocs := r.getLinkedSupplementalDocs(driveDoc, "DriveMetrics", "EnvironmentMetrics", "Metrics")
supplementalDocs = append(supplementalDocs, r.getLinkedPCIeFunctions(driveDoc)...)
out = append(out, parseDriveWithSupplementalDocs(driveDoc, supplementalDocs...))
}
}
@@ -48,6 +50,7 @@ func (r redfishSnapshotReader) collectStorage(systemPath string, plan redfishpro
}
if !isAbsentDriveDoc(driveDoc) && !isVirtualStorageDrive(driveDoc) {
supplementalDocs := r.getLinkedSupplementalDocs(driveDoc, "DriveMetrics", "EnvironmentMetrics", "Metrics")
supplementalDocs = append(supplementalDocs, r.getLinkedPCIeFunctions(driveDoc)...)
out = append(out, parseDriveWithSupplementalDocs(driveDoc, supplementalDocs...))
}
}
@@ -58,6 +61,7 @@ func (r redfishSnapshotReader) collectStorage(systemPath string, plan redfishpro
continue
}
supplementalDocs := r.getLinkedSupplementalDocs(member, "DriveMetrics", "EnvironmentMetrics", "Metrics")
supplementalDocs = append(supplementalDocs, r.getLinkedPCIeFunctions(member)...)
out = append(out, parseDriveWithSupplementalDocs(member, supplementalDocs...))
}
@@ -68,6 +72,7 @@ func (r redfishSnapshotReader) collectStorage(systemPath string, plan redfishpro
for _, driveDoc := range driveDocs {
if looksLikeDrive(driveDoc) && !isAbsentDriveDoc(driveDoc) && !isVirtualStorageDrive(driveDoc) {
supplementalDocs := r.getLinkedSupplementalDocs(driveDoc, "DriveMetrics", "EnvironmentMetrics", "Metrics")
supplementalDocs = append(supplementalDocs, r.getLinkedPCIeFunctions(driveDoc)...)
out = append(out, parseDriveWithSupplementalDocs(driveDoc, supplementalDocs...))
}
}
@@ -88,6 +93,7 @@ func (r redfishSnapshotReader) collectStorage(systemPath string, plan redfishpro
for _, driveDoc := range r.collectKnownStorageMembers(systemPath, plan.KnownStorageDriveCollections) {
if looksLikeDrive(driveDoc) && !isAbsentDriveDoc(driveDoc) && !isVirtualStorageDrive(driveDoc) {
supplementalDocs := r.getLinkedSupplementalDocs(driveDoc, "DriveMetrics", "EnvironmentMetrics", "Metrics")
supplementalDocs = append(supplementalDocs, r.getLinkedPCIeFunctions(driveDoc)...)
out = append(out, parseDriveWithSupplementalDocs(driveDoc, supplementalDocs...))
}
}