package redfishprofile import "strings" func ResolveAnalysisPlan(match MatchResult, snapshot map[string]interface{}, discovered DiscoveredResources, signals MatchSignals) ResolvedAnalysisPlan { plan := ResolvedAnalysisPlan{ Match: match, Directives: AnalysisDirectives{}, } if match.Mode == ModeFallback { plan.Directives.EnableProcessorGPUFallback = true plan.Directives.EnableSupermicroNVMeBackplane = true plan.Directives.EnableProcessorGPUChassisAlias = true plan.Directives.EnableGenericGraphicsControllerDedup = true plan.Directives.EnableStorageEnclosureRecovery = true plan.Directives.EnableKnownStorageControllerRecovery = true addAnalysisLookupMode(&plan, "msi-index") addAnalysisLookupMode(&plan, "hgx-alias") addAnalysisStorageDriveCollections(&plan, "/Storage/IntelVROC/Drives", "/Storage/IntelVROC/Controllers/1/Drives", ) addAnalysisStorageVolumeCollections(&plan, "/Storage/IntelVROC/Volumes", "/Storage/HA-RAID/Volumes", "/Storage/MRVL.HA-RAID/Volumes", ) addAnalysisNote(&plan, "fallback analysis enables broad recovery directives") } for _, profile := range match.Profiles { profile.ApplyAnalysisDirectives(&plan.Directives, signals) } for _, profile := range match.Profiles { profile.RefineAnalysisPlan(&plan, snapshot, discovered, signals) } return plan } func snapshotHasPathPrefix(snapshot map[string]interface{}, prefix string) bool { prefix = normalizePath(prefix) if prefix == "" { return false } for path := range snapshot { if strings.HasPrefix(normalizePath(path), prefix) { return true } } return false } func snapshotHasPathContaining(snapshot map[string]interface{}, sub string) bool { sub = strings.ToLower(strings.TrimSpace(sub)) if sub == "" { return false } for path := range snapshot { if strings.Contains(strings.ToLower(path), sub) { return true } } return false } func snapshotHasGPUProcessor(snapshot map[string]interface{}, systemPaths []string) bool { for _, systemPath := range systemPaths { prefix := normalizePath(joinPath(systemPath, "/Processors")) + "/" for path, docAny := range snapshot { if !strings.HasPrefix(normalizePath(path), prefix) { continue } doc, ok := docAny.(map[string]interface{}) if !ok { continue } if strings.EqualFold(strings.TrimSpace(asString(doc["ProcessorType"])), "GPU") { return true } } } return false } func snapshotHasStorageControllerHint(snapshot map[string]interface{}, needles ...string) bool { for _, needle := range needles { if snapshotHasPathContaining(snapshot, needle) { return true } } return false } func asString(v interface{}) string { switch x := v.(type) { case string: return x default: return "" } }