docs: design notes for a Redfish/IPMI BMC driver
No code yet. The README explains why one Redfish driver with vendor quirk modules beats a Supermicro-only IPMI driver, and keeps IPMI over LAN as a read-only fallback. docs/ holds a draft for a new ManagementController role base in napalm-device-types, the getter-to-resource map, the first test device (Supermicro X10DRL-i, Redfish firmware 3.91), the security points (IPMI RAKP hash disclosure, power control, credentials) and the test plan with DMTF mockups and fixtures to record.
This commit is contained in:
commit
5f8a4ef975
9 files changed
+557
No files matched your search
@@ -0,0 +1,7 @@
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*.egg-info/
|
||||
build/
|
||||
dist/
|
||||
.venv/
|
||||
.pytest_cache/
|
||||
@@ -0,0 +1,191 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship made available under
|
||||
the License, as indicated by a copyright notice that is included in
|
||||
or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other transformations
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean, as submitted to the Licensor for inclusion
|
||||
in the Work by the copyright owner or by an individual or Legal Entity
|
||||
authorized to submit on behalf of the copyright owner. For the purposes
|
||||
of this definition, "submitted" means any form of electronic, verbal,
|
||||
or written communication sent to the Licensor or its representatives,
|
||||
including but not limited to communication on electronic mailing lists,
|
||||
source code control systems, and issue tracking systems that are managed
|
||||
by, or on behalf of, the Licensor for the purpose of discussing and
|
||||
improving the Work, but excluding communication that is conspicuously
|
||||
marked or designated in writing by the copyright owner as "Not a
|
||||
Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any Legal Entity on behalf of
|
||||
whom a Contribution has been received by the Licensor and incorporated
|
||||
within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by the combined Contribution(s) and the Work
|
||||
to which such Contribution(s) was submitted. If You institute patent
|
||||
litigation against any entity (including a cross-claim or counterclaim
|
||||
in a lawsuit) alleging that the Work or any Contribution embodied
|
||||
within the Work constitutes direct or contributory patent infringement,
|
||||
then any patent licenses granted to You under this License for that
|
||||
Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or Derivative
|
||||
Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, You must include a readable copy of the
|
||||
attribution notices contained within such NOTICE file, in
|
||||
at least one of the following places: within a NOTICE text file
|
||||
distributed as part of the Derivative Works; within the Source
|
||||
form or documentation, if provided along with the Derivative
|
||||
Works; or, within a display generated by the Derivative Works,
|
||||
if and wherever such third-party notices normally appear. The
|
||||
contents of the NOTICE file are for informational purposes only
|
||||
and do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own license statement for Your modifications and
|
||||
may provide additional grant of rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Work,
|
||||
and to permit persons to whom the Work is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any conditions of TITLE,
|
||||
MERCHANTIBILITY, or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or exemplary damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (even if such Contributor has been advised of the possibility
|
||||
of such damages).
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may offer only
|
||||
conditions consistent with this License, subject to the following
|
||||
additional conditions:
|
||||
|
||||
(a) You may offer additional warranty, indemnity, or other liability
|
||||
terms and conditions; and
|
||||
|
||||
(b) You may offer support for the Work in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format in question. It may also be
|
||||
possible to make it available with a creative commons license.
|
||||
|
||||
Copyright 2026 Christian Manivong
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,65 @@
|
||||
# napalm-redfish
|
||||
|
||||
NAPALM driver for server **baseboard management controllers (BMCs)** over
|
||||
[DMTF Redfish](https://www.dmtf.org/standards/redfish), with a read-only IPMI fallback for
|
||||
boards that predate Redfish. Built on
|
||||
[napalm-device-types](https://git.netork.io/NAPALM/napalm-device-types). Written for netOrk.
|
||||
|
||||
**Status: planning.** There is no code yet. This repository holds the design so far. The
|
||||
first test device is a Supermicro X10DRL-i (BMC firmware 3.91, Redfish).
|
||||
|
||||
## Why Redfish, and why not one driver per vendor
|
||||
|
||||
Redfish is the DMTF's REST API for management controllers. Supermicro (X10 with Redfish
|
||||
firmware, X11 and later), Dell iDRAC, HPE iLO and Lenovo XCC all implement it. One driver
|
||||
with small vendor quirk modules covers all of them; a `napalm-supermicro-ipmi` would cover
|
||||
one.
|
||||
|
||||
IPMI over LAN stays a **read-only fallback** for boards without Redfish. Its IPMI 2.0
|
||||
RAKP handshake hands the password hash to anyone who asks (CVE-2013-4786), so netOrk should
|
||||
not depend on it. Finding IPMI over LAN enabled is itself worth reporting, see
|
||||
[docs/security.md](docs/security.md).
|
||||
|
||||
## Layout (planned)
|
||||
|
||||
| Entry point | Transport | Scope |
|
||||
|---|---|---|
|
||||
| `redfish` | HTTPS, Redfish REST (session token or basic auth) | Read, plus power control and BMC reset |
|
||||
| `ipmi` | IPMI 2.0 over LAN (UDP 623) via `pyghmi` | Read-only: facts, sensors, power state, SEL |
|
||||
|
||||
Vendor quirks (Supermicro, Dell, HPE, Lenovo) live in one module per vendor, selected from
|
||||
the service root's `Vendor`/`Oem` data and `Manager.Model`. No separate entry point per
|
||||
vendor.
|
||||
|
||||
## Documents
|
||||
|
||||
- [docs/role.md](docs/role.md): the role base this needs in napalm-device-types (draft)
|
||||
- [docs/redfish-map.md](docs/redfish-map.md): getters mapped to Redfish resources
|
||||
- [docs/supermicro-x10.md](docs/supermicro-x10.md): first test device, its Redfish level, IPMI
|
||||
- [docs/security.md](docs/security.md): credentials, IPMI over LAN, power control
|
||||
- [docs/testing.md](docs/testing.md): DMTF mockups, emulators, fixtures to record
|
||||
- [docs/references.md](docs/references.md)
|
||||
|
||||
## Building without hardware
|
||||
|
||||
Unlike most drivers in this organisation, much of this one can be built and tested
|
||||
without a device: the DMTF publishes complete mockups of Redfish services (DSP2043), and
|
||||
both the DMTF Redfish-Mockup-Server and OpenStack's sushy-tools serve them over HTTP.
|
||||
Recorded output from the X10DRL-i then covers what the mockups do not: an old Redfish 1.0.x
|
||||
implementation and Supermicro's quirks.
|
||||
|
||||
## Conventions
|
||||
|
||||
These follow the other drivers in the `NAPALM` organisation:
|
||||
|
||||
- Role bases declare, they never implement. Generic logic goes into napalm-device-types,
|
||||
vendor mechanics stay here.
|
||||
- Parsing lives in pure functions, tested on recorded responses under
|
||||
`tests/fixtures/<vendor>-<model>-<firmware>/`, with a `COMMANDS.txt` (here: the request
|
||||
paths) listing what produced each file.
|
||||
- `napalm-device-types` is not on PyPI: install it from
|
||||
`git+https://git.netork.io/NAPALM/napalm-device-types.git` before this package.
|
||||
|
||||
## License
|
||||
|
||||
Apache License 2.0, see [LICENSE](LICENSE).
|
||||
@@ -0,0 +1,44 @@
|
||||
# Getters mapped to Redfish resources
|
||||
|
||||
Paths use the usual single-member IDs (`Systems/1`, `Managers/1`, `Chassis/1`); the driver
|
||||
must follow the collections instead of assuming IDs, because vendors differ (Dell uses
|
||||
`System.Embedded.1`, HPE uses `1`, Supermicro uses `1`).
|
||||
|
||||
## Authentication
|
||||
|
||||
- **Session:** `POST /redfish/v1/SessionService/Sessions` with user and password returns
|
||||
an `X-Auth-Token` header and the session's URI. Use the token, `DELETE` the session on
|
||||
close. BMCs allow few concurrent sessions, so leaking them locks out the web UI.
|
||||
- **Basic auth** works on most services and is the fallback.
|
||||
- Self-signed certificates are the norm; verification is configurable per device.
|
||||
|
||||
## NAPALM getters
|
||||
|
||||
| Getter | Resource | Fields |
|
||||
|---|---|---|
|
||||
| `get_facts` | `Systems/{id}`, `Managers/{id}` | `Manufacturer`, `Model`, `SerialNumber`, `HostName`; BMC `FirmwareVersion` as `os_version`. `uptime` is not in Redfish (return -1). `interface_list` from `Managers/{id}/EthernetInterfaces` |
|
||||
| `get_interfaces` | `Managers/{id}/EthernetInterfaces/*` | BMC ports: `MACAddress`, `SpeedMbps`, `LinkStatus`, `InterfaceEnabled` |
|
||||
| `get_interfaces_ip` | same | `IPv4Addresses`, `IPv6Addresses` |
|
||||
| `get_environment` | `Chassis/{id}/Thermal` (`Temperatures[]`, `Fans[]`), `Chassis/{id}/Power` (`PowerSupplies[]`, `PowerControl[].PowerConsumedWatts`) | Newer services move these to `ThermalSubsystem`, `PowerSubsystem` and `Sensors`; read whichever exists. CPU and memory of the host OS are unknown to a BMC |
|
||||
| `get_users` | `AccountService/Accounts/*` | `UserName`, `RoleId`, `Enabled` |
|
||||
| `get_ntp_servers` | `Managers/{id}/NetworkProtocol` | `NTP.NTPServers` (newer schema versions only) |
|
||||
| `get_snmp_information` | `Managers/{id}/NetworkProtocol` | `SNMP.ProtocolEnabled` (details vary) |
|
||||
| `get_config` | n/a | A BMC has no configuration file. Not implemented |
|
||||
|
||||
## Role methods (draft, see role.md)
|
||||
|
||||
| Method | Resource |
|
||||
|---|---|
|
||||
| `get_power_state` | `Systems/{id}`: `PowerState` |
|
||||
| `set_power_state` | `POST Systems/{id}/Actions/ComputerSystem.Reset` with `ResetType`; allowed values from `ResetType@Redfish.AllowableValues` (or the `ActionInfo` resource) |
|
||||
| `reboot_host` (the BMC) | `POST Managers/{id}/Actions/Manager.Reset` |
|
||||
| `get_hardware_inventory` | `Systems/{id}` (`ProcessorSummary`, `MemorySummary`), `Systems/{id}/Processors/*`, `Systems/{id}/Memory/*`, `Systems/{id}/Storage/*` (older: `SimpleStorage`), `Chassis/{id}/Power` PSUs, `Systems/{id}/EthernetInterfaces/*` |
|
||||
| `get_event_log` | `Systems/{id}/LogServices/*/Entries` or `Managers/{id}/LogServices/*/Entries` (where the SEL lives varies by vendor) |
|
||||
| `get_firmware_inventory` | `UpdateService/FirmwareInventory/*`: `Name`, `Version`, `Updateable` |
|
||||
| `get_management_protocols` | `Managers/{id}/NetworkProtocol`: `HTTP`, `HTTPS`, `SSH`, `IPMI`, `SNMP`, `KVMIP`, `VirtualMedia`, `SSDP`, each with `ProtocolEnabled` and `Port` |
|
||||
|
||||
## IPMI fallback (`ipmi` entry point)
|
||||
|
||||
Read-only, via `pyghmi`: device ID and FRU data for `get_facts`, sensor data repository for
|
||||
`get_environment`, chassis status for `get_power_state`, SEL for `get_event_log`. No power
|
||||
control over IPMI.
|
||||
@@ -0,0 +1,46 @@
|
||||
# References
|
||||
|
||||
Collected 2026-10-13.
|
||||
|
||||
## Standards and DMTF tools
|
||||
|
||||
| What | URL |
|
||||
|---|---|
|
||||
| DMTF Redfish standards page (specification, schemas, DSP2043 mockups) | https://www.dmtf.org/standards/redfish |
|
||||
| Redfish publications (schemas, mockups) on GitHub | https://github.com/DMTF/Redfish-Publications |
|
||||
| Redfish-Mockup-Server | https://github.com/DMTF/Redfish-Mockup-Server |
|
||||
| Redfish-Mockup-Server Docker image | https://hub.docker.com/r/dmtf/redfish-mockup-server |
|
||||
| Redfish-Service-Validator | https://github.com/DMTF/Redfish-Service-Validator |
|
||||
| Redfish-Interop-Validator | https://github.com/DMTF/Redfish-Interop-Validator |
|
||||
|
||||
## Libraries
|
||||
|
||||
| Library | Use | License | Status (2026-10) |
|
||||
|---|---|---|---|
|
||||
| `redfish` (DMTF python-redfish-library) | thin Redfish client: sessions, GET/POST | BSD-3-Clause | release 3.4.1, 2026-10-09 |
|
||||
| `sushy` (OpenStack) | object-model Redfish client | Apache-2.0 | active |
|
||||
| `sushy-tools` (OpenStack) | Redfish emulator for tests | Apache-2.0 | active |
|
||||
| `pyghmi` | IPMI over LAN, pure Python | Apache-2.0 | release 1.6.19, 2026-07-13 on PyPI (the GitHub mirror is archived) |
|
||||
|
||||
Choosing between the thin `redfish` client and `sushy` is open. The thin client keeps
|
||||
quirk handling in this driver; `sushy` brings an object model but also its own assumptions
|
||||
about Ironic's needs.
|
||||
|
||||
## Supermicro
|
||||
|
||||
| What | URL |
|
||||
|---|---|
|
||||
| BMC firmware for X10DRL-i (REDFISH_X10 3.91) | https://supermicro.com/en/support/resources/downloadcenter/firmware/MBD-X10DRL-i/BMC |
|
||||
| Redfish Reference Guide (HTML, X12/H12 and later) | https://www.supermicro.com/manuals/other/redfish-ref-guide-html/ |
|
||||
| Redfish Reference Guide 1.0a for X10 (third-party mirror) | https://update.shared.it/SUPERMICRO/X10DRL-I/IPMI/REDFISH_X10_327/Redfish_Ref_Guide_1%200a.pdf |
|
||||
|
||||
## Security
|
||||
|
||||
- CVE-2013-4786: IPMI 2.0 RAKP password hash disclosure.
|
||||
|
||||
## netOrk
|
||||
|
||||
- Discovery already fingerprints `idrac` and `ilo` by HTTP (`netork/jobs/tasks/discovery.py`),
|
||||
without a driver. Supermicro BMCs are not fingerprinted yet.
|
||||
- Default-credential audit: NetOrk/netork#141.
|
||||
- Reachability recovery (a hung host could be power-cycled through its BMC): NetOrk/netork#938.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Role base draft: `ManagementControllerDriver`
|
||||
|
||||
Draft for napalm-device-types. Nothing here is decided; the decisions are tracked in the
|
||||
netOrk options issue.
|
||||
|
||||
## Why a new role
|
||||
|
||||
The existing role bases (`SwitchDriver`, `FirewallDriver`, `AccessPointDriver`,
|
||||
`HypervisorDriver`, `StorageDriver`, `OSDriver`, `PhoneDriver`, `MediaDriver`,
|
||||
`ResidentialGatewayDriver`) each describe what a device *is*. A BMC is a separate computer
|
||||
with its own network port, IP and MAC that manages *another* machine: it reads that
|
||||
machine's sensors and switches its power, whatever OS the machine runs. None of the
|
||||
existing contracts fits, and borrowing one (e.g. `OSDriver`) would make netOrk offer
|
||||
package updates and service control for a BMC.
|
||||
|
||||
## Sketch
|
||||
|
||||
```python
|
||||
class ManagementControllerDriver(DeviceTypeDriver):
|
||||
"""Contract, not code."""
|
||||
ROLE: str = "management_controller" # key exposed as device_class
|
||||
TYPE_LABEL: str = "Management Controller"
|
||||
USES_SSH: bool = False # Redfish is HTTPS; IPMI is UDP
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# The managed machine
|
||||
def get_power_state(self) -> PowerStateDict: ...
|
||||
def set_power_state(self, action: PowerAction) -> None: ... # On, GracefulShutdown,
|
||||
# ForceOff, GracefulRestart,
|
||||
# ForceRestart, PowerCycle
|
||||
def get_hardware_inventory(self) -> HardwareInventoryDict: ... # CPUs, DIMMs, drives,
|
||||
# PSUs, NICs, serials
|
||||
def get_event_log(self, limit: int = 500) -> List[EventLogEntryDict]: ... # SEL
|
||||
# The controller itself
|
||||
def get_firmware_inventory(self) -> List[FirmwareDict]: ... # BMC, BIOS, others
|
||||
def get_management_protocols(self) -> ManagementProtocolsDict: ... # IPMI, SSH,
|
||||
# HTTP(S), SNMP,
|
||||
# KVM, virtual media
|
||||
```
|
||||
|
||||
Points to settle in napalm-device-types:
|
||||
|
||||
- **`reboot_host` means the BMC.** `HostRebootMixin` says a driver restarts its *own*
|
||||
host, never one it manages ("a hypervisor restarts the hypervisor, not a VM"). For a BMC
|
||||
that is `Manager.Reset`; the managed server goes through `set_power_state`. A driver for
|
||||
a BMC must not map `reboot_host` to the server.
|
||||
- **Sensors.** NAPALM's `get_environment` already has fans, temperatures and power supplies.
|
||||
It also requires CPU and memory, which a BMC does not know for the host OS. Either return
|
||||
`get_environment` with those empty, or add a `get_sensors` that also carries voltages and
|
||||
power draw. Prefer reusing `get_environment` if the empty fields are acceptable.
|
||||
- **Health metrics.** `HealthMetricsMixin` is SNMP/UCD-MIB. A BMC's health comes from Redfish,
|
||||
so this role does **not** mix it in. If netOrk needs `get_health_metrics` for BMCs, the
|
||||
driver implements it from Redfish, as `SwitchDriver` drivers do from their own sources.
|
||||
- **`CommandChannelMixin`** comes with `DeviceTypeDriver` but stays unimplemented: no shell.
|
||||
- **Write capability by `hasattr`.** `set_power_state` exists only on drivers that can do it,
|
||||
so the IPMI fallback (read-only) simply does not define it.
|
||||
- **Models.** `PowerStateDict`, `HardwareInventoryDict`, `EventLogEntryDict`,
|
||||
`FirmwareDict`, `ManagementProtocolsDict` go into `models.py`.
|
||||
- **Fingerprinting.** An unauthenticated `GET /redfish/v1/` returns the service root
|
||||
(`RedfishVersion`, `UUID`, `Vendor` on newer services) on every Redfish BMC. That is a
|
||||
vendor-neutral `PORT_SPECS`/`HTTP_FINGERPRINT` rule and can replace the hand-written
|
||||
`idrac`/`ilo` platform strings in netOrk's discovery.
|
||||
|
||||
## Relation to the managed server
|
||||
|
||||
A BMC is its own device in netOrk (own IP, own credentials, own firmware and CVEs), linked
|
||||
to the host it manages. How to link them (matching the server's serial or system UUID from
|
||||
`Systems/{id}` against the host's DMI data, or by hand) is a netOrk decision, not part of
|
||||
this contract. The driver exposes the identifiers needed for matching:
|
||||
`SerialNumber`, `UUID` and the host's MAC addresses from `Systems/{id}/EthernetInterfaces`.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Security
|
||||
|
||||
A BMC can power a server off, mount virtual media and open a remote console. Its
|
||||
credentials are worth as much as root on every machine it manages.
|
||||
|
||||
## Credentials
|
||||
|
||||
- Use a dedicated BMC account for netOrk, not the factory administrator. A read-only role
|
||||
(Redfish `ReadOnly`) suffices for everything except power control, which needs
|
||||
`Operator`.
|
||||
- netOrk's credential gating applies unchanged: no job without credentials.
|
||||
- Close Redfish sessions after each poll. BMCs allow few concurrent sessions, and a leaked
|
||||
session can lock the web UI out.
|
||||
|
||||
## IPMI over LAN
|
||||
|
||||
- IPMI 2.0's RAKP handshake returns a salted hash of the user's password to any client that
|
||||
names a valid user, before authentication (CVE-2013-4786). The hash can be cracked
|
||||
offline. This is part of the protocol, not a bug a firmware update fixes.
|
||||
- Cipher suite 0 (no authentication) is enabled on some BMCs and allows login with any
|
||||
password.
|
||||
- So the `ipmi` entry point is read-only and a fallback only. `get_management_protocols`
|
||||
reporting `IPMI.ProtocolEnabled = true` should become a finding in netOrk, with the advice
|
||||
to disable IPMI over LAN where Redfish is available.
|
||||
|
||||
## Power control
|
||||
|
||||
- `set_power_state` can take a production server down. In netOrk it needs a
|
||||
`ConfirmDialog`, a permission of its own, and an audit log entry.
|
||||
- `ForceOff`/`ForceRestart`/`PowerCycle` skip the OS shutdown; offer `GracefulShutdown`/
|
||||
`GracefulRestart` first.
|
||||
- `reboot_host` restarts only the BMC (`Manager.Reset`). The managed server keeps running.
|
||||
|
||||
## Firmware
|
||||
|
||||
BMC firmware versions from `UpdateService/FirmwareInventory` feed netOrk's vulnerability
|
||||
management. Supermicro BMCs in particular have had serious published vulnerabilities, and
|
||||
the X10 Redfish firmware line is no longer updated.
|
||||
|
||||
## Network placement
|
||||
|
||||
A BMC belongs in a management network that only administrators and netOrk can reach. A BMC
|
||||
reachable from a user or guest VLAN is itself a finding for the segmentation checks.
|
||||
@@ -0,0 +1,44 @@
|
||||
# Supermicro X10 (first test device: X10DRL-i)
|
||||
|
||||
## Firmware
|
||||
|
||||
Supermicro shipped Redfish to X10 boards as a separate BMC firmware line, named
|
||||
`REDFISH_X10_<version>`. For the X10DRL-i the latest is **3.91**
|
||||
(`REDFISH_X10_391_20200806_unsigned.zip`) in Supermicro's download center. Other X10
|
||||
boards have 3.86–3.90 from 2019–2020. Users report Redfish version 1.0.x on these
|
||||
firmwares, so expect:
|
||||
|
||||
- the legacy `Chassis/{id}/Thermal` and `Power` resources, not `ThermalSubsystem`/`Sensors`,
|
||||
- an older `ManagerNetworkProtocol` schema (NTP and SNMP details may be missing),
|
||||
- fewer collections overall (storage details may be absent).
|
||||
|
||||
The X10 BMC firmware is unlikely to get further updates. For the driver that is useful
|
||||
twice: it is the oldest Redfish the driver has to survive, and a real case for flagging
|
||||
outdated BMC firmware in netOrk's vulnerability management.
|
||||
|
||||
Supermicro's **Redfish Reference Guide 1.0a** was published with the X10 Redfish firmware.
|
||||
Supermicro's own HTML guide covers X12/H12 and later.
|
||||
|
||||
## Check before starting
|
||||
|
||||
```bash
|
||||
# Service root, no login: Redfish version and available collections
|
||||
curl -sk https://<bmc>/redfish/v1/ | python3 -m json.tool
|
||||
# The managed server: model, serial, BIOS, power state
|
||||
curl -sk -u <user>:<password> https://<bmc>/redfish/v1/Systems/1 | python3 -m json.tool
|
||||
```
|
||||
|
||||
## Known Supermicro points (from memory, to verify on the device)
|
||||
|
||||
- Older Supermicro BMCs shipped with `ADMIN`/`ADMIN`; newer ones have a unique password on
|
||||
a label. A BMC still on `ADMIN`/`ADMIN` is a test case for netOrk's default-credential
|
||||
audit (NetOrk/netork#141).
|
||||
- Some out-of-band features (BIOS update and BIOS settings through the BMC) need a
|
||||
Supermicro license (SFT-OOB-LIC / SFT-DCMS-SINGLE). Reading and power control should not.
|
||||
Which resources the X10 omits without a license shows up in the recorded responses.
|
||||
- Vendor-specific data sits under `Oem.Supermicro` in several resources.
|
||||
|
||||
## IPMI on the same board
|
||||
|
||||
The X10DRL-i also speaks IPMI 2.0 over LAN (UDP 623), so the `ipmi` fallback can be tested on
|
||||
the same device, and so can the check that reports IPMI over LAN as enabled.
|
||||
@@ -0,0 +1,47 @@
|
||||
# Testing
|
||||
|
||||
## Without hardware
|
||||
|
||||
- **DMTF mockups (DSP2043).** Complete Redfish service trees as static JSON, published by
|
||||
the DMTF with each Redfish release (download from the Redfish standards page). They cover
|
||||
the current schema: `ThermalSubsystem`, `PowerSubsystem`, `Sensors`, storage, logs, and
|
||||
actions.
|
||||
- **DMTF Redfish-Mockup-Server.** Serves a mockup over HTTP (`127.0.0.1:8000` by default),
|
||||
also as a Docker image `dmtf/redfish-mockup-server`. Good for integration tests of the
|
||||
transport (sessions, collections, actions).
|
||||
- **OpenStack sushy-tools.** An emulator that serves mockups or drives libvirt VMs via Redfish,
|
||||
so `set_power_state` can be tested against something that actually changes state.
|
||||
- **DMTF Redfish-Mockup-Creator.** Records a live service into a mockup. It is the tool to
|
||||
turn the X10DRL-i into a complete fixture set in one go.
|
||||
|
||||
Unit tests use recorded JSON responses directly; the mockup server is for a small set of
|
||||
integration tests.
|
||||
|
||||
## Fixtures to record from the X10DRL-i
|
||||
|
||||
Store under `tests/fixtures/supermicro-x10drl-i-3.91/`, one file per request path, plus
|
||||
`COMMANDS.txt` with the paths and the machine's state (powered on/off, fans present).
|
||||
Scrub serial numbers, UUIDs, MACs and IPs before committing.
|
||||
|
||||
- [ ] `GET /redfish/v1/` (without login)
|
||||
- [ ] `GET /redfish/v1/Systems` and each member
|
||||
- [ ] `GET /redfish/v1/Systems/1/Processors` and each member
|
||||
- [ ] `GET /redfish/v1/Systems/1/Memory` and each member
|
||||
- [ ] `GET /redfish/v1/Systems/1/Storage` or `SimpleStorage`, whichever exists
|
||||
- [ ] `GET /redfish/v1/Systems/1/EthernetInterfaces` and each member
|
||||
- [ ] `GET /redfish/v1/Systems/1/LogServices` and the entries of each
|
||||
- [ ] `GET /redfish/v1/Chassis` and each member
|
||||
- [ ] `GET /redfish/v1/Chassis/1/Thermal`
|
||||
- [ ] `GET /redfish/v1/Chassis/1/Power`
|
||||
- [ ] `GET /redfish/v1/Managers/1`
|
||||
- [ ] `GET /redfish/v1/Managers/1/EthernetInterfaces` and each member
|
||||
- [ ] `GET /redfish/v1/Managers/1/NetworkProtocol`
|
||||
- [ ] `GET /redfish/v1/Managers/1/LogServices` and the entries of each
|
||||
- [ ] `GET /redfish/v1/AccountService` and `AccountService/Accounts`
|
||||
- [ ] `GET /redfish/v1/UpdateService/FirmwareInventory` and each member
|
||||
- [ ] `POST /redfish/v1/SessionService/Sessions` response headers (token redacted)
|
||||
- [ ] the error body of a request without credentials and of a wrong path
|
||||
- [ ] `ResetType@Redfish.AllowableValues` from `Systems/1`
|
||||
- [ ] IPMI: FRU, sensor list, chassis status, SEL (via `ipmitool` for comparison with `pyghmi`)
|
||||
|
||||
Or run the Redfish-Mockup-Creator once against the BMC and keep its output.
|
||||
Reference in new issue
Block a user