37 KiB
Руководство по интеграции Reanimator
Импорт серверов через JSON (Redfish/API)
Данное руководство описывает формат JSON для импорта аппаратной информации о серверах, собранной через Redfish API или другие источники мониторинга.
Принципы импорта
- Snapshot данных - JSON содержит состояние сервера на момент сбора и может включать историю изменений статуса компонентов
- Автоматическое определение LOT - классификация компонентов определяется приложением на основе vendor/model/type
- Статус компонентов - каждый компонент имеет статус работоспособности (OK, Warning, Critical, Unknown) и может передавать время проверки статуса
- Идемпотентность - повторный импорт с тем же snapshot не создает дубликаты
- Event-driven обновления - импорт создает события в timeline (LOG_COLLECTED, INSTALLED, REMOVED, FIRMWARE_CHANGED)
Формат JSON для импорта
Важно: endpoint использует строгий JSON-декодер (
DisallowUnknownFields). Любое неизвестное поле (включая вложенные объекты) приведет к400 Bad Request. Используйте толькоsnake_caseключи из этого руководства.
Структура верхнего уровня
{
"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": {...},
"cpus": [...],
"memory": [...],
"storage": [...],
"pcie_devices": [...],
"power_supplies": [...],
"firmware": [...]
}
}
Обязательные поля верхнего уровня
collected_at(string RFC3339, обязательно) - время сбора информацииtarget_host(string, опционально) - IP или hostname сервераhardware.board.serial_number(string, обязательно) - серийный номер сервера/платыsource_type(string, опционально) - тип источника:api,logfile,manualprotocol(string, опционально) - протокол сбора:redfish,ipmi,snmp,sshfilename(string, опционально) - идентификатор источника данныхhardware(object, обязательно) - структура с аппаратными компонентами
Общее поле статуса для компонентных секций
Для секций cpus, memory, storage, pcie_devices, power_supplies поддерживается дополнительное поле:
status_checked_at(string RFC3339, опционально) - дата/время, когда был проверен статус работоспособности компонентаstatus_changed_at(string RFC3339, опционально) - дата/время последнего изменения статуса компонентаstatus_at_collection(object, опционально) - зафиксированный статус на момент сбора логов:status(string) - статус в момент сбора (OK,Warning,Critical,Unknown,Empty)at(string RFC3339) - дата/время, к которому относится этот статус
status_history(array, опционально) - история статусов компонента:status(string) - статус (OK,Warning,Critical,Unknown,Empty)changed_at(string RFC3339) - дата/время смены статусаdetails(string, опционально) - пояснение к переходу статуса
error_description(string, опционально) - текст ошибки/диагностики для статуса компонента (например приWarning/Critical)
Правила экспорта JSON для внешнего проекта
Используйте эти правила, если JSON формируется внешним сервисом/экспортером:
- Всегда передавайте
statusкак текущее состояние компонента в snapshot. - Если есть точное время последней смены, передавайте
status_changed_at(RFC3339, UTC). - Если источник умеет фиксировать состояние именно на момент сбора, передавайте
status_at_collectionc полямиstatusиat. - Если источник хранит историю (например Windows Event Log), передавайте
status_historyотсортированным поchanged_atпо возрастанию. - В
status_historyне отправляйте записи безchanged_at; такие записи игнорируются. - Для совместимости допускается передавать только старые поля (
status,status_checked_at) без истории. - Все даты/время в исторических полях должны быть RFC3339; рекомендуется использовать UTC (
Z).
Секция hardware
1. Board (Материнская плата / Server)
Назначение: Основная информация о сервере/материнской плате. Эта информация используется для создания/обновления Asset.
{
"board": {
"manufacturer": "Supermicro",
"product_name": "X12DPG-QT6",
"serial_number": "21D634101",
"part_number": "X12DPG-QT6-REV1.01",
"uuid": "d7ef2fe5-2fd0-11f0-910a-346f11040868"
}
}
Поля:
serial_number(string, обязательно) - серийный номер материнской платы/сервера (используется какvendor_serialдля Asset)manufacturer(string, опционально) - производитель (используется какvendorдля Asset)product_name(string, опционально) - модель (используется какmodelдля Asset)part_number(string, опционально) - партномерuuid(string, опционально) - UUID системы
Примечание: Если manufacturer или product_name = "NULL", они интерпретируются как отсутствующие.
2. CPUs (Процессоры)
Назначение: Информация о установленных процессорах.
{
"cpus": [
{
"socket": 0,
"model": "INTEL(R) XEON(R) GOLD 6530",
"cores": 32,
"threads": 64,
"frequency_mhz": 2100,
"max_frequency_mhz": 4000,
"manufacturer": "Intel",
"status": "OK",
"status_checked_at": "2026-02-10T15:28:00Z"
},
{
"socket": 1,
"model": "INTEL(R) XEON(R) GOLD 6530",
"cores": 32,
"threads": 64,
"frequency_mhz": 2100,
"max_frequency_mhz": 4000,
"manufacturer": "Intel",
"status": "OK",
"status_checked_at": "2026-02-10T15:28:00Z"
}
]
}
Поля:
socket(int, обязательно) - номер сокета (используется для формирования уникального идентификатора)model(string, обязательно) - модель процессораcores(int, опционально) - количество ядерthreads(int, опционально) - количество потоковfrequency_mhz(int, опционально) - текущая частота в МГцmax_frequency_mhz(int, опционально) - максимальная частота в МГцmanufacturer(string, опционально) - производитель (Intel, AMD, etc.)status(string, опционально) - статус:OK,Warning,Critical,Unknownstatus_checked_at(string RFC3339, опционально) - дата/время проверки статуса
Генерация serial_number:
- Формат:
{board_serial}-CPU-{socket} - Пример:
21D634101-CPU-0,21D634101-CPU-1
LOT автоопределение:
- Формат:
CPU_{NORMALIZED_MODEL} - Пример:
CPU_XEON_GOLD_6530,CPU_EPYC_7763
3. Memory (Модули памяти)
Назначение: Информация о модулях памяти (DIMM).
{
"memory": [
{
"slot": "CPU0_C0D0",
"location": "CPU0_C0D0",
"present": true,
"size_mb": 32768,
"type": "DDR5",
"max_speed_mhz": 4800,
"current_speed_mhz": 4800,
"manufacturer": "Hynix",
"serial_number": "80AD032419E17CEEC1",
"part_number": "HMCG88AGBRA191N",
"status": "OK",
"status_checked_at": "2026-02-10T15:28:00Z"
},
{
"slot": "CPU0_C1D0",
"location": "CPU0_C1D0",
"present": false,
"size_mb": 0,
"type": null,
"manufacturer": null,
"serial_number": null,
"part_number": null,
"status": "Empty"
}
]
}
Поля:
slot(string, обязательно) - идентификатор слотаlocation(string, опционально) - физическое расположениеpresent(bool, обязательно) - наличие модуля в слотеsize_mb(int, опционально) - размер в МБtype(string, опционально) - тип памяти:DDR4,DDR5,DDR3, etc.max_speed_mhz(int, опционально) - максимальная частотаcurrent_speed_mhz(int, опционально) - текущая частотаmanufacturer(string, опционально) - производительserial_number(string, условно обязательно если present=true) - серийный номерpart_number(string, опционально) - партномерstatus(string, опционально) - статус:OK,Warning,Critical,Unknown,Emptystatus_checked_at(string RFC3339, опционально) - дата/время проверки статуса
Обработка:
- Если
present = falseилиstatus = "Empty", компонент не создается/не обновляется - Если модуль был в предыдущем snapshot, но отсутствует в текущем - создается событие REMOVED
LOT автоопределение:
- Формат:
DIMM_{TYPE}_{SIZE_GB}GB - Пример:
DIMM_DDR5_32GB,DIMM_DDR4_64GB
4. Storage (Диски)
Назначение: Информация о дисках (SSD, HDD, NVMe).
{
"storage": [
{
"slot": "OB01",
"type": "NVMe",
"model": "INTEL SSDPF2KX076T1",
"size_gb": 7680,
"serial_number": "BTAX41900GF87P6DGN",
"manufacturer": "Intel",
"firmware": "9CV10510",
"interface": "NVMe",
"present": true,
"status": "OK"
},
{
"slot": "FP00HDD00",
"type": "HDD",
"model": "ST12000NM0008",
"size_gb": 12000,
"serial_number": "ZJV01234",
"manufacturer": "Seagate",
"firmware": "SN03",
"interface": "SATA",
"present": true,
"status": "OK"
}
]
}
Поля:
slot(string, обязательно) - идентификатор слотаtype(string, опционально) - тип:NVMe,SSD,HDDmodel(string, обязательно) - модель дискаsize_gb(int, опционально) - размер в ГБserial_number(string, обязательно) - серийный номерmanufacturer(string, опционально) - производитель (может быть VID в hex формате типа "8086")firmware(string, опционально) - версия прошивкиinterface(string, опционально) - интерфейс:NVMe,SATA,SASpresent(bool, обязательно) - наличие диска в слотеstatus(string, опционально) - статус:OK,Warning,Critical,Unknownstatus_checked_at(string RFC3339, опционально) - дата/время проверки статуса
Обработка firmware:
- Если версия firmware изменилась относительно предыдущего observation - создается событие FIRMWARE_CHANGED
LOT автоопределение:
- Формат:
{TYPE}_{INTERFACE}_{SIZE_TB}TBили{TYPE}_{INTERFACE}_{SIZE_GB}GB - Пример:
SSD_NVME_07.68TB,HDD_SATA_12TB
5. Power Supplies (Блоки питания)
Назначение: Информация о блоках питания.
{
"power_supplies": [
{
"slot": "0",
"present": true,
"model": "GW-CRPS3000LW",
"vendor": "Great Wall",
"wattage_w": 3000,
"serial_number": "2P06C102610",
"part_number": "V0310C9000000000",
"firmware": "00.03.05",
"status": "OK",
"status_checked_at": "2026-02-10T15:28:00Z",
"input_type": "ACWideRange",
"input_power_w": 137,
"output_power_w": 104,
"input_voltage": 215.25
}
]
}
Поля:
slot(string, обязательно) - идентификатор слотаpresent(bool, обязательно) - наличие PSUmodel(string, опционально) - модельvendor(string, опционально) - производительwattage_w(int, опционально) - мощность в ваттахserial_number(string, условно обязательно если present=true) - серийный номерpart_number(string, опционально) - партномерfirmware(string, опционально) - версия прошивкиstatus(string, опционально) - статус:OK,Warning,Critical,Unknownstatus_checked_at(string RFC3339, опционально) - дата/время проверки статусаinput_type(string, опционально) - тип входаinput_power_w(int, опционально) - входная мощность (telemetry)output_power_w(int, опционально) - выходная мощность (telemetry)input_voltage(float, опционально) - входное напряжение (telemetry)
Примечание: Telemetry поля (input_power_w, output_power_w, input_voltage) сохраняются в observation, но не влияют на Component.
LOT автоопределение:
- Формат:
PSU_{WATTAGE}W - Пример:
PSU_3000W,PSU_1600W
6. PCIe Devices (PCIe устройства)
Назначение: Информация о PCIe устройствах (NIC, RAID контроллеры, GPU, etc.).
{
"pcie_devices": [
{
"slot": "PCIeCard1",
"vendor_id": 32902,
"device_id": 2912,
"bdf": "0000:18:00.0",
"device_class": "MassStorageController",
"manufacturer": "Intel",
"model": "RAID Controller RSP3DD080F",
"link_width": 8,
"link_speed": "Gen3",
"max_link_width": 8,
"max_link_speed": "Gen3",
"serial_number": "RAID-001-12345",
"firmware": "50.9.1-4296",
"status": "OK",
"status_checked_at": "2026-02-10T15:28:00Z"
},
{
"slot": "PCIeCard2",
"vendor_id": 5555,
"device_id": 4401,
"bdf": "",
"device_class": "NetworkController",
"manufacturer": "Mellanox",
"model": "ConnectX-5",
"link_width": 16,
"link_speed": "Gen3",
"max_link_width": 16,
"max_link_speed": "Gen3",
"serial_number": "MT2892012345",
"status": "OK"
}
]
}
Поля:
slot(string, обязательно) - идентификатор слотаvendor_id(int, опционально) - PCI Vendor ID (hex в decimal)device_id(int, опционально) - PCI Device ID (hex в decimal)bdf(string, опционально) - Bus:Device.Function (например "0000:18:00.0")device_class(string, опционально) - класс устройства:NetworkController,MassStorageController,DisplayController, etc.manufacturer(string, опционально) - производительmodel(string, опционально) - модель устройстваlink_width(int, опционально) - текущая ширина линка (x1, x4, x8, x16)link_speed(string, опционально) - текущая скорость линка (Gen3, Gen4, Gen5)max_link_width(int, опционально) - максимальная ширина линкаmax_link_speed(string, опционально) - максимальная скорость линкаserial_number(string, опционально) - серийный номер (если доступен, иначе генерируется)firmware(string, опционально) - версия прошивкиstatus(string, опционально) - статус:OK,Warning,Critical,Unknownstatus_checked_at(string RFC3339, опционально) - дата/время проверки статуса
Генерация serial_number (если отсутствует):
- Формат:
{board_serial}-PCIE-{slot} - Пример:
21D634101-PCIE-PCIeCard1
LOT автоопределение:
- Формат:
PCIE_{DEVICE_CLASS}_{NORMALIZED_MODEL}илиPCIE_{DEVICE_CLASS}_{VENDOR_ID}_{DEVICE_ID} - Пример:
PCIE_NETWORK_CONNECTX5,PCIE_STORAGE_32902_2912
7. Firmware (Прошивки системных компонентов)
Назначение: Информация о версиях прошивок системных компонентов (BIOS, BMC, etc.).
{
"firmware": [
{
"device_name": "BIOS",
"version": "06.08.05 (2025-05-15 18:39:00)"
},
{
"device_name": "BMC",
"version": "5.17.00 (2025-04-22 12:06:31)"
}
]
}
Поля:
device_name(string, обязательно) - название устройства:BIOS,BMC,CPLD, etc.version(string, обязательно) - версия прошивки
Обработка:
- Firmware данные сохраняются в observation
- Изменения версий firmware системных компонентов создают события FIRMWARE_CHANGED для Asset
Полный пример 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",
"part_number": "X12DPG-QT6-REV1.01",
"uuid": "d7ef2fe5-2fd0-11f0-910a-346f11040868"
},
"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",
"cores": 32,
"threads": 64,
"frequency_mhz": 2100,
"max_frequency_mhz": 4000,
"manufacturer": "Intel",
"status": "OK"
},
{
"socket": 1,
"model": "INTEL(R) XEON(R) GOLD 6530",
"cores": 32,
"threads": 64,
"frequency_mhz": 2100,
"max_frequency_mhz": 4000,
"manufacturer": "Intel",
"status": "OK"
}
],
"memory": [
{
"slot": "CPU0_C0D0",
"location": "CPU0_C0D0",
"present": true,
"size_mb": 32768,
"type": "DDR5",
"max_speed_mhz": 4800,
"current_speed_mhz": 4800,
"manufacturer": "Hynix",
"serial_number": "80AD032419E17CEEC1",
"part_number": "HMCG88AGBRA191N",
"status": "OK"
},
{
"slot": "CPU1_C0D0",
"location": "CPU1_C0D0",
"present": true,
"size_mb": 32768,
"type": "DDR5",
"max_speed_mhz": 4800,
"current_speed_mhz": 4800,
"manufacturer": "Hynix",
"serial_number": "80AD032419E17D6FBA",
"part_number": "HMCG88AGBRA191N",
"status": "OK"
}
],
"storage": [
{
"slot": "OB01",
"type": "NVMe",
"model": "INTEL SSDPF2KX076T1",
"size_gb": 7680,
"serial_number": "BTAX41900GF87P6DGN",
"manufacturer": "Intel",
"firmware": "9CV10510",
"interface": "NVMe",
"present": true,
"status": "OK"
},
{
"slot": "OB02",
"type": "NVMe",
"model": "INTEL SSDPF2KX076T1",
"size_gb": 7680,
"serial_number": "BTAX41900BEG7P6DGN",
"manufacturer": "Intel",
"firmware": "9CV10510",
"interface": "NVMe",
"present": true,
"status": "OK"
}
],
"pcie_devices": [
{
"slot": "PCIeCard1",
"vendor_id": 32902,
"device_id": 2912,
"bdf": "0000:18:00.0",
"device_class": "MassStorageController",
"manufacturer": "Intel",
"model": "RAID Controller",
"serial_number": "RAID-001-12345",
"status": "OK"
}
],
"power_supplies": [
{
"slot": "0",
"present": true,
"model": "GW-CRPS3000LW",
"vendor": "Great Wall",
"wattage_w": 3000,
"serial_number": "2P06C102610",
"part_number": "V0310C9000000000",
"firmware": "00.03.05",
"status": "OK",
"input_power_w": 137,
"output_power_w": 104,
"input_voltage": 215.25
}
]
}
}
Процесс обработки импорта
1. Валидация входных данных
- Проверка наличия обязательных полей:
collected_at,hardware.board.serial_number - Проверка формата
collected_at(RFC3339) - Проверка наличия
hardware.board.serial_number
2. Поиск или создание Asset
Поиск: по hardware.board.serial_number (= vendor_serial в таблице assets)
Создание/Обновление:
vendor_serial = board.serial_number
vendor = board.manufacturer (если != "NULL")
model = board.product_name (если != "NULL")
name = target_host (если передан), иначе `hardware.board.serial_number`
Примечание: Asset должен быть связан с Project. Если project_id не задан, используется default project для данного импорта.
3. Обработка компонентов
Для каждого типа компонентов (cpus, memory, storage, pcie_devices, power_supplies):
3.1. Фильтрация
- Игнорировать компоненты с
present = false(кроме создания REMOVED events) - Игнорировать компоненты без serial_number (после генерации, если применимо)
3.2. Определение LOT
- Автоматически определить LOT на основе vendor/model/type/size
- Создать LOT если не существует
- Связать component с lot_id
3.3. Поиск или создание Component
Поиск: по vendor_serial
Создание/Обновление:
vendor_serial = {serial_number или generated}
vendor = {manufacturer}
model = {model}
lot_id = {auto-determined lot}
3.4. Создание Observation
Для каждого компонента создается observation запись:
log_bundle_id = {created bundle}
asset_id = {asset.id}
component_id = {component.id}
observed_at = collected_at
Дополнительные данные сохраняются в JSON поле observation (slot, status, firmware, telemetry, etc.)
3.5. Обновление Installations
Логика:
- Если компонент уже установлен в этот asset (
installations.removed_at IS NULL) - ничего не делать - Если компонент был в другом asset - закрыть старую installation (установить
removed_at) - Создать новую installation:
asset_id = {asset.id} component_id = {component.id} installed_at = collected_at (или first_seen_at если компонент новый) removed_at = NULL
3.6. Определение removed компонентов
Сравнить текущий snapshot с предыдущим observation для этого asset:
- Если компонент был в предыдущем observation, но отсутствует в текущем - закрыть installation (
removed_at = collected_at)
4. Создание Timeline Events
События создаются автоматически на основе изменений:
LOG_COLLECTED:
subject_type = "asset"
subject_id = asset.id
event_type = "LOG_COLLECTED"
event_time = collected_at
INSTALLED: (при создании новой installation)
subject_type = "component"
subject_id = component.id
event_type = "INSTALLED"
event_time = installed_at
asset_id = asset.id
component_id = component.id
REMOVED: (при закрытии installation)
subject_type = "component"
subject_id = component.id
event_type = "REMOVED"
event_time = removed_at
asset_id = asset.id
component_id = component.id
FIRMWARE_CHANGED: (при изменении firmware версии)
subject_type = "component" (или "asset" для BIOS/BMC)
subject_id = {id}
event_type = "FIRMWARE_CHANGED"
event_time = collected_at
firmware_version = {new version}
5. Обработка статусов компонентов
Статусы (OK, Warning, Critical, Unknown) сохраняются в observation и могут быть использованы для:
- Анализа трендов деградации
- Автоматического создания failure events (если
status = "Critical") - Dashboard отображения текущего состояния
API Endpoint для импорта
POST /ingest/hardware
Content-Type: application/json
{
"collected_at": "2026-02-10T15:30:00Z",
"target_host": "10.10.10.103",
"hardware": {...}
}
Ответ при успехе (201 Created)
{
"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
}
}
Ответ при дубликате (200 OK)
{
"status": "success",
"bundle_id": "lb_01J...",
"asset_id": "mach_01J...",
"collected_at": "2026-02-10T15:30:00Z",
"duplicate": true,
"message": "LogBundle with this content hash already exists"
}
Ответ при ошибке (400 Bad Request)
{
"status": "error",
"error": "validation_failed",
"details": {
"field": "hardware.board.serial_number",
"message": "serial_number is required"
}
}
Частые причины 400 Bad Request
- Лишние поля в JSON (даже глубоко во вложенных объектах).
- Неверное имя ключа (например,
targetHostвместоtarget_host). - Неверный формат даты (
collected_atдолжен быть RFC3339). - Пустой
hardware.board.serial_number.
Правила автоопределения LOT
CPU
Формат: CPU_{VENDOR}_{MODEL_NORMALIZED}
Пример:
"INTEL(R) XEON(R) GOLD 6530" -> "CPU_INTEL_XEON_GOLD_6530"
"AMD EPYC 7763" -> "CPU_AMD_EPYC_7763"
Memory (DIMM)
Формат: DIMM_{TYPE}_{SIZE_GB}GB
Пример:
DDR5 32GB -> "DIMM_DDR5_32GB"
DDR4 64GB -> "DIMM_DDR4_64GB"
Storage
Формат: {TYPE}_{INTERFACE}_{SIZE_TB}TB (или GB для маленьких дисков)
Пример:
NVMe 7.68TB -> "SSD_NVME_07.68TB"
HDD 12TB -> "HDD_SATA_12TB"
SSD 960GB -> "SSD_SATA_0.96TB" или "SSD_SATA_960GB"
Power Supply
Формат: PSU_{WATTAGE}W_{VENDOR_NORMALIZED}
Пример:
3000W Great Wall -> "PSU_3000W_GREAT_WALL"
1600W Delta -> "PSU_1600W_DELTA"
PCIe Device
Формат: PCIE_{DEVICE_CLASS}_{MODEL_NORMALIZED} или PCIE_{DEVICE_CLASS}_{VENDOR_ID}_{DEVICE_ID}
Пример:
Network Mellanox ConnectX-5 -> "PCIE_NETWORK_CONNECTX5"
Storage Intel RAID -> "PCIE_STORAGE_INTEL_RAID"
Unknown 32902:2912 -> "PCIE_STORAGE_32902_2912"
Правила нормализации
- Удаление специальных символов:
(,),-,®,™, пробелы заменяются на_ - Uppercase: все символы в верхнем регистре
- Множественные подчеркивания: заменяются на одно
- Префиксы: убираются общие префиксы типа
MODEL:,PN:, etc.
Статусы компонентов
Возможные значения
OK- компонент работает нормальноWarning- есть предупреждения (degraded, warning threshold)Critical- критическое состояние (failed, error)Unknown- статус неизвестен или не поддерживаетсяEmpty- слот пустой (только для memory, pcie_devices)
Обработка статусов
OK:
- Нормальная обработка, никаких дополнительных действий
Warning:
- Создать observation с флагом warning
- Опционально: создать timeline event
COMPONENT_WARNING
Critical:
- Создать observation с флагом critical
- Автоматически создать failure_event для этого компонента
- Создать timeline event
COMPONENT_FAILED
Unknown:
- Сохранить как есть, считать компонент рабочим
Empty:
- Не создавать component/observation для этого слота
Обработка отсутствующих полей
serial_number
CPU: генерируется как {board_serial}-CPU-{socket}
PCIe Device: генерируется как {board_serial}-PCIE-{slot} (если serial_number = "N/A" или пустой)
Другие компоненты: если serial_number отсутствует и не может быть сгенерирован - компонент игнорируется
manufacturer
Если vendor_id присутствует (PCIe): используется lookup таблица PCI vendors
8086->Intel10de->NVIDIA15b3->Mellanox- etc.
Если "NULL" или пустой: сохраняется как NULL в БД
status
Если отсутствует: считается Unknown
firmware
Если отсутствует: не создается FIRMWARE_CHANGED event
Примеры использования
Пример 1: Минимальный snapshot
{
"collected_at": "2026-02-10T15:30:00Z",
"target_host": "192.168.1.100",
"hardware": {
"board": {
"serial_number": "TEST-SERVER-001"
},
"cpus": [
{
"socket": 0,
"model": "Intel Xeon Gold 6530"
}
],
"memory": [],
"storage": [],
"pcie_devices": [],
"power_supplies": []
}
}
Пример 2: Server с историей "сломан -> починен"
{
"collected_at": "2026-02-10T15:30:00Z",
"target_host": "prod-db-01",
"hardware": {
"board": {
"manufacturer": "Dell",
"product_name": "PowerEdge R740",
"serial_number": "CN7475162Q0123"
},
"storage": [
{
"slot": "Disk.Bay.0",
"type": "SSD",
"model": "Samsung PM1733",
"serial_number": "S5GUNG0N123456",
"firmware": "9CV10510",
"interface": "NVMe",
"present": true,
"status": "OK",
"status_changed_at": "2026-02-10T15:22:00Z",
"status_at_collection": {
"status": "OK",
"at": "2026-02-10T15:30: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"
}
]
},
{
"slot": "Disk.Bay.1",
"type": "SSD",
"model": "Samsung PM1733",
"serial_number": "S5GUNG0N123457",
"firmware": "9CV10510",
"interface": "NVMe",
"present": true,
"status": "OK"
}
]
}
}
Обработка:
- Disk.Bay.0 получит текущий статус
OK - История статусов сохранится в
observations.details.status_history - Автоматический
failure_eventне создается, так как текущий статус snapshot неCritical
Пример 3: Замена памяти
Snapshot 1 (до замены):
{
"collected_at": "2026-02-09T10:00:00Z",
"target_host": "web-01",
"hardware": {
"board": {"serial_number": "SRV001"},
"memory": [
{
"slot": "DIMM_A1",
"serial_number": "OLD-DIMM-001",
"present": true,
"status": "OK"
}
]
}
}
Snapshot 2 (после замены):
{
"collected_at": "2026-02-10T14:00:00Z",
"target_host": "web-01",
"hardware": {
"board": {"serial_number": "SRV001"},
"memory": [
{
"slot": "DIMM_A1",
"serial_number": "NEW-DIMM-002",
"present": true,
"status": "OK"
}
]
}
}
Обработка:
- Компонент OLD-DIMM-001: закрывается installation (
removed_at = 2026-02-10T14:00:00Z), создается REMOVED event - Компонент NEW-DIMM-002: создается новый component, создается installation, создается INSTALLED event
Интеграция с существующим кодом
Текущий эндпоинт /ingest/logbundle уже реализует часть этой логики. Новый формат должен:
- Быть обратно совместимым - старый формат продолжает работать
- Использовать ту же инфраструктуру - LogBundle, Observations, Installations
- Расширить observation JSON - добавить поля status, slot, telemetry
- Добавить LOT автоопределение - новая функция в
internal/ingest - Добавить обработку статусов - автоматическое создание failure events
Предлагаемые изменения
Новый endpoint: POST /ingest/hardware (принимает новый формат)
Старый endpoint: POST /ingest/logbundle (остается без изменений)
Общая логика: оба endpoint используют общий ingest.Service с расширенной обработкой
Следующие шаги
- Реализовать парсер нового формата -
internal/ingest/parser_hardware.go - Добавить LOT автоопределение -
internal/ingest/lot_classifier.go - Расширить observation модель - добавить JSON поля для status, slot, etc.
- Реализовать обработку статусов - автосоздание failure events
- Добавить endpoint -
POST /ingest/hardware - Написать тесты - unit + integration тесты для нового формата
- Документировать API - OpenAPI спецификация