Firmware endpoint hardware identity¶
https://bugs.launchpad.net/ironic/+bug/2149880
Ironic stores per-component firmware versions from Redfish. The
GET /v1/nodes/{ident}/firmware endpoint exposes only version-tracking
fields with no hardware identity — vendor, model, or serial number. The
GET /v1/nodes/{ident}/inventory endpoint exposes NIC inventory including
vendor and product identifiers but no firmware versions. This spec extends
the firmware endpoint with vendor, model, and serial number to allow
correlation between firmware and inventory records.
Problem description¶
An operator cannot answer what firmware version has the Intel E810 NIC of a
server. This happens because: an operator can query the inventory endpoint to
get the NIC vendor as a PCI identifier:
GET /v1/nodes/{ident}/inventory
{
"inventory": {
"interfaces": [
{
"name": "eth0",
"mac_address": "52:54:00:5e:09:ff",
"ipv4_address": "192.168.1.10",
"has_carrier": true,
"vendor": "0x8086",
"product": "0x1572",
"biosdevname": null,
"speed_mbps": 25000
}
]
}
}
Then query the firmware endpoint to get the version
GET /v1/nodes/{ident}/firmware
{
"firmware": [
{
"component": "NIC:ABC12345",
"initial_version": "22.0.9",
"current_version": "22.5.0",
"last_version_flashed": "22.5.0",
"created_at": "2024-01-01T00:00:00+00:00",
"updated_at": "2024-06-01T00:00:00+00:00"
}
]
}
But there is no common field to associate an entry in the inventory to an entry in the firmware components.
As a solution we leverage the fact that the Redfish NetworkAdapter
resource (DMTF schema NetworkAdapter.v1_3_0) that Ironic already
queries for firmware version carries hardware identity fields:
Manufacturer– e.g."Intel Corporation"(exposed asvendorin the Ironic API)Model– e.g."Intel(R) 25GbE 2P XXV710 Adptr"SerialNumber– e.g."ABC12345"(already used to build the component identifier, but not returned as a structured field)
These fields are already fetched at the time cache_firmware_components
runs — no new Redfish calls are required. They are simply never stored
or returned.
The operator can heuristically correlate the human-readable identity from
the firmware endpoint to the PCI identifiers in the inventory. Redfish
returns Manufacturer and Model as vendor-chosen strings; the
inventory exposes vendor and product as raw PCI IDs. The mapping
is approximate: vendor: "Intel Corporation" corresponds to
vendor: "0x8086" via PCI ID resolution, and model: "Intel(R)
E810-CQDA2" approximates the device string for product: "0x1592".
This is the best correlation possible given the data each subsystem
exposes.
Proposed change¶
Three nullable string fields — vendor, model,
serial_number — are added to the firmware component response.
NIC: one
NetworkAdapterresource per physical card, iterated fromSystems/{id}/NetworkAdapters/. The component identifier"NIC:{serial}"is built fromNetworkAdapter.SerialNumber; the identity fields are sourced from the same resource with no additional Redfish traversal.API field
Redfish property
vendorNetworkAdapter.ManufacturermodelNetworkAdapter.Modelserial_numberNetworkAdapter.SerialNumberAll fields are optional in the Redfish schema. Example values:
vendor="Intel Corporation",model="Intel(R) 25GbE 2P XXV710 Adptr",serial_number="ABC12345".BMC: one
Managerresource per node.API field
Redfish property
vendor(not available)
modelManager.Modelserial_number(not available)
Manager.Model(e.g."iDRAC 9","iLO 5") populatesmodel.Managerhas noManufacturerorSerialNumberproperty, sovendorandserial_numberarenull.BIOS: all fields
null.API field
Redfish property
vendor(not available)
model(not available)
serial_number(not available)
ComputerSystemcarriesManufacturer,Model, andSerialNumberbut these describe the server chassis, not the BIOS component; Redfish does not expose BIOS-chip-specific identity.
Note
Items 2 and 3 are documented here because BMC and BIOS share the
same firmware_information DB schema as NICs. The fields exist
on every row; null is the honest value when Redfish provides no
component-specific identity.
Alternatives¶
Live Redfish fetch at request time rather than caching in the database adds per-request BMC calls to a read path that currently requires no out-of-band contact, increasing latency and BMC load.
A separate sub-endpoint (e.g.
GET /v1/nodes/{ident}/firmware/{component}/identity) adds complexity
without benefit since the data is colocated with the firmware record and
is small.
Data model impact¶
Three nullable VARCHAR(255) columns are added to the
firmware_information table: vendor, model,
serial_number. A single Alembic migration adds all three.
Existing rows are unaffected (columns default to NULL). No
back-fill is performed; new values are populated on the next inspection
or cleaning pass. The table is bounded by the number of firmware
components per node (typically fewer than 20), so the additional columns
have negligible storage and query impact.
State Machine Impact¶
None.
REST API impact¶
One existing endpoint is modified.
GET /v1/nodes/{node_ident}/firmware¶
Method: GET
Normal response: 200
Error responses:
404 if the node does not exist.
403 if the caller lacks
baremetal:node:firmware:getpolicy.406 if any of
vendor,model,serial_numberappears in the?fields=query parameter and is not supported by the server version.
Response body (with new fields):
{
"firmware": [
{
"component": "BMC",
"initial_version": "2.10.0",
"current_version": "2.10.0",
"last_version_flashed": null,
"model": "iDRAC 9",
"vendor": null,
"serial_number": null,
"created_at": "2024-01-01T00:00:00+00:00",
"updated_at": null
},
{
"component": "BIOS",
"initial_version": "3.5.0",
"current_version": "3.5.0",
"last_version_flashed": null,
"model": null,
"vendor": null,
"serial_number": null,
"created_at": "2024-01-01T00:00:00+00:00",
"updated_at": null
},
{
"component": "NIC:ABC12345",
"initial_version": "22.0.9",
"current_version": "22.5.0",
"last_version_flashed": "22.5.0",
"model": "Intel(R) 25GbE 2P XXV710 Adptr",
"vendor": "Intel Corporation",
"serial_number": "ABC12345",
"created_at": "2024-01-01T00:00:00+00:00",
"updated_at": "2024-06-01T00:00:00+00:00"
}
]
}
Response body (prior to this change): unchanged — the three new fields are absent. No policy changes. No new endpoints.
Client (CLI) impact¶
python-ironicclient will be updated. The baremetal node firmware
list command will display the new Vendor, Model, and
Serial Number fields in its tabular output. The fields are only
queried and displayed when the command targets a server that supports
the new API microversion.
RPC API impact¶
None.
Driver API impact¶
None.
Nova driver impact¶
None.
Ramdisk impact¶
None.
Security impact¶
None.
Other end user impact¶
Baremetal operators consuming Ironic through higher-level clients such as gophercloud should adapt their clients to make use of the new fields.
Scalability impact¶
None beyond what is noted in the Data model impact section.
Performance Impact¶
None.
Other deployer impact¶
None.
Developer impact¶
None beyond the standard versioned-object conventions.
Implementation¶
Assignee(s)¶
- Primary assignee:
karampok
- Other contributors:
None
Work Items¶
Database: Alembic migration adding nullable
VARCHAR(255)columnsvendor,model,serial_numberto thefirmware_informationtable.Object: Add the three fields to the
FirmwareComponentversioned object; implementobj_make_compatibleto strip them when communicating with conductors pinned below the new version.Driver: Update
cache_firmware_componentsin the Redfish hardware type to populate the new fields fromNetworkAdapter(NICs) andManager(BMC).API: Define a new microversion; update the
GET /v1/nodes/{node_ident}/firmwarecontroller to return the new fields for requests at or above that version.
Dependencies¶
None.
Testing¶
Unit tests will be added conforming to Ironic testing requirements.
CI coverage may be extended by adding the new identity fields to the sushy-tools virtual Redfish resources used in the gate.
Upgrades and Backwards Compatibility¶
REST API: clients that do not declare the new API version receive
the unchanged response. Requesting any new field explicitly on an
older server returns 406 Not Acceptable.
Database: new columns are nullable (default NULL). The
migration completes without touching existing rows. New values are
populated only when cache_firmware_components next runs (inspection
or cleaning). No back-fill is performed.
Rolling upgrades: FirmwareComponent.obj_make_compatible strips
vendor, model, and serial_number from primitives sent to
conductors pinned below the new object version. No data is lost.
No operator action is required.
Documentation Impact¶
doc/source/contributor/webapi-version-history.rst,
api-ref/source/baremetal-api-v1-nodes-firmware.inc, and the API ref
sample JSON require updates for the new microversion and fields.
References¶
Original firmware interface specification: https://specs.openstack.org/openstack/ironic-specs/specs/approved/firmware-interface.html
Redfish NetworkAdapter schema (DMTF): https://redfish.dmtf.org/schemas/v1/NetworkAdapter.v1_3_0.json
Redfish Manager schema (DMTF): https://redfish.dmtf.org/schemas/v1/Manager.v1_0_0.json
Redfish ComputerSystem schema (DMTF): https://redfish.dmtf.org/schemas/v1/ComputerSystem.v1_0_0.json
Related spec — NIC firmware updates: https://review.opendev.org/c/openstack/ironic-specs/+/948503