Files
bee/audit/internal/collector/contract.go
Mikhail ChusavitinandClaude Sonnet 5 134bed3eae refactor: dedupe status-severity ranking and small webui helpers
statusSeverity was byte-for-byte duplicated in collector/contract.go and
app/sat_overlay.go (same switch, same comment). Export it as
collector.StatusSeverity and drop the app-package copy.

page_topo.go inlined the same GPU/NIC/RAID class switch as its own
pcieDeviceKind function in one spot — call the function instead.

page_validate.go had its own copy of pages.go's firstNonEmpty (all call
sites already pre-trim their inputs via validateTrimPtr, so the extra
TrimSpace was redundant) — drop the duplicate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 14:44:52 +03:00

112 lines
3.4 KiB
Go

package collector
import (
"bee/audit/internal/schema"
"strings"
)
const (
statusOK = "OK"
statusWarning = "Warning"
statusCritical = "Critical"
statusUnknown = "Unknown"
statusEmpty = "Empty"
)
func mapPCIeDeviceClass(raw string) string {
normalized := strings.ToLower(strings.TrimSpace(raw))
switch {
case normalized == "":
return ""
case strings.Contains(normalized, "ethernet controller"):
return "EthernetController"
case strings.Contains(normalized, "fibre channel"):
return "FibreChannelController"
case strings.Contains(normalized, "network controller"), strings.Contains(normalized, "infiniband controller"):
return "NetworkController"
case strings.Contains(normalized, "serial attached scsi"), strings.Contains(normalized, "storage controller"):
return "StorageController"
case strings.Contains(normalized, "raid"), strings.Contains(normalized, "mass storage"):
return "MassStorageController"
case strings.Contains(normalized, "display controller"):
return "DisplayController"
case strings.Contains(normalized, "vga"), strings.Contains(normalized, "3d controller"), strings.Contains(normalized, "video controller"):
return "VideoController"
case strings.Contains(normalized, "processing accelerators"), strings.Contains(normalized, "processing accelerator"):
return "ProcessingAccelerator"
default:
return raw
}
}
func isNICClass(class string) bool {
switch strings.TrimSpace(class) {
case "EthernetController", "NetworkController":
return true
default:
return false
}
}
// IsGPUClass reports whether a normalized PCIe device class (see
// mapPCIeDeviceClass) identifies a GPU/accelerator die itself, as opposed to
// a same-vendor companion device (NIC, storage controller, NVLink bridge,
// audio/USB function, ...) that happens to share the GPU's PCI vendor ID.
func IsGPUClass(class string) bool {
switch strings.TrimSpace(class) {
case "VideoController", "DisplayController", "ProcessingAccelerator":
return true
default:
return false
}
}
func isRAIDClass(class string) bool {
switch strings.TrimSpace(class) {
case "MassStorageController", "StorageController":
return true
default:
return false
}
}
// StatusSeverity ranks component statuses so merges can only escalate, never
// downgrade. Unknown ranks with OK: it means "couldn't tell", not "healthy",
// so it must not silently clear a Warning/Critical raised by an earlier stage.
func StatusSeverity(status string) int {
switch strings.TrimSpace(status) {
case statusCritical:
return 3
case statusWarning:
return 2
case statusOK:
return 1
case statusUnknown:
return 1
default:
return 0
}
}
// mergeDeviceStatus applies status/description to dev only if it is at least
// as severe as whatever is already set. This lets later enrichment stages
// (e.g. NVIDIA telemetry) report their own findings without silently
// clobbering a Warning/Critical raised earlier in the collector pipeline
// (e.g. a PCIe link-speed degradation).
func mergeDeviceStatus(dev *schema.HardwarePCIeDevice, status, description string) {
if dev == nil || status == "" {
return
}
current := ""
if dev.Status != nil {
current = strings.TrimSpace(*dev.Status)
}
if current != "" && current != statusUnknown && StatusSeverity(status) <= StatusSeverity(current) {
return
}
dev.Status = &status
if strings.TrimSpace(description) != "" {
dev.ErrorDescription = &description
}
}