export: align reanimator and enrich redfish metrics
This commit is contained in:
330
bible-local/docs/hardware-ingest-contract.md
Normal file
330
bible-local/docs/hardware-ingest-contract.md
Normal file
@@ -0,0 +1,330 @@
|
||||
# Hardware Ingest Contract
|
||||
|
||||
Version: 2.4
|
||||
Updated: 2026-03-15
|
||||
Source: Reanimator Core `hardware-ingest-contract.md`
|
||||
|
||||
This file mirrors the external Reanimator hardware-ingest contract that LOGPile targets.
|
||||
The Reanimator endpoint uses strict JSON decoding. Any field not listed here must not be emitted.
|
||||
|
||||
## Endpoint
|
||||
|
||||
```http
|
||||
POST /ingest/hardware
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
The ingest request is asynchronous.
|
||||
Accepted response:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "accepted",
|
||||
"job_id": "job_01J..."
|
||||
}
|
||||
```
|
||||
|
||||
Final result is available from:
|
||||
|
||||
```http
|
||||
GET /ingest/hardware/jobs/{job_id}
|
||||
```
|
||||
|
||||
## Top-level payload
|
||||
|
||||
```json
|
||||
{
|
||||
"filename": "redfish://10.10.10.103",
|
||||
"source_type": "api",
|
||||
"protocol": "redfish",
|
||||
"target_host": "10.10.10.103",
|
||||
"collected_at": "2026-02-10T15:30:00Z",
|
||||
"hardware": {
|
||||
"board": {},
|
||||
"firmware": [],
|
||||
"cpus": [],
|
||||
"memory": [],
|
||||
"storage": [],
|
||||
"pcie_devices": [],
|
||||
"power_supplies": [],
|
||||
"sensors": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Top-level rules
|
||||
|
||||
- `collected_at` is required and must be RFC3339
|
||||
- `hardware.board.serial_number` is required
|
||||
- `source_type` allowed values: `api`, `logfile`, `manual`
|
||||
- `protocol` allowed values: `redfish`, `ipmi`, `snmp`, `ssh`
|
||||
- Unknown JSON keys are rejected by Reanimator
|
||||
|
||||
## Shared component status fields
|
||||
|
||||
Allowed on `cpus`, `memory`, `storage`, `pcie_devices`, `power_supplies`:
|
||||
|
||||
- `status`
|
||||
- `status_checked_at`
|
||||
- `status_changed_at`
|
||||
- `status_history`
|
||||
- `error_description`
|
||||
|
||||
`status_history[]` items:
|
||||
|
||||
- `status`
|
||||
- `changed_at`
|
||||
- `details`
|
||||
|
||||
Do not emit `status_at_collection`; it is not part of the current strict ingest schema.
|
||||
|
||||
## `hardware.board`
|
||||
|
||||
Allowed fields:
|
||||
|
||||
- `serial_number` required
|
||||
- `manufacturer`
|
||||
- `product_name`
|
||||
- `part_number`
|
||||
- `uuid`
|
||||
|
||||
String values equal to `"NULL"` should be omitted.
|
||||
|
||||
## `hardware.firmware`
|
||||
|
||||
Allowed fields:
|
||||
|
||||
- `device_name`
|
||||
- `version`
|
||||
|
||||
Only system-level firmware belongs here.
|
||||
Device-bound firmware must stay on the relevant device record and must not be duplicated at the top level.
|
||||
|
||||
## `hardware.cpus`
|
||||
|
||||
Allowed fields:
|
||||
|
||||
- `socket`
|
||||
- `model`
|
||||
- `manufacturer`
|
||||
- `cores`
|
||||
- `threads`
|
||||
- `frequency_mhz`
|
||||
- `max_frequency_mhz`
|
||||
- `temperature_c`
|
||||
- `power_w`
|
||||
- `throttled`
|
||||
- `correctable_error_count`
|
||||
- `uncorrectable_error_count`
|
||||
- `life_remaining_pct`
|
||||
- `life_used_pct`
|
||||
- `serial_number`
|
||||
- `firmware`
|
||||
- `present`
|
||||
- shared status fields
|
||||
|
||||
Exporter rule:
|
||||
- if CPU serial is missing, generate `{board_serial}-CPU-{socket}`
|
||||
|
||||
## `hardware.memory`
|
||||
|
||||
Allowed fields:
|
||||
|
||||
- `slot`
|
||||
- `location`
|
||||
- `present`
|
||||
- `serial_number`
|
||||
- `part_number`
|
||||
- `manufacturer`
|
||||
- `size_mb`
|
||||
- `type`
|
||||
- `max_speed_mhz`
|
||||
- `current_speed_mhz`
|
||||
- `temperature_c`
|
||||
- `correctable_ecc_error_count`
|
||||
- `uncorrectable_ecc_error_count`
|
||||
- `life_remaining_pct`
|
||||
- `life_used_pct`
|
||||
- `spare_blocks_remaining_pct`
|
||||
- `performance_degraded`
|
||||
- `data_loss_detected`
|
||||
- shared status fields
|
||||
|
||||
Exporter rules:
|
||||
- skip memory items with missing `serial_number`
|
||||
- skip memory items with `present=false`
|
||||
- skip memory items with `status=Empty`
|
||||
|
||||
## `hardware.storage`
|
||||
|
||||
Allowed fields:
|
||||
|
||||
- `slot`
|
||||
- `serial_number`
|
||||
- `model`
|
||||
- `manufacturer`
|
||||
- `type`
|
||||
- `interface`
|
||||
- `size_gb`
|
||||
- `temperature_c`
|
||||
- `power_on_hours`
|
||||
- `power_cycles`
|
||||
- `unsafe_shutdowns`
|
||||
- `media_errors`
|
||||
- `error_log_entries`
|
||||
- `written_bytes`
|
||||
- `read_bytes`
|
||||
- `life_used_pct`
|
||||
- `firmware`
|
||||
- `present`
|
||||
- `remaining_endurance_pct`
|
||||
- `life_remaining_pct`
|
||||
- `available_spare_pct`
|
||||
- `reallocated_sectors`
|
||||
- `current_pending_sectors`
|
||||
- `offline_uncorrectable`
|
||||
- shared status fields
|
||||
|
||||
Exporter rule:
|
||||
- skip storage items with missing `serial_number`
|
||||
|
||||
## `hardware.pcie_devices`
|
||||
|
||||
Allowed fields:
|
||||
|
||||
- `slot`
|
||||
- `vendor_id`
|
||||
- `device_id`
|
||||
- `numa_node`
|
||||
- `temperature_c`
|
||||
- `power_w`
|
||||
- `life_remaining_pct`
|
||||
- `life_used_pct`
|
||||
- `ecc_corrected_total`
|
||||
- `ecc_uncorrected_total`
|
||||
- `hw_slowdown`
|
||||
- `battery_charge_pct`
|
||||
- `battery_health_pct`
|
||||
- `battery_temperature_c`
|
||||
- `battery_voltage_v`
|
||||
- `battery_replace_required`
|
||||
- `sfp_temperature_c`
|
||||
- `sfp_tx_power_dbm`
|
||||
- `sfp_rx_power_dbm`
|
||||
- `sfp_voltage_v`
|
||||
- `sfp_bias_ma`
|
||||
- `bdf`
|
||||
- `device_class`
|
||||
- `manufacturer`
|
||||
- `model`
|
||||
- `serial_number`
|
||||
- `firmware`
|
||||
- `link_width`
|
||||
- `link_speed`
|
||||
- `max_link_width`
|
||||
- `max_link_speed`
|
||||
- `mac_addresses`
|
||||
- `present`
|
||||
- shared status fields
|
||||
|
||||
Known `device_class` values:
|
||||
|
||||
- `MassStorageController`
|
||||
- `StorageController`
|
||||
- `NetworkController`
|
||||
- `EthernetController`
|
||||
- `FibreChannelController`
|
||||
- `VideoController`
|
||||
- `ProcessingAccelerator`
|
||||
- `DisplayController`
|
||||
|
||||
Exporter rules:
|
||||
|
||||
- if PCIe serial is missing or placeholder-like, generate `{board_serial}-PCIE-{slot}`
|
||||
- `numa_node` is allowed again in the upstream contract
|
||||
- network adapters should emit `mac_addresses` when available
|
||||
- do not emit fields outside the upstream contract
|
||||
|
||||
## `hardware.power_supplies`
|
||||
|
||||
Allowed fields:
|
||||
|
||||
- `slot`
|
||||
- `present`
|
||||
- `serial_number`
|
||||
- `part_number`
|
||||
- `model`
|
||||
- `vendor`
|
||||
- `wattage_w`
|
||||
- `firmware`
|
||||
- `input_type`
|
||||
- `input_voltage`
|
||||
- `input_power_w`
|
||||
- `output_power_w`
|
||||
- `temperature_c`
|
||||
- `life_remaining_pct`
|
||||
- `life_used_pct`
|
||||
- shared status fields
|
||||
|
||||
Exporter rule:
|
||||
- skip PSUs with missing `serial_number`
|
||||
|
||||
## `hardware.sensors`
|
||||
|
||||
Shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"fans": [],
|
||||
"power": [],
|
||||
"temperatures": [],
|
||||
"other": []
|
||||
}
|
||||
```
|
||||
|
||||
### `sensors.fans`
|
||||
|
||||
Allowed fields:
|
||||
|
||||
- `name` required
|
||||
- `location`
|
||||
- `rpm`
|
||||
- `status`
|
||||
|
||||
### `sensors.power`
|
||||
|
||||
Allowed fields:
|
||||
|
||||
- `name` required
|
||||
- `location`
|
||||
- `voltage_v`
|
||||
- `current_a`
|
||||
- `power_w`
|
||||
- `status`
|
||||
|
||||
### `sensors.temperatures`
|
||||
|
||||
Allowed fields:
|
||||
|
||||
- `name` required
|
||||
- `location`
|
||||
- `celsius`
|
||||
- `threshold_warning_celsius`
|
||||
- `threshold_critical_celsius`
|
||||
- `status`
|
||||
|
||||
### `sensors.other`
|
||||
|
||||
Allowed fields:
|
||||
|
||||
- `name` required
|
||||
- `location`
|
||||
- `value`
|
||||
- `unit`
|
||||
- `status`
|
||||
|
||||
Sensor rules:
|
||||
|
||||
- dedupe within one payload by `(section, name)`, keeping the first item
|
||||
- skip sensors without `name`
|
||||
- the current LOGPile exporter maps generic `SensorReading` values into these four groups heuristically
|
||||
Reference in New Issue
Block a user