Unify Redfish analysis through raw replay and add storage volumes
This commit is contained in:
@@ -51,6 +51,7 @@ func ReplayRedfishFromRawPayloads(rawPayloads map[string]any, emit ProgressFn) (
|
||||
processors, _ := r.getCollectionMembers(joinPath(primarySystem, "/Processors"))
|
||||
memory, _ := r.getCollectionMembers(joinPath(primarySystem, "/Memory"))
|
||||
storageDevices := r.collectStorage(primarySystem)
|
||||
storageVolumes := r.collectStorageVolumes(primarySystem)
|
||||
|
||||
if emit != nil {
|
||||
emit(Progress{Status: "running", Progress: 80, Message: "Redfish snapshot: replay network/BMC..."})
|
||||
@@ -74,6 +75,7 @@ func ReplayRedfishFromRawPayloads(rawPayloads map[string]any, emit ProgressFn) (
|
||||
CPUs: parseCPUs(processors),
|
||||
Memory: parseMemory(memory),
|
||||
Storage: storageDevices,
|
||||
Volumes: storageVolumes,
|
||||
PCIeDevices: pcieDevices,
|
||||
GPUs: gpus,
|
||||
PowerSupply: psus,
|
||||
@@ -256,6 +258,15 @@ func (r redfishSnapshotReader) collectStorage(systemPath string) []models.Storag
|
||||
}
|
||||
}
|
||||
|
||||
for _, driveDoc := range r.collectKnownStorageMembers(systemPath, []string{
|
||||
"/Storage/IntelVROC/Drives",
|
||||
"/Storage/IntelVROC/Controllers/1/Drives",
|
||||
}) {
|
||||
if looksLikeDrive(driveDoc) {
|
||||
out = append(out, parseDrive(driveDoc))
|
||||
}
|
||||
}
|
||||
|
||||
simpleStorageMembers, _ := r.getCollectionMembers(joinPath(systemPath, "/SimpleStorage"))
|
||||
for _, member := range simpleStorageMembers {
|
||||
devices, ok := member["Devices"].([]interface{})
|
||||
@@ -298,6 +309,49 @@ func (r redfishSnapshotReader) collectStorage(systemPath string) []models.Storag
|
||||
return dedupeStorage(out)
|
||||
}
|
||||
|
||||
func (r redfishSnapshotReader) collectStorageVolumes(systemPath string) []models.StorageVolume {
|
||||
var out []models.StorageVolume
|
||||
storageMembers, _ := r.getCollectionMembers(joinPath(systemPath, "/Storage"))
|
||||
for _, member := range storageMembers {
|
||||
controller := firstNonEmpty(asString(member["Id"]), asString(member["Name"]))
|
||||
volumeCollectionPath := redfishLinkedPath(member, "Volumes")
|
||||
if volumeCollectionPath == "" {
|
||||
continue
|
||||
}
|
||||
volumeDocs, err := r.getCollectionMembers(volumeCollectionPath)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, volDoc := range volumeDocs {
|
||||
if looksLikeVolume(volDoc) {
|
||||
out = append(out, parseStorageVolume(volDoc, controller))
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, volDoc := range r.collectKnownStorageMembers(systemPath, []string{
|
||||
"/Storage/IntelVROC/Volumes",
|
||||
"/Storage/HA-RAID/Volumes",
|
||||
"/Storage/MRVL.HA-RAID/Volumes",
|
||||
}) {
|
||||
if looksLikeVolume(volDoc) {
|
||||
out = append(out, parseStorageVolume(volDoc, storageControllerFromPath(asString(volDoc["@odata.id"]))))
|
||||
}
|
||||
}
|
||||
return dedupeStorageVolumes(out)
|
||||
}
|
||||
|
||||
func (r redfishSnapshotReader) collectKnownStorageMembers(systemPath string, relativeCollections []string) []map[string]interface{} {
|
||||
var out []map[string]interface{}
|
||||
for _, rel := range relativeCollections {
|
||||
docs, err := r.getCollectionMembers(joinPath(systemPath, rel))
|
||||
if err != nil || len(docs) == 0 {
|
||||
continue
|
||||
}
|
||||
out = append(out, docs...)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (r redfishSnapshotReader) probeSupermicroNVMeDiskBays(backplanePath string) []map[string]interface{} {
|
||||
return r.probeDirectDiskBayChildren(joinPath(backplanePath, "/Drives"))
|
||||
}
|
||||
@@ -351,6 +405,12 @@ func (r redfishSnapshotReader) collectPSUs(chassisPaths []string) []models.PSU {
|
||||
seen := make(map[string]struct{})
|
||||
idx := 1
|
||||
for _, chassisPath := range chassisPaths {
|
||||
if memberDocs, err := r.getCollectionMembers(joinPath(chassisPath, "/PowerSubsystem/PowerSupplies")); err == nil && len(memberDocs) > 0 {
|
||||
for _, doc := range memberDocs {
|
||||
idx = appendPSU(&out, seen, parsePSU(doc, idx), idx)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if powerDoc, err := r.getJSON(joinPath(chassisPath, "/Power")); err == nil {
|
||||
if members, ok := powerDoc["PowerSupplies"].([]interface{}); ok && len(members) > 0 {
|
||||
for _, item := range members {
|
||||
@@ -358,37 +418,10 @@ func (r redfishSnapshotReader) collectPSUs(chassisPaths []string) []models.PSU {
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
psu := parsePSU(doc, idx)
|
||||
idx++
|
||||
key := firstNonEmpty(psu.SerialNumber, psu.Slot+"|"+psu.Model)
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[key]; ok {
|
||||
continue
|
||||
}
|
||||
seen[key] = struct{}{}
|
||||
out = append(out, psu)
|
||||
idx = appendPSU(&out, seen, parsePSU(doc, idx), idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
memberDocs, err := r.getCollectionMembers(joinPath(chassisPath, "/PowerSubsystem/PowerSupplies"))
|
||||
if err != nil || len(memberDocs) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, doc := range memberDocs {
|
||||
psu := parsePSU(doc, idx)
|
||||
idx++
|
||||
key := firstNonEmpty(psu.SerialNumber, psu.Slot+"|"+psu.Model)
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[key]; ok {
|
||||
continue
|
||||
}
|
||||
seen[key] = struct{}{}
|
||||
out = append(out, psu)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user