package collector import ( "git.mchus.pro/mchus/logpile/internal/collector/redfishprofile" "git.mchus.pro/mchus/logpile/internal/models" ) func (r redfishSnapshotReader) collectStorage(systemPath string, plan redfishprofile.ResolvedAnalysisPlan) []models.Storage { var out []models.Storage storageMembers, _ := r.getCollectionMembers(joinPath(systemPath, "/Storage")) for _, member := range storageMembers { if driveCollection, ok := member["Drives"].(map[string]interface{}); ok { if driveCollectionPath := asString(driveCollection["@odata.id"]); driveCollectionPath != "" { driveDocs, err := r.getCollectionMembers(driveCollectionPath) if err == nil { for _, driveDoc := range driveDocs { if !isVirtualStorageDrive(driveDoc) { supplementalDocs := r.getLinkedSupplementalDocs(driveDoc, "DriveMetrics", "EnvironmentMetrics", "Metrics") out = append(out, parseDriveWithSupplementalDocs(driveDoc, supplementalDocs...)) } } if len(driveDocs) == 0 { for _, driveDoc := range r.probeDirectDiskBayChildren(driveCollectionPath) { supplementalDocs := r.getLinkedSupplementalDocs(driveDoc, "DriveMetrics", "EnvironmentMetrics", "Metrics") out = append(out, parseDriveWithSupplementalDocs(driveDoc, supplementalDocs...)) } } } continue } } if drives, ok := member["Drives"].([]interface{}); ok { for _, driveAny := range drives { driveRef, ok := driveAny.(map[string]interface{}) if !ok { continue } odata := asString(driveRef["@odata.id"]) if odata == "" { continue } driveDoc, err := r.getJSON(odata) if err != nil { continue } if !isVirtualStorageDrive(driveDoc) { supplementalDocs := r.getLinkedSupplementalDocs(driveDoc, "DriveMetrics", "EnvironmentMetrics", "Metrics") out = append(out, parseDriveWithSupplementalDocs(driveDoc, supplementalDocs...)) } } continue } if looksLikeDrive(member) { if isVirtualStorageDrive(member) { continue } supplementalDocs := r.getLinkedSupplementalDocs(member, "DriveMetrics", "EnvironmentMetrics", "Metrics") out = append(out, parseDriveWithSupplementalDocs(member, supplementalDocs...)) } if plan.Directives.EnableStorageEnclosureRecovery { for _, enclosurePath := range redfishLinkRefs(member, "Links", "Enclosures") { driveDocs, err := r.getCollectionMembers(joinPath(enclosurePath, "/Drives")) if err == nil { for _, driveDoc := range driveDocs { 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)) } } } } } } if len(plan.KnownStorageDriveCollections) > 0 { for _, driveDoc := range r.collectKnownStorageMembers(systemPath, plan.KnownStorageDriveCollections) { if looksLikeDrive(driveDoc) && !isVirtualStorageDrive(driveDoc) { supplementalDocs := r.getLinkedSupplementalDocs(driveDoc, "DriveMetrics", "EnvironmentMetrics", "Metrics") out = append(out, parseDriveWithSupplementalDocs(driveDoc, supplementalDocs...)) } } } simpleStorageMembers, _ := r.getCollectionMembers(joinPath(systemPath, "/SimpleStorage")) for _, member := range simpleStorageMembers { devices, ok := member["Devices"].([]interface{}) if !ok { continue } for _, devAny := range devices { devDoc, ok := devAny.(map[string]interface{}) if !ok || !looksLikeDrive(devDoc) || isVirtualStorageDrive(devDoc) { continue } out = append(out, parseDrive(devDoc)) } } chassisPaths := r.discoverMemberPaths("/redfish/v1/Chassis", "/redfish/v1/Chassis/1") for _, chassisPath := range chassisPaths { driveDocs, err := r.getCollectionMembers(joinPath(chassisPath, "/Drives")) if err != nil { continue } for _, driveDoc := range driveDocs { if !looksLikeDrive(driveDoc) || isVirtualStorageDrive(driveDoc) { continue } out = append(out, parseDrive(driveDoc)) } } if plan.Directives.EnableSupermicroNVMeBackplane { for _, chassisPath := range chassisPaths { if !isSupermicroNVMeBackplanePath(chassisPath) { continue } for _, driveDoc := range r.probeSupermicroNVMeDiskBays(chassisPath) { if !looksLikeDrive(driveDoc) || isVirtualStorageDrive(driveDoc) { continue } out = append(out, parseDrive(driveDoc)) } } } return dedupeStorage(out) } func (r redfishSnapshotReader) collectStorageVolumes(systemPath string, plan redfishprofile.ResolvedAnalysisPlan) []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)) } } } if len(plan.KnownStorageVolumeCollections) > 0 { for _, volDoc := range r.collectKnownStorageMembers(systemPath, plan.KnownStorageVolumeCollections) { if looksLikeVolume(volDoc) { out = append(out, parseStorageVolume(volDoc, storageControllerFromPath(asString(volDoc["@odata.id"])))) } } } return dedupeStorageVolumes(out) }