@@ -0,0 +1,730 @@
---
title: Hardware Ingest JSON Contract
version: "2.1"
updated: "2026-03-15"
maintainer: Reanimator Core
audience: external-integrators, ai-agents
language: ru
---
# Интеграция с Reanimator: контракт JSON-импорта аппаратного обеспечения
Версия: **2.1 ** · Дата: **2026-03-15 **
Документ описывает формат JSON для передачи данных об аппаратном обеспечении серверов в систему **Reanimator ** (управление жизненным циклом аппаратного обеспечения).
Предназначен для разработчиков смежных систем (Redfish-коллекторов, агентов мониторинга, CMDB-экспортёров) и может быть включён в документацию интегрируемых проектов.
> Актуальная версия документа: https://git.mchus.pro/reanimator/core/src/branch/main/bible-local/docs/hardware-ingest-contract.md
---
## Changelog
| Версия | Дата | Изменения |
|--------|------|-----------|
| 2.4 | 2026-03-15 | Добавлена первая волна component telemetry: health/life поля для `cpus` , `memory` , `storage` , `pcie_devices` , `power_supplies` |
| 2.3 | 2026-03-15 | Добавлены component telemetry поля: `pcie_devices.temperature_c` , `pcie_devices.power_w` , `power_supplies.temperature_c` |
| 2.2 | 2026-03-15 | Добавлено поле `numa_node` у `pcie_devices` для topology/affinity |
| 2.1 | 2026-03-15 | Добавлена секция `sensors` (fans, power, temperatures, other); поле `mac_addresses` у `pcie_devices` ; расширен список значений `device_class` |
| 2.0 | 2026-02-01 | История статусов (`status_history` , `status_changed_at` ); поля telemetry у PSU; async job response |
| 1.0 | 2026-01-01 | Начальная версия контракта |
---
## Принципы
1. **Snapshot ** — JSON описывает состояние сервера на момент сбора. Может включать историю изменений статуса компонентов.
2. **Идемпотентность ** — повторная отправка идентичного payload не создаёт дублей (дедупликация по хешу).
3. **Частичность ** — можно передавать только те секции, данные по которым доступны. Пустой массив и отсутствие секции эквивалентны.
4. **Строгая схема ** — endpoint использует строгий JSON-декодер; неизвестные поля приводят к `400 Bad Request` .
5. **Event-driven ** — импорт создаёт события в timeline (LOG_COLLECTED, INSTALLED, REMOVED, FIRMWARE_CHANGED и др.).
---
## Endpoint
```
POST /ingest/hardware
Content-Type: application/json
```
**Ответ при приёме (202 Accepted): **
``` json
{
"status" : "accepted" ,
"job_id" : "job_01J..."
}
```
Импорт выполняется асинхронно. Результат доступен по:
```
GET /ingest/hardware/jobs/{job_id}
```
**Ответ при успехе задачи: **
``` json
{
"status" : "success" ,
"bundle_id" : "lb_01J..." ,
"asset_id" : "mach_01J..." ,
"collected_at" : "2026-02-10T15:30:00Z" ,
"duplicate" : false ,
"summary" : {
"parts_observed" : 15 ,
"parts_created" : 2 ,
"parts_updated" : 13 ,
"installations_created" : 2 ,
"installations_closed" : 1 ,
"timeline_events_created" : 9 ,
"failure_events_created" : 1
}
}
```
**Ответ при дубликате: **
``` json
{
"status" : "success" ,
"duplicate" : true ,
"message" : "LogBundle with this content hash already exists"
}
```
**Ответ при ошибке (400 Bad Request): **
``` json
{
"status" : "error" ,
"error" : "validation_failed" ,
"details" : {
"field" : "hardware.board.serial_number" ,
"message" : "serial_number is required"
}
}
```
Частые причины `400` :
- Неверный формат `collected_at` (требуется RFC3339).
- Пустой `hardware.board.serial_number` .
- Наличие неизвестного JSON-поля на любом уровне.
- Тело запроса превышает допустимый размер.
---
## Структура верхнего уровня
``` 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" : { . . . }
}
}
```
### Поля верхнего уровня
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `collected_at` | string RFC3339 | **да ** | Время сбора данных |
| `hardware` | object | **да ** | Аппаратный снапшот |
| `hardware.board.serial_number` | string | **да ** | Серийный номер платы/сервера |
| `target_host` | string | нет | IP или hostname |
| `source_type` | string | нет | Тип источника: `api` , `logfile` , `manual` |
| `protocol` | string | нет | Протокол: `redfish` , `ipmi` , `snmp` , `ssh` |
| `filename` | string | нет | Идентификатор источника |
---
## Общие поля статуса компонентов
Применяются ко всем компонентным секциям (`cpus` , `memory` , `storage` , `pcie_devices` , `power_supplies` ).
| Поле | Тип | Описание |
|------|-----|----------|
| `status` | string | Текущий статус: `OK` , `Warning` , `Critical` , `Unknown` , `Empty` |
| `status_checked_at` | string RFC3339 | Время последней проверки статуса |
| `status_changed_at` | string RFC3339 | Время последнего изменения статуса |
| `status_history` | array | История переходов статусов (см. ниже) |
| `error_description` | string | Текст ошибки/диагностики |
**Объект `status_history[]`: **
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `status` | string | **да ** | Статус в этот момент |
| `changed_at` | string RFC3339 | **да ** | Время перехода (без этого поля запись игнорируется) |
| `details` | string | нет | Пояснение к переходу |
**Правила приоритета времени события: **
1. `status_changed_at`
2. Последняя запись `status_history` с совпадающим статусом
3. Последняя парсируемая запись `status_history`
4. `status_checked_at`
**Правила передачи статусов: **
- Передавайте `status` как текущее состояние компонента в snapshot.
- Если источник хранит историю — передавайте `status_history` отсортированным по `changed_at` по возрастанию.
- Не включайте записи `status_history` без `changed_at` .
- Все даты — RFC3339, рекомендуется UTC (`Z` ).
---
## Секции hardware
### board
Основная информация о сервере. Обязательная секция.
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `serial_number` | string | **да ** | Серийный номер (ключ идентификации Asset) |
| `manufacturer` | string | нет | Производитель |
| `product_name` | string | нет | Модель |
| `part_number` | string | нет | Партномер |
| `uuid` | string | нет | UUID системы |
Значения `"NULL"` в строковых полях трактуются как отсутствие данных.
``` json
"board" : {
"manufacturer" : "Supermicro" ,
"product_name" : "X12DPG-QT6" ,
"serial_number" : "21D634101" ,
"part_number" : "X12DPG-QT6-REV1.01" ,
"uuid" : "d7ef2fe5-2fd0-11f0-910a-346f11040868"
}
```
---
### firmware
Версии прошивок системных компонентов (BIOS, BMC, CPLD и др.).
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `device_name` | string | **да ** | Название устройства (`BIOS` , `BMC` , `CPLD` , …) |
| `version` | string | **да ** | Версия прошивки |
Записи с пустым `device_name` или `version` игнорируются.
Изменение версии создаёт событие `FIRMWARE_CHANGED` для Asset.
``` json
"firmware" : [
{ "device_name" : "BIOS" , "version" : "06.08.05" } ,
{ "device_name" : "BMC" , "version" : "5.17.00" } ,
{ "device_name" : "CPLD" , "version" : "01.02.03" }
]
```
---
### cpus
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `socket` | int | **да ** | Номер сокета (используется для генерации serial) |
| `model` | string | нет | Модель процессора |
| `manufacturer` | string | нет | Производитель |
| `cores` | int | нет | Количество ядер |
| `threads` | int | нет | Количество потоков |
| `frequency_mhz` | int | нет | Текущая частота |
| `max_frequency_mhz` | int | нет | Максимальная частота |
| `temperature_c` | float | нет | Температура CPU, °C (telemetry) |
| `power_w` | float | нет | Текущая мощность CPU, Вт (telemetry) |
| `throttled` | bool | нет | Зафиксирован thermal/power throttling |
| `correctable_error_count` | int | нет | Количество корректируемых ошибок CPU |
| `uncorrectable_error_count` | int | нет | Количество некорректируемых ошибок CPU |
| `life_remaining_pct` | float | нет | Остаточный ресурс / health, % |
| `life_used_pct` | float | нет | Использованный ресурс / wear, % |
| `serial_number` | string | нет | Серийный номер (если доступен) |
| `firmware` | string | нет | Версия микрокода |
| `present` | bool | нет | Наличие (по умолчанию `true` ) |
| + общие поля статуса | | | см. раздел выше |
**Генерация serial_number при отсутствии: ** `{board_serial}-CPU-{socket}`
``` json
"cpus" : [
{
"socket" : 0 ,
"model" : "INTEL(R) XEON(R) GOLD 6530" ,
"cores" : 32 ,
"threads" : 64 ,
"frequency_mhz" : 2100 ,
"max_frequency_mhz" : 4000 ,
"temperature_c" : 61.5 ,
"power_w" : 182.0 ,
"throttled" : false ,
"manufacturer" : "Intel" ,
"status" : "OK" ,
"status_checked_at" : "2026-02-10T15:28:00Z"
}
]
```
---
### memory
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `slot` | string | нет | Идентификатор слота |
| `location` | string | нет | Физическое расположение |
| `present` | bool | нет | Наличие модуля (по умолчанию `true` ) |
| `serial_number` | string | нет | Серийный номер |
| `part_number` | string | нет | Партномер (используется как модель) |
| `manufacturer` | string | нет | Производитель |
| `size_mb` | int | нет | Объём в МБ |
| `type` | string | нет | Тип: `DDR3` , `DDR4` , `DDR5` , … |
| `max_speed_mhz` | int | нет | Максимальная частота |
| `current_speed_mhz` | int | нет | Текущая частота |
| `temperature_c` | float | нет | Температура DIMM/модуля, °C (telemetry) |
| `correctable_ecc_error_count` | int | нет | Количество корректируемых ECC-ошибок |
| `uncorrectable_ecc_error_count` | int | нет | Количество некорректируемых ECC-ошибок |
| `life_remaining_pct` | float | нет | Остаточный ресурс / health, % |
| `life_used_pct` | float | нет | Использованный ресурс / wear, % |
| `spare_blocks_remaining_pct` | float | нет | Остаток spare blocks, % |
| `performance_degraded` | bool | нет | Зафиксирована деградация производительности |
| `data_loss_detected` | bool | нет | Источник сигнализирует риск/факт потери данных |
| + общие поля статуса | | | см. раздел выше |
Модуль без `serial_number` игнорируется. Модуль с `present=false` или `status=Empty` игнорируется.
``` json
"memory" : [
{
"slot" : "CPU0_C0D0" ,
"present" : true ,
"size_mb" : 32768 ,
"type" : "DDR5" ,
"max_speed_mhz" : 4800 ,
"current_speed_mhz" : 4800 ,
"temperature_c" : 43.0 ,
"correctable_ecc_error_count" : 0 ,
"manufacturer" : "Hynix" ,
"serial_number" : "80AD032419E17CEEC1" ,
"part_number" : "HMCG88AGBRA191N" ,
"status" : "OK"
}
]
```
---
### storage
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `slot` | string | нет | Идентификатор слота |
| `serial_number` | string | нет | Серийный номер |
| `model` | string | нет | Модель |
| `manufacturer` | string | нет | Производитель |
| `type` | string | нет | Тип: `NVMe` , `SSD` , `HDD` |
| `interface` | string | нет | Интерфейс: `NVMe` , `SATA` , `SAS` |
| `size_gb` | int | нет | Размер в ГБ |
| `temperature_c` | float | нет | Температура накопителя, °C (telemetry) |
| `power_on_hours` | int64 | нет | Время работы, часы |
| `power_cycles` | int64 | нет | Количество циклов питания |
| `unsafe_shutdowns` | int64 | нет | Нештатные выключения |
| `media_errors` | int64 | нет | Ошибки носителя / media errors |
| `error_log_entries` | int64 | нет | Количество записей в error log |
| `written_bytes` | int64 | нет | Всего записано байт |
| `read_bytes` | int64 | нет | Всего прочитано байт |
| `life_used_pct` | float | нет | Использованный ресурс / wear, % |
| `life_remaining_pct` | float | нет | Остаточный ресурс / health, % |
| `available_spare_pct` | float | нет | Доступный spare, % |
| `reallocated_sectors` | int64 | нет | Переназначенные сектора |
| `current_pending_sectors` | int64 | нет | Сектора в ожидании ремапа |
| `offline_uncorrectable` | int64 | нет | Некорректируемые ошибки offline scan |
| `firmware` | string | нет | Версия прошивки |
| `present` | bool | нет | Наличие (по умолчанию `true` ) |
| + общие поля статуса | | | см. раздел выше |
Диск без `serial_number` игнорируется. Изменение `firmware` создаёт событие `FIRMWARE_CHANGED` .
``` json
"storage" : [
{
"slot" : "OB01" ,
"type" : "NVMe" ,
"model" : "INTEL SSDPF2KX076T1" ,
"size_gb" : 7680 ,
"temperature_c" : 38.5 ,
"power_on_hours" : 12450 ,
"unsafe_shutdowns" : 3 ,
"written_bytes" : 9876543210 ,
"life_remaining_pct" : 91.0 ,
"serial_number" : "BTAX41900GF87P6DGN" ,
"manufacturer" : "Intel" ,
"firmware" : "9CV10510" ,
"interface" : "NVMe" ,
"present" : true ,
"status" : "OK"
}
]
```
---
### pcie_devices
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `slot` | string | нет | Идентификатор слота |
| `vendor_id` | int | нет | PCI Vendor ID (decimal) |
| `device_id` | int | нет | PCI Device ID (decimal) |
| `numa_node` | int | нет | NUMA node / CPU affinity устройства |
| `temperature_c` | float | нет | Температура устройства, °C (telemetry) |
| `power_w` | float | нет | Текущее энергопотребление устройства, Вт (telemetry) |
| `life_remaining_pct` | float | нет | Остаточный ресурс / health, % |
| `life_used_pct` | float | нет | Использованный ресурс / wear, % |
| `ecc_corrected_total` | int64 | нет | Всего корректируемых ECC-ошибок |
| `ecc_uncorrected_total` | int64 | нет | Всего некорректируемых ECC-ошибок |
| `hw_slowdown` | bool | нет | Устройство вошло в hardware slowdown / protective mode |
| `battery_charge_pct` | float | нет | Заряд батареи / supercap, % |
| `battery_health_pct` | float | нет | Состояние батареи / supercap, % |
| `battery_temperature_c` | float | нет | Температура батареи / supercap, °C |
| `battery_voltage_v` | float | нет | Напряжение батареи / supercap, В |
| `battery_replace_required` | bool | нет | Требуется замена батареи / supercap |
| `sfp_temperature_c` | float | нет | Температура SFP/optic, °C |
| `sfp_tx_power_dbm` | float | нет | TX optical power, dBm |
| `sfp_rx_power_dbm` | float | нет | RX optical power, dBm |
| `sfp_voltage_v` | float | нет | Напряжение SFP, В |
| `sfp_bias_ma` | float | нет | Bias current SFP, мА |
| `bdf` | string | нет | Bus:Device.Function, например `0000:18:00.0` |
| `device_class` | string | нет | Класс устройства (см. список ниже) |
| `manufacturer` | string | нет | Производитель |
| `model` | string | нет | Модель |
| `serial_number` | string | нет | Серийный номер |
| `firmware` | string | нет | Версия прошивки |
| `link_width` | int | нет | Текущая ширина линка |
| `link_speed` | string | нет | Текущая скорость: `Gen3` , `Gen4` , `Gen5` |
| `max_link_width` | int | нет | Максимальная ширина линка |
| `max_link_speed` | string | нет | Максимальная скорость |
| `mac_addresses` | string[] | нет | MAC-адреса портов (для сетевых устройств) |
| `present` | bool | нет | Наличие (по умолчанию `true` ) |
| + общие поля статуса | | | см. раздел выше |
`numa_node` передавайте для NIC / InfiniBand / RAID / GPU, когда источник знает CPU/NUMA affinity. Поле сохраняется в snapshot-атрибутах PCIe-компонента и дублируется в telemetry для topology use cases.
Поля `temperature_c` и `power_w` используйте для device-level telemetry GPU / accelerator / smart PCIe devices. Они не влияют на идентификацию компонента.
**Генерация serial_number при отсутствии или `"N/A"`: ** `{board_serial}-PCIE-{slot}`
**Значения `device_class`: **
| Значение | Назначение |
|----------|------------|
| `MassStorageController` | RAID-контроллеры |
| `StorageController` | HBA, SAS-контроллеры |
| `NetworkController` | Сетевые адаптеры (InfiniBand, общий) |
| `EthernetController` | Ethernet NIC |
| `FibreChannelController` | Fibre Channel HBA |
| `VideoController` | GPU, видеокарты |
| `ProcessingAccelerator` | Вычислительные ускорители (AI/ML) |
| `DisplayController` | Контроллеры дисплея (BMC VGA) |
Список открытый: допускаются произвольные строки для нестандартных классов.
``` json
"pcie_devices" : [
{
"slot" : "PCIeCard2" ,
"vendor_id" : 5555 ,
"device_id" : 4401 ,
"numa_node" : 0 ,
"temperature_c" : 48.5 ,
"power_w" : 18.2 ,
"sfp_temperature_c" : 36.2 ,
"sfp_tx_power_dbm" : -1.8 ,
"sfp_rx_power_dbm" : -2.1 ,
"bdf" : "0000:3b:00.0" ,
"device_class" : "EthernetController" ,
"manufacturer" : "Intel" ,
"model" : "X710 10GbE" ,
"serial_number" : "K65472-003" ,
"firmware" : "9.20 0x8000d4ae" ,
"mac_addresses" : [ "3c:fd:fe:aa:bb:cc" , "3c:fd:fe:aa:bb:cd" ] ,
"status" : "OK"
}
]
```
---
### power_supplies
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `slot` | string | нет | Идентификатор слота |
| `present` | bool | нет | Наличие (по умолчанию `true` ) |
| `serial_number` | string | нет | Серийный номер |
| `part_number` | string | нет | Партномер |
| `model` | string | нет | Модель |
| `vendor` | string | нет | Производитель |
| `wattage_w` | int | нет | Мощность в ваттах |
| `firmware` | string | нет | Версия прошивки |
| `input_type` | string | нет | Тип входа (например `ACWideRange` ) |
| `input_voltage` | float | нет | Входное напряжение, В (telemetry) |
| `input_power_w` | float | нет | Входная мощность, Вт (telemetry) |
| `output_power_w` | float | нет | Выходная мощность, Вт (telemetry) |
| `temperature_c` | float | нет | Температура PSU, °C (telemetry) |
| `life_remaining_pct` | float | нет | Остаточный ресурс / health, % |
| `life_used_pct` | float | нет | Использованный ресурс / wear, % |
| + общие поля статуса | | | см. раздел выше |
Поля telemetry (`input_voltage` , `input_power_w` , `output_power_w` , `temperature_c` , `life_remaining_pct` , `life_used_pct` ) сохраняются в атрибутах компонента и не влияют на его идентификацию.
PSU без `serial_number` игнорируется.
``` json
"power_supplies" : [
{
"slot" : "0" ,
"present" : true ,
"model" : "GW-CRPS3000LW" ,
"vendor" : "Great Wall" ,
"wattage_w" : 3000 ,
"serial_number" : "2P06C102610" ,
"firmware" : "00.03.05" ,
"status" : "OK" ,
"input_type" : "ACWideRange" ,
"input_power_w" : 137 ,
"output_power_w" : 104 ,
"input_voltage" : 215.25 ,
"temperature_c" : 39.5 ,
"life_remaining_pct" : 97.0
}
]
```
---
### sensors
Показания сенсоров сервера. Секция опциональная, не привязана к компонентам.
Данные хранятся как последнее известное значение (last-known-value) на уровне Asset.
``` json
"sensors" : {
"fans" : [ . . . ] ,
"power" : [ . . . ] ,
"temperatures" : [ . . . ] ,
"other" : [ . . . ]
}
```
#### sensors.fans
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `name` | string | **да ** | Уникальное имя сенсора в рамках секции |
| `location` | string | нет | Физическое расположение |
| `rpm` | int | нет | Обороты, RPM |
| `status` | string | нет | Статус: `OK` , `Warning` , `Critical` , `Unknown` |
#### sensors.power
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `name` | string | **да ** | Уникальное имя сенсора |
| `location` | string | нет | Физическое расположение |
| `voltage_v` | float | нет | Напряжение, В |
| `current_a` | float | нет | Ток, А |
| `power_w` | float | нет | Мощность, Вт |
| `status` | string | нет | Статус |
#### sensors.temperatures
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `name` | string | **да ** | Уникальное имя сенсора |
| `location` | string | нет | Физическое расположение |
| `celsius` | float | нет | Температура, °C |
| `threshold_warning_celsius` | float | нет | Порог Warning, °C |
| `threshold_critical_celsius` | float | нет | Порог Critical, °C |
| `status` | string | нет | Статус |
#### sensors.other
| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| `name` | string | **да ** | Уникальное имя сенсора |
| `location` | string | нет | Физическое расположение |
| `value` | float | нет | Значение |
| `unit` | string | нет | Единица измерения |
| `status` | string | нет | Статус |
**Правила sensors: **
- Идентификатор сенсора: пара `(sensor_type, name)` . Дубли в одном payload — берётся первое вхождение.
- Сенсоры без `name` игнорируются.
- При каждом импорте значения перезаписываются (upsert по ключу).
``` json
"sensors" : {
"fans" : [
{ "name" : "FAN1" , "location" : "Front" , "rpm" : 4200 , "status" : "OK" } ,
{ "name" : "FAN_CPU0" , "location" : "CPU0" , "rpm" : 5600 , "status" : "OK" }
] ,
"power" : [
{ "name" : "12V Rail" , "location" : "Mainboard" , "voltage_v" : 12.06 , "status" : "OK" } ,
{ "name" : "PSU0 Input" , "location" : "PSU0" , "voltage_v" : 215.25 , "current_a" : 0.64 , "power_w" : 137.0 , "status" : "OK" }
] ,
"temperatures" : [
{ "name" : "CPU0 Temp" , "location" : "CPU0" , "celsius" : 46.0 , "threshold_warning_celsius" : 80.0 , "threshold_critical_celsius" : 95.0 , "status" : "OK" } ,
{ "name" : "Inlet Temp" , "location" : "Front" , "celsius" : 22.0 , "threshold_warning_celsius" : 40.0 , "threshold_critical_celsius" : 50.0 , "status" : "OK" }
] ,
"other" : [
{ "name" : "System Humidity" , "value" : 38.5 , "unit" : "%" , "status" : "OK" }
]
}
```
---
## Обработка статусов компонентов
| Статус | Поведение |
|--------|-----------|
| `OK` | Нормальная обработка |
| `Warning` | Создаётся событие `COMPONENT_WARNING` |
| `Critical` | Создаётся событие `COMPONENT_FAILED` + запись в `failure_events` |
| `Unknown` | Компонент считается рабочим, создаётся событие `COMPONENT_UNKNOWN` |
| `Empty` | Компонент не создаётся/не обновляется |
---
## Обработка отсутствующих serial_number
| Тип | Поведение |
|-----|-----------|
| CPU | Генерируется: `{board_serial}-CPU-{socket}` |
| PCIe | Генерируется: `{board_serial}-PCIE-{slot}` (если serial = `"N/A"` или пустой) |
| Memory | Компонент игнорируется |
| Storage | Компонент игнорируется |
| PSU | Компонент игнорируется |
Если `serial_number` не уникален внутри одного payload для того же `model` :
- Первое вхождение сохраняет оригинальный серийный номер.
- Каждое следующее дублирующее получает placeholder: `NO_SN-XXXXXXXX` .
---
## Минимальный валидный пример
``` json
{
"collected_at" : "2026-02-10T15:30:00Z" ,
"target_host" : "192.168.1.100" ,
"hardware" : {
"board" : {
"serial_number" : "SRV-001"
}
}
}
```
---
## Полный пример с историей статусов
``` 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" : {
"manufacturer" : "Supermicro" ,
"product_name" : "X12DPG-QT6" ,
"serial_number" : "21D634101"
} ,
"firmware" : [
{ "device_name" : "BIOS" , "version" : "06.08.05" } ,
{ "device_name" : "BMC" , "version" : "5.17.00" }
] ,
"cpus" : [
{
"socket" : 0 ,
"model" : "INTEL(R) XEON(R) GOLD 6530" ,
"manufacturer" : "Intel" ,
"cores" : 32 ,
"threads" : 64 ,
"status" : "OK"
}
] ,
"storage" : [
{
"slot" : "OB01" ,
"type" : "NVMe" ,
"model" : "INTEL SSDPF2KX076T1" ,
"size_gb" : 7680 ,
"serial_number" : "BTAX41900GF87P6DGN" ,
"manufacturer" : "Intel" ,
"firmware" : "9CV10510" ,
"present" : true ,
"status" : "OK" ,
"status_changed_at" : "2026-02-10T15:22:00Z" ,
"status_history" : [
{ "status" : "Critical" , "changed_at" : "2026-02-10T15:10:00Z" , "details" : "I/O timeout on NVMe queue 3" } ,
{ "status" : "OK" , "changed_at" : "2026-02-10T15:22:00Z" , "details" : "Recovered after controller reset" }
]
}
] ,
"pcie_devices" : [
{
"slot" : "PCIeCard1" ,
"device_class" : "EthernetController" ,
"manufacturer" : "Intel" ,
"model" : "X710 10GbE" ,
"serial_number" : "K65472-003" ,
"mac_addresses" : [ "3c:fd:fe:aa:bb:cc" , "3c:fd:fe:aa:bb:cd" ] ,
"status" : "OK"
}
] ,
"power_supplies" : [
{
"slot" : "0" ,
"present" : true ,
"model" : "GW-CRPS3000LW" ,
"vendor" : "Great Wall" ,
"wattage_w" : 3000 ,
"serial_number" : "2P06C102610" ,
"firmware" : "00.03.05" ,
"status" : "OK" ,
"input_power_w" : 137 ,
"output_power_w" : 104 ,
"input_voltage" : 215.25
}
] ,
"sensors" : {
"fans" : [
{ "name" : "FAN1" , "location" : "Front" , "rpm" : 4200 , "status" : "OK" }
] ,
"power" : [
{ "name" : "12V Rail" , "voltage_v" : 12.06 , "status" : "OK" }
] ,
"temperatures" : [
{ "name" : "CPU0 Temp" , "celsius" : 46.0 , "threshold_warning_celsius" : 80.0 , "threshold_critical_celsius" : 95.0 , "status" : "OK" }
] ,
"other" : [
{ "name" : "System Humidity" , "value" : 38.5 , "unit" : "%" }
]
}
}
}
```