From 5f8a4ef9751ef2cfbf149982a2038526fe4b9be5 Mon Sep 17 00:00:00 2001 From: Christian Manivong Date: Tue, 13 Oct 2026 01:15:57 +0200 Subject: [PATCH] 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. --- .gitignore | 7 ++ LICENSE | 191 +++++++++++++++++++++++++++++++++++++++++ README.md | 65 ++++++++++++++ docs/redfish-map.md | 44 ++++++++++ docs/references.md | 46 ++++++++++ docs/role.md | 70 +++++++++++++++ docs/security.md | 43 ++++++++++ docs/supermicro-x10.md | 44 ++++++++++ docs/testing.md | 47 ++++++++++ 9 files changed, 557 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 docs/redfish-map.md create mode 100644 docs/references.md create mode 100644 docs/role.md create mode 100644 docs/security.md create mode 100644 docs/supermicro-x10.md create mode 100644 docs/testing.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3b4fdc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +__pycache__/ +*.py[cod] +*.egg-info/ +build/ +dist/ +.venv/ +.pytest_cache/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..68d39ec --- /dev/null +++ b/LICENSE @@ -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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..2474955 --- /dev/null +++ b/README.md @@ -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/--/`, 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). diff --git a/docs/redfish-map.md b/docs/redfish-map.md new file mode 100644 index 0000000..ff65199 --- /dev/null +++ b/docs/redfish-map.md @@ -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. diff --git a/docs/references.md b/docs/references.md new file mode 100644 index 0000000..e6d3a72 --- /dev/null +++ b/docs/references.md @@ -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. diff --git a/docs/role.md b/docs/role.md new file mode 100644 index 0000000..6b00122 --- /dev/null +++ b/docs/role.md @@ -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`. diff --git a/docs/security.md b/docs/security.md new file mode 100644 index 0000000..eda09ac --- /dev/null +++ b/docs/security.md @@ -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. diff --git a/docs/supermicro-x10.md b/docs/supermicro-x10.md new file mode 100644 index 0000000..c3512bb --- /dev/null +++ b/docs/supermicro-x10.md @@ -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_`. 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:///redfish/v1/ | python3 -m json.tool +# The managed server: model, serial, BIOS, power state +curl -sk -u : https:///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. diff --git a/docs/testing.md b/docs/testing.md new file mode 100644 index 0000000..e4964bd --- /dev/null +++ b/docs/testing.md @@ -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.