Files
Christian Manivong e9ad7951cd feat: a bmc driver that takes the best of Redfish and IPMI (0.4.0)
bmc (napalm_redfish.bmc:BmcDriver) reads a BMC over Redfish where it
answers. A BMC that refuses Redfish (no license) is read and switched over
IPMI. A getter that fails over Redfish is asked over IPMI where IPMI has it;
IPMI is opened only then. Power control goes over Redfish when it answers,
and a refusal is final. The BMC is reset over Redfish only. Same account
for both; ipmi_port in optional_args.

Discovery suggests bmc for a BMC it finds: the fingerprint rules moved from
RedfishDriver to BmcDriver.
2026-10-17 10:34:20 +02:00

62 lines
4.1 KiB
Markdown

# 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)
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`.
`set_power_state` sends a chassis control (`On` → power up, `GracefulShutdown` → soft off
via ACPI, `ForceOff` → power down, `ForceRestart` → hard reset). IPMI has no graceful
restart, and pyghmi offers no power cycle, so `get_power_state` never offers those two.
No BMC reset over IPMI.
## Redfish and IPMI together (`bmc` entry point)
`BmcDriver` holds a `RedfishDriver` and an `IpmiDriver` for the same BMC and account:
| Situation | Used |
|---|---|
| Redfish answers | Redfish for every getter; IPMI is not opened |
| A getter fails over Redfish (`RedfishError`, `ConnectionException`) | that getter over IPMI, if IPMI has it (Redfish-only getters re-raise) |
| The service root refuses Redfish for want of a license, or Redfish does not answer | IPMI for everything; Redfish-only getters raise `NotImplementedError` |
| `set_power_state` | Redfish when it answers; a refusal (`RuntimeError`) is final |
| `reboot_host` | Redfish only (`Manager.Reset`) |
| `get_management_protocols` over IPMI | `{"ipmi": {"enabled": True, "port": 623}}` |