Files
bee/bible-local/proposals/2026-06-19-sfp-modules-contract-rfc.md
T

10 KiB
Raw Blame History

RFC: SFP Module Identity and Telemetry in Hardware Ingest Contract

Date: 2026-06-19 Status: proposal Target: Reanimator Core — ingest schema, validation, and storage Requested by: bee (hardware audit LiveCD) Contract version affected: 2.10 → 2.11


Задача для агента

Внести изменения в контракт ingest и реализовать их в Reanimator Core:

  1. Добавить массив sfp_modules[] внутри pcie_devices[].
  2. Обновить JSON-схему и валидатор ingest endpoint.
  3. Реализовать хранение/upsert данных SFP-модулей.
  4. Пометить скалярные поля sfp_* на уровне pcie_devices[] как deprecated.
  5. Обновить документ контракта (hardware-ingest-contract.md) до версии 2.11.

Ниже — всё необходимое для принятия решений без дополнительных вопросов.


Контекст: откуда берутся данные

Источник в bee: ethtool -m <iface> (читает EEPROM SFP/SFP+/QSFP28/QSFP-DD по стандарту MSA SFF-8472 / SFF-8636).

Связь с PCIe: ethtool -i <iface> возвращает bus-info = BDF (0000:3b:00.0), который совпадает с pcie_devices[].slot. Так bee связывает SFP-данные конкретного интерфейса с PCIe-устройством.

Один NIC — несколько модулей: карта ConnectX-6 Dx (2 порта), Intel X710 (4 порта), Mellanox HDR (2 порта). Каждый порт — отдельный ethtool -m, отдельный SFP-модуль. Одного скаляра на устройство недостаточно.

QSFP28/QSFP-DD: 4-канальные модули возвращают telemetry отдельно по каждому каналу (lane). В предложенной схеме lane-уровень не включён в первую версию — только агрегированные значения модуля в целом. Расширение до lane-уровня — отдельный RFC если понадобится.


Проблема с текущим контрактом v2.10

В pcie_devices[] есть пять скалярных полей:

sfp_temperature_c   float
sfp_tx_power_dbm    float
sfp_rx_power_dbm    float
sfp_voltage_v       float
sfp_bias_ma         float

Ограничения:

  • Нет идентификации модуля — vendor, part_number, serial_number, wavelength отсутствуют; модуль нельзя инвентаризировать как самостоятельный компонент.
  • Только один набор значений на устройство — невозможно описать 4-портовый NIC.
  • Нет типа модуля — SFP, QSFP28, DAC-кабель не различаются.
  • Нет connector/transceiver_type — невозможно понять, оптика это или медь.

Предлагаемое изменение схемы

Новая структура sfp_modules[]

Добавляется как необязательное поле внутри каждого объекта pcie_devices[].

"pcie_devices": [
  {
    "slot": "0000:3b:00.0",
    "device_class": "EthernetController",
    "model": "ConnectX-6 Dx",
    "manufacturer": "Mellanox",
    "serial_number": "MT2012X12345",
    "status": "OK",
    "sfp_modules": [
      {
        "port": 0,
        "identifier": "QSFP28",
        "connector": "LC",
        "vendor": "Mellanox",
        "part_number": "MFA1A00-C003",
        "serial_number": "MT2124VS09999",
        "revision": "A",
        "wavelength_nm": 850,
        "transceiver_type": "100GBase-SR4",
        "temperature_c": 36.4,
        "voltage_v": 3.29,
        "tx_power_dbm": -1.8,
        "rx_power_dbm": -2.1,
        "bias_ma": 7.2
      },
      {
        "port": 1,
        "identifier": "QSFP28",
        "connector": "LC",
        "vendor": "Mellanox",
        "part_number": "MFA1A00-C003",
        "serial_number": "MT2124VS09998",
        "revision": "A",
        "wavelength_nm": 850,
        "transceiver_type": "100GBase-SR4",
        "temperature_c": 35.9,
        "voltage_v": 3.28,
        "tx_power_dbm": -1.9,
        "rx_power_dbm": -2.3,
        "bias_ma": 7.1
      }
    ]
  }
]

Поля sfp_modules[]

Поле Тип Обязательно Описание
port int да Номер порта на NIC (0-based). Ключ дедупликации внутри устройства.
identifier string нет Тип модуля: SFP, SFP+, SFP28, QSFP+, QSFP28, QSFP-DD, DAC
connector string нет Тип разъёма: LC, MPO, RJ45, DAC, AOC, No separable connector
vendor string нет Производитель модуля из EEPROM
part_number string нет Партномер из EEPROM
serial_number string нет Серийный номер из EEPROM
revision string нет Ревизия из EEPROM
wavelength_nm int нет Длина волны, нм (0 для DAC/медных кабелей)
transceiver_type string нет 10GBase-SR, 10GBase-LR, 25GBase-SR, 100GBase-SR4, DAC, …
temperature_c float нет Температура модуля, °C (DOM telemetry)
voltage_v float нет Напряжение питания, В (DOM telemetry)
tx_power_dbm float нет TX оптическая мощность, dBm (DOM telemetry)
rx_power_dbm float нет RX оптическая мощность, dBm (DOM telemetry)
bias_ma float нет Bias current, мА (DOM telemetry)

Ключ дедупликации: (pcie_device.slot, sfp_modules[].port).

Модули без серийного номера — допустимы; многие DAC-кабели не имеют SN. Не игнорировать, сохранять по ключу (slot, port).


Deprecated поля

Следующие поля на уровне pcie_devices[] помечаются как deprecated начиная с v2.11:

sfp_temperature_c
sfp_tx_power_dbm
sfp_rx_power_dbm
sfp_voltage_v
sfp_bias_ma

Поведение при получении deprecated полей:

  • Продолжать принимать и сохранять (не ломать существующих интеграторов).
  • Если одновременно присутствуют sfp_modules[] и deprecated скаляры — приоритет у sfp_modules[]; скаляры игнорируются.
  • В документации пометить как deprecated since 2.11, will be removed in 3.0.

Не удалять deprecated поля из валидации в этом PR — только пометить в документации и changelog.


Правила ingest для sfp_modules[]

  • sfp_modules[] хранится как snapshot-атрибут PCIe-компонента (аналогично mac_addresses).
  • При каждом импорте — полная замена sfp_modules[] для данного pcie_devices[].slot (upsert всего массива целиком, не merge по портам).
  • Если sfp_modules отсутствует или null — существующие данные SFP не трогать (не затирать).
  • Если sfp_modules: [] (пустой массив) — трактовать как «модули не обнаружены», очистить сохранённые данные.
  • Изменение serial_number или part_number модуля на порту — создавать событие COMPONENT_CHANGED для PCIe-устройства с описанием «SFP module replaced on port N».

Изменения в документе контракта

Файл: bible-local/docs/hardware-ingest-contract.md

  1. Заголовок версии: 2.102.11, дата → 2026-06-19.
  2. Добавить в changelog:
    | 2.11 | 2026-06-19 | В `pcie_devices[]` добавлен необязательный массив `sfp_modules[]`
    с идентификацией и DOM telemetry SFP/QSFP-модулей. Скалярные поля
    sfp_temperature_c / sfp_tx_power_dbm / sfp_rx_power_dbm / sfp_voltage_v /
    sfp_bias_ma помечены как deprecated (принимаются, но sfp_modules[] имеет приоритет). |
    
  3. В секции pcie_devices добавить строку в таблицу полей:
    | `sfp_modules` | array | нет | Установленные SFP/QSFP-модули по портам (см. sfp_modules[]) |
    
  4. Добавить подсекцию #### pcie_devices[].sfp_modules[] с таблицей полей и примером JSON (из раздела выше).
  5. Пометить deprecated поля в таблице: добавить суффикс *(deprecated since 2.11)*.
  6. Обновить полный пример JSON — добавить sfp_modules к NIC-записи в pcie_devices.

Что не нужно делать в этом PR

  • Не добавлять lane-level данные QSFP (tx_power_dbm_lane_0 и т.п.) — отдельный RFC.
  • Не удалять deprecated поля — только пометить.
  • Не создавать отдельную top-level секцию network_ports — данные остаются вложенными в pcie_devices.
  • Не менять логику идентификации PCIe-компонента — serial_number SFP-модуля не является ключом для самостоятельного компонента.

Валидация

Единственное обязательное поле в sfp_modules[]port (int, >= 0).
Все остальные поля опциональны.
Дубли по port внутри одного pcie_devices[] — невалидны, возвращать 400 с описанием поля.