export: align reanimator and enrich redfish metrics
This commit is contained in:
@@ -66,104 +66,15 @@ func (e *Exporter) ExportCSV(w io.Writer) error {
|
||||
}
|
||||
}
|
||||
|
||||
// CPUs
|
||||
for _, cpu := range e.result.Hardware.CPUs {
|
||||
if !hasUsableSerial(cpu.SerialNumber) {
|
||||
seenCanonical := make(map[string]struct{})
|
||||
for _, dev := range canonicalDevicesForExport(e.result.Hardware) {
|
||||
if !hasUsableSerial(dev.SerialNumber) {
|
||||
continue
|
||||
}
|
||||
if err := writer.Write([]string{
|
||||
cpu.Model,
|
||||
strings.TrimSpace(cpu.SerialNumber),
|
||||
"",
|
||||
"CPU",
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Memory
|
||||
for _, mem := range e.result.Hardware.Memory {
|
||||
if !hasUsableSerial(mem.SerialNumber) {
|
||||
continue
|
||||
}
|
||||
location := mem.Location
|
||||
if location == "" {
|
||||
location = mem.Slot
|
||||
}
|
||||
if err := writer.Write([]string{
|
||||
mem.PartNumber,
|
||||
strings.TrimSpace(mem.SerialNumber),
|
||||
mem.Manufacturer,
|
||||
location,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Storage
|
||||
for _, stor := range e.result.Hardware.Storage {
|
||||
if !hasUsableSerial(stor.SerialNumber) {
|
||||
continue
|
||||
}
|
||||
if err := writer.Write([]string{
|
||||
stor.Model,
|
||||
strings.TrimSpace(stor.SerialNumber),
|
||||
stor.Manufacturer,
|
||||
stor.Slot,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// GPUs
|
||||
for _, gpu := range e.result.Hardware.GPUs {
|
||||
if !hasUsableSerial(gpu.SerialNumber) {
|
||||
continue
|
||||
}
|
||||
component := gpu.Model
|
||||
if component == "" {
|
||||
component = "GPU"
|
||||
}
|
||||
if err := writer.Write([]string{
|
||||
component,
|
||||
strings.TrimSpace(gpu.SerialNumber),
|
||||
gpu.Manufacturer,
|
||||
gpu.Slot,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// PCIe devices
|
||||
for _, pcie := range e.result.Hardware.PCIeDevices {
|
||||
if !hasUsableSerial(pcie.SerialNumber) {
|
||||
continue
|
||||
}
|
||||
if err := writer.Write([]string{
|
||||
pcie.DeviceClass,
|
||||
strings.TrimSpace(pcie.SerialNumber),
|
||||
pcie.Manufacturer,
|
||||
pcie.Slot,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Network adapters
|
||||
for _, nic := range e.result.Hardware.NetworkAdapters {
|
||||
if !hasUsableSerial(nic.SerialNumber) {
|
||||
continue
|
||||
}
|
||||
location := nic.Location
|
||||
if location == "" {
|
||||
location = nic.Slot
|
||||
}
|
||||
if err := writer.Write([]string{
|
||||
nic.Model,
|
||||
strings.TrimSpace(nic.SerialNumber),
|
||||
nic.Vendor,
|
||||
location,
|
||||
}); err != nil {
|
||||
serial := strings.TrimSpace(dev.SerialNumber)
|
||||
seenCanonical[serial] = struct{}{}
|
||||
component, manufacturer, location := csvFieldsFromCanonicalDevice(dev)
|
||||
if err := writer.Write([]string{component, serial, manufacturer, location}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -173,26 +84,15 @@ func (e *Exporter) ExportCSV(w io.Writer) error {
|
||||
if !hasUsableSerial(nic.SerialNumber) {
|
||||
continue
|
||||
}
|
||||
if err := writer.Write([]string{
|
||||
nic.Model,
|
||||
strings.TrimSpace(nic.SerialNumber),
|
||||
"",
|
||||
"Network",
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Power supplies
|
||||
for _, psu := range e.result.Hardware.PowerSupply {
|
||||
if !hasUsableSerial(psu.SerialNumber) {
|
||||
serial := strings.TrimSpace(nic.SerialNumber)
|
||||
if _, ok := seenCanonical[serial]; ok {
|
||||
continue
|
||||
}
|
||||
if err := writer.Write([]string{
|
||||
psu.Model,
|
||||
strings.TrimSpace(psu.SerialNumber),
|
||||
psu.Vendor,
|
||||
psu.Slot,
|
||||
nic.Model,
|
||||
serial,
|
||||
"",
|
||||
"Network",
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -221,3 +121,52 @@ func hasUsableSerial(serial string) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func csvFieldsFromCanonicalDevice(dev models.HardwareDevice) (component, manufacturer, location string) {
|
||||
component = firstNonEmptyString(
|
||||
dev.Model,
|
||||
dev.PartNumber,
|
||||
dev.DeviceClass,
|
||||
dev.Kind,
|
||||
)
|
||||
manufacturer = firstNonEmptyString(dev.Manufacturer, inferCSVVendor(dev))
|
||||
location = firstNonEmptyString(dev.Location, dev.Slot, dev.BDF, dev.Kind)
|
||||
|
||||
switch dev.Kind {
|
||||
case models.DeviceKindCPU:
|
||||
if component == "" {
|
||||
component = "CPU"
|
||||
}
|
||||
if location == "" {
|
||||
location = "CPU"
|
||||
}
|
||||
case models.DeviceKindMemory:
|
||||
component = firstNonEmptyString(dev.PartNumber, dev.Model, "Memory")
|
||||
case models.DeviceKindPCIe, models.DeviceKindGPU, models.DeviceKindNetwork:
|
||||
if location == "" {
|
||||
location = firstNonEmptyString(dev.Slot, dev.BDF, "PCIe")
|
||||
}
|
||||
case models.DeviceKindPSU:
|
||||
component = firstNonEmptyString(dev.Model, "Power Supply")
|
||||
}
|
||||
|
||||
return component, manufacturer, location
|
||||
}
|
||||
|
||||
func inferCSVVendor(dev models.HardwareDevice) string {
|
||||
switch dev.Kind {
|
||||
case models.DeviceKindCPU:
|
||||
return ""
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func firstNonEmptyString(values ...string) string {
|
||||
for _, value := range values {
|
||||
if strings.TrimSpace(value) != "" {
|
||||
return strings.TrimSpace(value)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user