Skip to content

Add the report transceiver command - #2880

Draft
berendt wants to merge 3 commits into
implement/issue-2876-hardware-report-groundworkfrom
implement/issue-2876-report-transceiver
Draft

berendt wants to merge 3 commits into
implement/issue-2876-hardware-report-groundworkfrom
implement/issue-2876-report-transceiver

Conversation

@berendt

@berendt berendt commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

This pull request adds osism report transceiver: a live inventory of the pluggable transceivers and the surrounding hardware of every physical network port on the managed Linux nodes and SONiC switches, as table, CSV or JSON.

It is the second of a stack of three and builds on #2879, which adds the shared helpers under osism/utils/hardware/. The base branch of this pull request is the branch of #2879.

Commits

  1. Collect transceiver, NIC and platform data on the devices: the Linux collector gains the sections ethtool, module, nic and system; the SONiC collector gains transceiver, dom and system.
  2. Parse transceiver, NIC and platform data: parsers for ethtool, ethtool -i, ethtool --show-fec, ethtool -m, lspci -vmm, devlink dev info and the SONiC tables TRANSCEIVER_INFO, TRANSCEIVER_FIRMWARE_INFO, TRANSCEIVER_DOM_SENSOR and EEPROM_INFO. Field names that differ between community SONiC and Enterprise SONiC are handled with a list of candidate keys per output field.
  3. Add the report transceiver command: the Transceiver command in osism/commands/report.py and its entry point in setup.cfg.

Behavior

  • Without arguments the command reports every physical port of all managed nodes and SONiC switches. Devices are selected with NetBox filters (--site, --role, --rack, --tag, --filter KEY=VALUE and so on), name patterns, --limit and --type.
  • A port without a module is a row with present = false, not a failure.
  • Every row shows the NetBox interface the port was matched to and the mapping method, or none. NetBox interfaces without a live port are listed per device.
  • SR-IOV virtual functions and InfiniBand ports appear with --include-vf and --include-infiniband.
  • A device that cannot be queried is listed as failed and leaves the exit code at 0. --strict turns it into 1.
  • Without NetBox the command reports the nodes of the inventory and rejects NetBox filters.
  • --dump-raw DIR writes the raw collector document of every device. The issue names --debug for this, but the log level of the CLI is fixed at INFO, so the dump is an option of its own. The files have the format of the parser fixtures.

Verification

The unit tests of this revision run in CI; they were not run locally. Every commit of the stack was checked with black --check and flake8, and all test modules import at every commit. mypy --ignore-missing-imports reports nothing in the new modules.

The parsers were run against the complete captures before the fixtures were derived from them, and the expectations of the new tests were taken from those runs.

Checked against captures

The captures of #2884 cover passive copper cables in SFP28 and QSFP28 cages, QSFP28 SR4 optics with diagnostics and empty cages on Enterprise SONiC 4.4.1 and 4.5.2, and Mellanox, Broadcom and Intel NICs on the nodes.

  • TRANSCEIVER_INFO on Enterprise SONiC carries the community key names (manufacturer, model, serial, vendor_date, vendor_oui) next to names of its own (vendor_name, vendor_part_number, vendor_serial_number). The candidate keys cover both. TRANSCEIVER_FIRMWARE_INFO is empty on these switches, which have no CMIS modules.
  • The values differ from what ethtool -m prints for the other end of the same cable, and are now written alike: specification_compliance is the text of a Python dict and is reduced to its codes, the vendor OUI is written with colons, cable length and wavelength get their unit, and the date code is a date on both sides. With that, both ends of a captured breakout cable report the same vendor, part number, date and length, and the serial number of the SFP28 end is the one of the QSFP28 end plus its number.
  • A passive copper cable has an entry in TRANSCEIVER_DOM_SENSOR with N/A for every value. It is reported without diagnostics, as on Linux.
  • TRANSCEIVER_INFO also holds the marker XcvrInitDone, which is not a port.
  • show platform firmware status has the columns the parser expects. ONIE is not one of its components on this platform and comes from the EEPROM.
  • show version prints SONiC-OS-4.5.2-Enterprise_Base on Enterprise SONiC; the prefix is removed like SONiC. on community SONiC.
  • bnxt_en reports the serial number of the board through devlink next to the one derived from the MAC address. The board serial is used.
  • ethtool -m fails with Operation not supported for RJ45 ports and for the USB host interface of a BMC. They are rows with present = false.

The fixtures of three nodes and of one switch are captures, anonymized and reduced. This covers the acceptance criterion that asks for fixtures from real hardware as far as the deployment has such hardware.

Not verified

No capture exists for the following. They are tested against synthetic fixtures only:

  • optical modules, CMIS modules and empty cages in a node, and so ethtool -m for SFF-8636 and CMIS,
  • SR-IOV virtual functions and InfiniBand ports,
  • community SONiC,
  • a node without lspci and devlink.

The command was not run against NetBox.

Closes #2876

Assisted-by: Claude:claude-fable-5-2

The collectors so far gather port identity and link state. The
transceiver report also needs to know what is plugged into a port and
what hardware carries it.

The Linux collector gains the sections ethtool (link settings, driver
and firmware, FEC), module (the EEPROM read with ethtool -m), nic
(lspci and devlink, once per PCI function) and system (DMI). A port
without a cage and an empty cage make ethtool -m fail; the result is
kept with its exit code, because that is an answer and not an error.
InfiniBand ports report state and rate from the IB device they belong
to.

The SONiC collector gains the sections transceiver, dom and system,
which dump TRANSCEIVER_INFO, TRANSCEIVER_FIRMWARE_INFO,
TRANSCEIVER_DOM_SENSOR and EEPROM_INFO from STATE_DB and read the
version file. show commands are only run for what the tables and the
file did not deliver, and for the firmware versions.

Tests: every section against the fake sysfs tree and command runner,
including the fallbacks on the switch.

Part of #2876.

Assisted-by: Claude:claude-fable-5-2
Signed-off-by: Christian Berendt <berendt@osism.tech>
Turn what the collectors gathered into the records of the transceiver
report: one record per port with its link settings, the NIC behind it
and the module in its cage, plus the identity of the device.

On Linux the module comes from the text ethtool -m prints, since JSON
output only exists in recent ethtool releases. Diagnostic readings
are taken from the value lines and not from the alarm thresholds that
carry the same names. A firmware version only exists for CMIS
modules and is left empty otherwise. A virtual function has no module
of its own. The serial number of a NIC is the one of its board where
devlink reports it, as bnxt_en does, and the one of the PCI device
otherwise.

On SONiC the field names in TRANSCEIVER_INFO differ between community
releases and Enterprise SONiC. Each output field therefore has a list
of candidate keys. CMIS firmware is read from TRANSCEIVER_INFO or
TRANSCEIVER_FIRMWARE_INFO, the chassis identity from EEPROM_INFO or
show platform syseeprom, the software version from the version file
or show version.

Both ends of a cable read alike. SONiC decodes what ethtool prints
raw, so its values are written the way the Linux parser writes them:
the compliance codes without the dict they are stored in, the vendor
OUI with colons, the cable length and the wavelength with their unit,
and the date code as a date on both sides. A passive copper cable has
a diagnostics entry with N/A for every value on SONiC and is reported
without diagnostics, as on Linux.

The fixtures of three nodes (ConnectX-4 Lx, BCM57414 with X710,
82599ES) and of a switch running Enterprise SONiC 4.5.2 are captures,
anonymized and reduced. What they do not cover stays synthetic:
optical and CMIS modules in a node, a node without lspci and
devlink, virtual functions, InfiniBand, community SONiC, and the
switch of the report command tests.

Tests: every parser against the fixtures and against missing tools,
missing modules and malformed output.

Part of #2876.

Assisted-by: Claude:claude-fable-5-2
Signed-off-by: Christian Berendt <berendt@osism.tech>
There was no way to answer which optics are plugged in where across a
deployment, short of running ethtool -m on every node and show
interfaces transceiver on every switch.

osism report transceiver collects, live over SSH, the transceiver of
every physical port on the managed nodes and SONiC switches, together
with the port state and the hardware carrying the port, and prints
one report as table, CSV or JSON. Devices are selected through NetBox
filters and name patterns. Each row shows the NetBox interface the
port was matched to and how, with its cable peer; NetBox interfaces
without a live port are listed as well.

A port without a module is a row with present = false. A device that
cannot be queried is listed as failed and leaves the exit code at 0
unless --strict is given. Without NetBox the command reports the
nodes of the inventory. --dump-raw writes the raw collector
documents, which is how parser fixtures are captured.

Tests: the command with selection, collection and NetBox replaced,
covering the row content for nodes and switches, mapping, the three
formats and column selection, row filters, failed devices and
--strict, and the run without NetBox.

Closes #2876

Assisted-by: Claude:claude-fable-5-2
Signed-off-by: Christian Berendt <berendt@osism.tech>
@berendt
berendt force-pushed the implement/issue-2876-report-transceiver branch from ab1b53e to f0fcb7c Compare November 13, 2026 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

Add report transceiver command: live NIC and transceiver hardware inventory for Linux nodes and SONiC switches

1 participant