package redfishprofile import ( "strings" "git.mchus.pro/mchus/logpile/internal/models" ) type staticProfile struct { name string priority int safeForFallback bool matchFn func(MatchSignals) int extendAcquisition func(*AcquisitionPlan, MatchSignals) refineAcquisition func(*ResolvedAcquisitionPlan, DiscoveredResources, MatchSignals) applyAnalysisDirectives func(*AnalysisDirectives, MatchSignals) refineAnalysis func(*ResolvedAnalysisPlan, map[string]interface{}, DiscoveredResources, MatchSignals) postAnalyze func(*models.AnalysisResult, map[string]interface{}, MatchSignals) } func (p staticProfile) Name() string { return p.name } func (p staticProfile) Priority() int { return p.priority } func (p staticProfile) Match(signals MatchSignals) int { return p.matchFn(normalizeSignals(signals)) } func (p staticProfile) SafeForFallback() bool { return p.safeForFallback } func (p staticProfile) ExtendAcquisitionPlan(plan *AcquisitionPlan, signals MatchSignals) { if p.extendAcquisition != nil { p.extendAcquisition(plan, normalizeSignals(signals)) } } func (p staticProfile) RefineAcquisitionPlan(resolved *ResolvedAcquisitionPlan, discovered DiscoveredResources, signals MatchSignals) { if p.refineAcquisition != nil { p.refineAcquisition(resolved, discovered, normalizeSignals(signals)) } } func (p staticProfile) ApplyAnalysisDirectives(directives *AnalysisDirectives, signals MatchSignals) { if p.applyAnalysisDirectives != nil { p.applyAnalysisDirectives(directives, normalizeSignals(signals)) } } func (p staticProfile) RefineAnalysisPlan(plan *ResolvedAnalysisPlan, snapshot map[string]interface{}, discovered DiscoveredResources, signals MatchSignals) { if p.refineAnalysis != nil { p.refineAnalysis(plan, snapshot, discovered, normalizeSignals(signals)) } } func (p staticProfile) PostAnalyze(result *models.AnalysisResult, snapshot map[string]interface{}, signals MatchSignals) { if p.postAnalyze != nil { p.postAnalyze(result, snapshot, normalizeSignals(signals)) } } func BuiltinProfiles() []Profile { return []Profile{ genericProfile(), amiProfile(), msiProfile(), supermicroProfile(), dellProfile(), inspurGroupOEMPlatformsProfile(), hgxProfile(), xfusionProfile(), } } func containsFold(v, sub string) bool { return strings.Contains(strings.ToLower(strings.TrimSpace(v)), strings.ToLower(strings.TrimSpace(sub))) } func addPlanPaths(dst *[]string, paths ...string) { *dst = append(*dst, paths...) *dst = dedupeSorted(*dst) } func addPlanNote(plan *AcquisitionPlan, note string) { if strings.TrimSpace(note) == "" { return } plan.Notes = append(plan.Notes, note) plan.Notes = dedupeSorted(plan.Notes) } func addAnalysisNote(plan *ResolvedAnalysisPlan, note string) { if plan == nil || strings.TrimSpace(note) == "" { return } plan.Notes = append(plan.Notes, note) plan.Notes = dedupeSorted(plan.Notes) } func addAnalysisLookupMode(plan *ResolvedAnalysisPlan, mode string) { if plan == nil || strings.TrimSpace(mode) == "" { return } plan.ProcessorGPUChassisLookupModes = dedupeSorted(append(plan.ProcessorGPUChassisLookupModes, mode)) } func addAnalysisStorageDriveCollections(plan *ResolvedAnalysisPlan, rels ...string) { if plan == nil { return } plan.KnownStorageDriveCollections = dedupeSorted(append(plan.KnownStorageDriveCollections, rels...)) } func addAnalysisStorageVolumeCollections(plan *ResolvedAnalysisPlan, rels ...string) { if plan == nil { return } plan.KnownStorageVolumeCollections = dedupeSorted(append(plan.KnownStorageVolumeCollections, rels...)) } func ensureSnapshotMaxDocuments(plan *AcquisitionPlan, n int) { if n <= 0 { return } if plan.Tuning.SnapshotMaxDocuments < n { plan.Tuning.SnapshotMaxDocuments = n } } func ensureSnapshotWorkers(plan *AcquisitionPlan, n int) { if n <= 0 { return } if plan.Tuning.SnapshotWorkers < n { plan.Tuning.SnapshotWorkers = n } } func ensurePrefetchEnabled(plan *AcquisitionPlan, enabled bool) { if plan.Tuning.PrefetchEnabled == nil { plan.Tuning.PrefetchEnabled = new(bool) } *plan.Tuning.PrefetchEnabled = enabled } func ensurePrefetchWorkers(plan *AcquisitionPlan, n int) { if n <= 0 { return } if plan.Tuning.PrefetchWorkers < n { plan.Tuning.PrefetchWorkers = n } } func ensureNVMePostProbeEnabled(plan *AcquisitionPlan, enabled bool) { if plan.Tuning.NVMePostProbeEnabled == nil { plan.Tuning.NVMePostProbeEnabled = new(bool) } *plan.Tuning.NVMePostProbeEnabled = enabled } func ensureRatePolicy(plan *AcquisitionPlan, policy AcquisitionRatePolicy) { if policy.TargetP95LatencyMS > plan.Tuning.RatePolicy.TargetP95LatencyMS { plan.Tuning.RatePolicy.TargetP95LatencyMS = policy.TargetP95LatencyMS } if policy.ThrottleP95LatencyMS > plan.Tuning.RatePolicy.ThrottleP95LatencyMS { plan.Tuning.RatePolicy.ThrottleP95LatencyMS = policy.ThrottleP95LatencyMS } if policy.MinSnapshotWorkers > plan.Tuning.RatePolicy.MinSnapshotWorkers { plan.Tuning.RatePolicy.MinSnapshotWorkers = policy.MinSnapshotWorkers } if policy.MinPrefetchWorkers > plan.Tuning.RatePolicy.MinPrefetchWorkers { plan.Tuning.RatePolicy.MinPrefetchWorkers = policy.MinPrefetchWorkers } if policy.DisablePrefetchOnErrors { plan.Tuning.RatePolicy.DisablePrefetchOnErrors = true } } func ensureETABaseline(plan *AcquisitionPlan, baseline AcquisitionETABaseline) { if baseline.DiscoverySeconds > plan.Tuning.ETABaseline.DiscoverySeconds { plan.Tuning.ETABaseline.DiscoverySeconds = baseline.DiscoverySeconds } if baseline.SnapshotSeconds > plan.Tuning.ETABaseline.SnapshotSeconds { plan.Tuning.ETABaseline.SnapshotSeconds = baseline.SnapshotSeconds } if baseline.PrefetchSeconds > plan.Tuning.ETABaseline.PrefetchSeconds { plan.Tuning.ETABaseline.PrefetchSeconds = baseline.PrefetchSeconds } if baseline.CriticalPlanBSeconds > plan.Tuning.ETABaseline.CriticalPlanBSeconds { plan.Tuning.ETABaseline.CriticalPlanBSeconds = baseline.CriticalPlanBSeconds } if baseline.ProfilePlanBSeconds > plan.Tuning.ETABaseline.ProfilePlanBSeconds { plan.Tuning.ETABaseline.ProfilePlanBSeconds = baseline.ProfilePlanBSeconds } } func ensurePostProbePolicy(plan *AcquisitionPlan, policy AcquisitionPostProbePolicy) { if policy.EnableDirectNVMEDiskBayProbe { plan.Tuning.PostProbePolicy.EnableDirectNVMEDiskBayProbe = true } if policy.EnableNumericCollectionProbe { plan.Tuning.PostProbePolicy.EnableNumericCollectionProbe = true } if policy.EnableSensorCollectionProbe { plan.Tuning.PostProbePolicy.EnableSensorCollectionProbe = true } } func ensureRecoveryPolicy(plan *AcquisitionPlan, policy AcquisitionRecoveryPolicy) { if policy.EnableCriticalCollectionMemberRetry { plan.Tuning.RecoveryPolicy.EnableCriticalCollectionMemberRetry = true } if policy.EnableCriticalSlowProbe { plan.Tuning.RecoveryPolicy.EnableCriticalSlowProbe = true } if policy.EnableProfilePlanB { plan.Tuning.RecoveryPolicy.EnableProfilePlanB = true } if policy.EnableEmptyCriticalCollectionRetry { plan.Tuning.RecoveryPolicy.EnableEmptyCriticalCollectionRetry = true } } func ensureScopedPathPolicy(plan *AcquisitionPlan, policy AcquisitionScopedPathPolicy) { addPlanPaths(&plan.ScopedPaths.SystemSeedSuffixes, policy.SystemSeedSuffixes...) addPlanPaths(&plan.ScopedPaths.SystemCriticalSuffixes, policy.SystemCriticalSuffixes...) addPlanPaths(&plan.ScopedPaths.ChassisSeedSuffixes, policy.ChassisSeedSuffixes...) addPlanPaths(&plan.ScopedPaths.ChassisCriticalSuffixes, policy.ChassisCriticalSuffixes...) addPlanPaths(&plan.ScopedPaths.ManagerSeedSuffixes, policy.ManagerSeedSuffixes...) addPlanPaths(&plan.ScopedPaths.ManagerCriticalSuffixes, policy.ManagerCriticalSuffixes...) } func ensurePrefetchPolicy(plan *AcquisitionPlan, policy AcquisitionPrefetchPolicy) { addPlanPaths(&plan.Tuning.PrefetchPolicy.IncludeSuffixes, policy.IncludeSuffixes...) addPlanPaths(&plan.Tuning.PrefetchPolicy.ExcludeContains, policy.ExcludeContains...) } func min(a, b int) int { if a < b { return a } return b }