rufish

rufish is an asynchronous Redfish client library written in Rust for BMC/server out-of-band management via the DMTF Redfish REST API.
Features
- ✅ Async HTTP/HTTPS client (based on
reqwest + tokio)
- ✅ Session-based authentication (X-Auth-Token) with fallback to Basic Auth
- ✅ Builder pattern — inject custom
reqwest::Client, existing session tokens, or credentials
- ✅ Session persistence — get/set tokens for cross-restart reuse
- ✅ Self-signed certificate support (common for BMCs)
- ✅ Typed Rust structs for all major Redfish resources
- ✅ High-level API for common operations:
- Systems, Chassis, Managers
- Power & Thermal monitoring
- Processors, Memory, Storage, Drives
- Ethernet Interfaces (System & Manager)
- Chassis Indicator LED (LocationIndicatorActive / IndicatorLED)
- Power control (On/Off/Restart/Cycle)
- Boot override (PXE, BIOS Setup, HDD, etc.)
- Account management
- Log services
- Update & Event services
- ✅ Low-level GET/POST/PATCH/DELETE for any Redfish endpoint
- ✅ Proper error handling with typed errors
Quick Start
use rufish::RedfishClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = RedfishClient::new("10.0.0.5", "admin", "password")?;
client.login().await?;
let root = client.get_service_root().await?;
println!("Redfish version: {:?}", root.redfish_version);
let systems = client.list_systems().await?;
println!("Systems: {:?}", systems.members_count);
let sys = client.get_system("1").await?;
println!("Model: {:?}, Power: {:?}", sys.model, sys.power_state);
client.power_on("1").await?;
client.graceful_shutdown("1").await?;
let thermal = client.get_thermal("1").await?;
for t in thermal.temperatures.unwrap_or_default() {
println!("{}: {}°C", t.name.unwrap_or_default(), t.reading_celsius.unwrap_or(0.0));
}
client.set_boot_pxe("1").await?;
client.logout().await?;
Ok(())
}
Builder Pattern
use rufish::RedfishClient;
let custom = reqwest::Client::builder()
.use_native_tls()
.http1_only()
.danger_accept_invalid_certs(true)
.build()?;
let client = RedfishClient::builder("10.0.0.5")
.credentials("admin", "password")
.client(custom)
.build()?;
let client = RedfishClient::builder("10.0.0.5")
.credentials("admin", "password")
.session("saved-token", "/redfish/v1/SessionService/Sessions/1")
.build()?;
API Summary
Session & Construction
| Method |
Description |
new(host, user, pass) |
Create client (HTTPS, accepts self-signed certs) |
builder(host) |
Start building a client with custom options |
.credentials(user, pass) |
Set credentials (builder) |
.client(reqwest_client) |
Inject custom reqwest Client (builder) |
.session(token, uri) |
Inject existing session token (builder) |
.build() |
Finalize and create the client (builder) |
set_session(token, uri) |
Inject session token after construction |
session_token() |
Get current token (for persistence) |
session_uri() |
Get current session URI |
login() |
Establish Redfish session |
logout() |
Close session |
Resources (GET)
| Method |
Description |
get_service_root() |
Service Root |
list_systems() / get_system(id) |
Computer Systems |
list_chassis() / get_chassis(id) |
Chassis |
list_managers() / get_manager(id) |
Managers (BMC) |
get_power(chassis_id) |
Power readings & supplies |
get_thermal(chassis_id) |
Temperatures & fans |
list_processors(sys) / get_processor(sys, id) |
CPUs |
list_memory(sys) / get_memory(sys, id) |
DIMMs |
list_storage(sys) / get_storage(sys, id) |
Storage controllers |
list_ethernet_interfaces(sys) |
NICs |
list_manager_ethernet_interfaces(mgr) |
BMC network interfaces |
get_manager_ethernet_interface(mgr, id) |
Get BMC NIC details |
patch_manager_ethernet_interface(mgr, id, body) |
Update BMC NIC settings |
get_chassis_indicator(chassis) |
Get Indicator LED state |
get_account_service() / list_accounts() |
User accounts |
get_update_service() |
Firmware update service |
get_event_service() |
Event subscriptions |
list_log_entries(mgr, log) |
Log entries |
Actions (POST/PATCH)
| Method |
Description |
reset_system(id, type) |
Reset with any ResetType |
power_on(id) |
Power on |
power_off(id) |
Force power off |
graceful_shutdown(id) |
ACPI shutdown |
graceful_restart(id) |
Graceful restart |
force_restart(id) |
Force restart |
power_cycle(id) |
Power cycle |
set_boot_override(id, target, enabled) |
Set boot source |
set_boot_pxe(id) |
Boot to PXE |
set_boot_bios(id) |
Boot to BIOS Setup |
set_chassis_indicator(chassis, on) |
Set Indicator LED on/off |
reset_manager(id, type) |
Reset BMC |
clear_log(mgr, log) |
Clear log service |
Virtual Media
| Method |
Description |
list_virtual_media(mgr) |
List virtual media devices |
get_virtual_media(mgr, id) |
Get virtual media status |
insert_media(mgr, id, url) |
Mount ISO/IMG from URL |
eject_media(mgr, id) |
Unmount media |
BIOS & Secure Boot
| Method |
Description |
get_bios(sys) |
Get current BIOS attributes |
get_bios_settings(sys) |
Get pending BIOS settings |
set_bios_attributes(sys, attrs) |
Set BIOS attributes (next boot) |
get_secure_boot(sys) |
Get Secure Boot status |
set_secure_boot(sys, enabled) |
Enable/disable Secure Boot |
Storage / RAID
| Method |
Description |
list_volumes(sys, storage) |
List RAID volumes |
get_volume(sys, storage, vol) |
Get volume details |
create_volume(sys, storage, body) |
Create RAID volume |
delete_volume(sys, storage, vol) |
Delete volume |
get_drive(path) |
Get drive details |
Network & Certificates
| Method |
Description |
get_network_protocol(mgr) |
BMC network services (NTP, SSH, etc.) |
set_network_protocol(mgr, settings) |
Update network settings |
list_serial_interfaces(mgr) |
List serial interfaces |
list_certificates(mgr) |
List HTTPS certificates |
replace_certificate(path, pem, type) |
Replace certificate |
Event Subscriptions
| Method |
Description |
list_subscriptions() |
List event subscriptions |
create_subscription(dest, types, ctx) |
Create subscription |
delete_subscription(id) |
Delete subscription |
Firmware Update
| Method |
Description |
list_firmware_inventory() |
List firmware items |
get_firmware_item(id) |
Get firmware version info |
simple_update(image_uri) |
Trigger firmware update from URI |
Tasks & Pagination
| Method |
Description |
list_tasks() |
List async tasks |
get_task(id) |
Get task status |
wait_task(id, timeout_secs) |
Poll until task completes |
get_all_members(path) |
Auto-follow @odata.nextLink |
Raw Access
| Method |
Description |
get(path) |
GET any endpoint (returns serde_json::Value) |
post(path, body) |
POST action |
patch(path, body) |
PATCH resource |
delete(path) |
DELETE resource |
Dependencies
[dependencies]
reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "1"
log = "0.4"
License
MIT OR Apache-2.0