Files
Michael Chus 1977730d93 Add hardware-ingest-json and submodule-integration contracts; expand go-database cursor safety
Synthesized from bible-local reviews across bee, logpile, core, chart, PriceForge:
- rules/patterns/hardware-ingest-json/contract.md — Reanimator JSON ingest schema v2.10
- rules/patterns/submodule-integration/contract.md — read-only submodule principle
- go-database: add driver-level violation symptoms for cursor safety rule

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 10:17:50 +03:00

15 KiB
Raw Permalink Blame History

Contract: Hardware Ingest JSON

Version: 2.10 Source: bee/bible-local/docs/hardware-ingest-contract.md (canonical upstream)

Стандартный JSON-контракт для передачи данных об аппаратном обеспечении серверов в Reanimator. Используется в bee, logpile, core и внешних интеграторах (Redfish-коллекторы, CMDB-экспортёры).

Актуальная версия: https://git.mchus.pro/reanimator/core/src/branch/main/bible-local/docs/hardware-ingest-contract.md

Принципы

  1. Snapshot — JSON описывает состояние сервера на момент сбора. Может включать историю изменений статуса.
  2. Идемпотентность — повторная отправка идентичного payload не создаёт дублей (дедупликация по хешу).
  3. Частичность — можно передавать только те секции, данные по которым доступны. Пустой массив и отсутствие секции эквивалентны.
  4. Строгая схема — endpoint использует строгий JSON-декодер; неизвестные поля приводят к 400 Bad Request.
  5. Event-driven — импорт создаёт события в timeline (LOG_COLLECTED, INSTALLED, REMOVED, FIRMWARE_CHANGED и др.).
  6. Без синтеза — сборщик передаёт только фактически собранные значения. Запрещено придумывать serial_number, component_ref, message, message_id или иные идентификаторы, если источник их не предоставил.

Endpoint

POST /ingest/hardware
Content-Type: application/json

Ответ 202 Accepted с job_id. Результат: GET /ingest/hardware/jobs/{job_id}.

Структура верхнего уровня

{
  "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":         { ... },
    "event_logs":      [ ... ],
    "platform_config": { ... }
  }
}
Поле Тип Обязательно Описание
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 История переходов (status, changed_at обязательны)
error_description string Текст ошибки/диагностики
manufactured_year_week string Дата производства YYYY-Www, например 2024-W07

Правила статуса:

  • Не включайте записи status_history без changed_at.
  • status_history сортировать по changed_at по возрастанию.
  • Все даты — RFC3339, рекомендуется UTC (Z).
Статус Поведение
OK Нормальная обработка
Warning Создаётся событие COMPONENT_WARNING
Critical Создаётся событие COMPONENT_FAILED + запись в failure_events
Unknown Компонент считается рабочим, создаётся событие COMPONENT_UNKNOWN
Empty Компонент не создаётся/не обновляется

Секции hardware

board (обязательная)

Поле Тип Обязательно Описание
serial_number string да Серийный номер (ключ идентификации Asset)
manufacturer string нет Производитель
product_name string нет Модель
part_number string нет Партномер
uuid string нет UUID системы

Значения "NULL" в строковых полях трактуются как отсутствие данных.

firmware

Поле Тип Обязательно
device_name string да
version string да

Записи с пустым device_name или version игнорируются. Изменение версии создаёт событие FIRMWARE_CHANGED.

cpus

Поле Тип Описание
socket int обязательно; используется для генерации serial
model string Модель процессора
manufacturer string
cores / threads int
frequency_mhz / max_frequency_mhz int
temperature_c float Telemetry, °C
power_w float Telemetry, Вт
throttled bool Thermal/power throttling
correctable_error_count / uncorrectable_error_count int
life_remaining_pct / life_used_pct float Health/wear, %
serial_number string Если доступен
firmware string Версия микрокода (Microcode level — передавать как есть)
present bool По умолчанию true

Генерация serial при отсутствии: {board_serial}-CPU-{socket}

memory

Поле Тип Описание
slot string
present bool По умолчанию true
serial_number string Обязателен для создания записи
part_number string Используется как модель
manufacturer string
size_mb int
type string DDR3, DDR4, DDR5
max_speed_mhz / current_speed_mhz int
temperature_c float Telemetry
correctable_ecc_error_count / uncorrectable_ecc_error_count int
life_remaining_pct / life_used_pct / spare_blocks_remaining_pct float
performance_degraded / data_loss_detected bool

Модуль без serial_number, с present=false или status=Empty игнорируется.

storage

Поле Тип Описание
slot string BDF (0000:18:00.0) для PCIe-подключённых
serial_number string Обязателен для создания записи
model / manufacturer string
type string NVMe, SSD, HDD
interface string NVMe, SATA, SAS
size_gb int
logical_block_size_bytes int64 Логический размер блока, например 512 или 4096
physical_block_size_bytes int64 Физический размер блока
metadata_bytes_per_block int64 Metadata/protection bytes на блок, например 0 или 8
temperature_c float Telemetry
power_on_hours / power_cycles / unsafe_shutdowns int64
media_errors / error_log_entries int64
written_bytes / read_bytes int64
life_used_pct / life_remaining_pct / available_spare_pct float
reallocated_sectors / current_pending_sectors / offline_uncorrectable int64
firmware string Изменение создаёт FIRMWARE_CHANGED
present bool По умолчанию true

Формат 512+8 не передаётся строкой — только через logical_block_size_bytes + metadata_bytes_per_block. Диск без serial_number игнорируется.

pcie_devices

Поле Тип Описание
slot string Канонический адрес (BDF). bdf — deprecated alias, нормализуется при ingest
vendor_id / device_id int PCI ID (decimal)
numa_node int NUMA/CPU affinity
device_class string MassStorageController, StorageController, NetworkController, EthernetController, FibreChannelController, VideoController, ProcessingAccelerator, DisplayController (список открытый)
manufacturer / model / serial_number / firmware string
link_width / max_link_width int
link_speed / max_link_speed string Gen3, Gen4, Gen5
mac_addresses string[] MAC-адреса портов
temperature_c / power_w float Device-level telemetry
life_remaining_pct / life_used_pct float
ecc_corrected_total / ecc_uncorrected_total int64
hw_slowdown bool
battery_charge_pct / battery_health_pct / battery_temperature_c / battery_voltage_v float
battery_replace_required bool
sfp_temperature_c / sfp_tx_power_dbm / sfp_rx_power_dbm / sfp_voltage_v / sfp_bias_ma float Optical telemetry
present bool По умолчанию true

Генерация serial при отсутствии или "N/A": {board_serial}-PCIE-{slot}

power_supplies

Поле Тип Описание
slot string
present bool По умолчанию true
serial_number string Обязателен для создания записи
part_number / model / vendor string
wattage_w int
firmware string
input_type string Например ACWideRange
input_voltage / input_power_w / output_power_w / temperature_c float Telemetry
life_remaining_pct / life_used_pct float

PSU без serial_number игнорируется.

sensors (опционально)

Данные хранятся как last-known-value на уровне Asset. Идентификатор: (sensor_type, name). Поле location передавать не нужно — игнорируется. Сенсоры без name игнорируются.

"sensors": {
  "fans":         [{ "name": "FAN1", "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": "%" }]
}

event_logs (опционально)

Нормализованные операционные логи. Не попадают в history timeline. Дедуплицируются по (asset, source, fingerprint).

Поле Тип Обязательно Описание
source string да host, bmc, redfish
message string да Нормализованный текст события
event_time string RFC3339 нет
severity string нет OK, Info, Warning, Critical, Unknown
message_id string нет Код события источника
component_ref string нет Ссылка на компонент/слот
fingerprint string нет Внешний dedup-key; если нет — система вычисляет свой
is_active bool нет Событие всё ещё активно
raw_payload object нет Сырой vendor-specific payload

Запрещено синтезировать message, message_id, component_ref, serial/device identifiers.

platform_config (опционально)

Произвольный объект с настройками платформы (BIOS/Redfish/IPMI) как есть из источника. При каждом импорте хранится latest-snapshot per machine.

Обработка отсутствующих serial_number

Интегратор не подставляет вымышленные значения, хеши или placeholder-идентификаторы. Разрешены только server-side fallback-правила:

Тип Поведение
CPU Генерируется: {board_serial}-CPU-{socket}
PCIe Генерируется: {board_serial}-PCIE-{slot}
Memory Компонент игнорируется
Storage Компонент игнорируется
PSU Компонент игнорируется

Если serial_number не уникален внутри payload для того же model: первое вхождение — оригинальный serial, дубли получают NO_SN-XXXXXXXX.

Минимальный валидный пример

{
  "collected_at": "2026-02-10T15:30:00Z",
  "target_host": "192.168.1.100",
  "hardware": {
    "board": {
      "serial_number": "SRV-001"
    }
  }
}

Changelog

Версия Дата Изменения
2.10 2026-04-29 hardware.storage[]: добавлены logical_block_size_bytes, physical_block_size_bytes, metadata_bytes_per_block
2.9 2026-03-19 Добавлена секция hardware.platform_config
2.8 2026-03-15 Поле location удалено из всех sensors.*
2.7 2026-03-15 Явно запрещён синтез данных в event_logs
2.6 2026-03-15 Добавлена секция event_logs
2.5 2026-03-15 Добавлено manufactured_year_week для всех компонентов
2.4 2026-03-15 Component telemetry: health/life поля для всех секций
2.0 2026-02-01 status_history, status_changed_at; async job response
1.0 2026-01-01 Начальная версия