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.
71 lines
4.2 KiB
Markdown
71 lines
4.2 KiB
Markdown
# 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`.
|