rufish 0.4.0

An asynchronous Redfish client library for BMC/server management in Rust.
Documentation

rufish

Crates.io Docs.rs License

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
  • Enriched APIs for UI/dashboard integration:
    • System Health Summary (aggregated status from thermal/power/processors/memory)
    • Storage Overview (controllers + RAID volumes + unassigned drives in one call)
    • Enriched Log Entries (auto-translated via message registry)
    • User Management (create/delete/change password/set role/unlock)
    • Simplified Event Subscription
  • SSE (Server-Sent Events) — real-time event streaming from BMC
  • BIOS Config Export/Import — export from one system, diff, and apply to others
  • Hardware Topology — full system/chassis/manager/processor/memory tree for UI
  • Firmware Update with Progress — update + poll with progress callback
  • Auto-Retry + Session Renewal — automatic re-login on 401, exponential backoff on network errors
  • Multi-Host Pool — manage fleets of BMCs with concurrency control
  • ✅ Low-level GET/POST/PATCH/DELETE for any Redfish endpoint
  • ✅ Registry metadata support — parse BIOS/attribute/message registries into UI-friendly structs
  • ✅ 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?;

    // Service Root
    let root = client.get_service_root().await?;
    println!("Redfish version: {:?}", root.redfish_version);

    // List systems
    let systems = client.list_systems().await?;
    println!("Systems: {:?}", systems.members_count);

    // Get system details
    let sys = client.get_system("1").await?;
    println!("Model: {:?}, Power: {:?}", sys.model, sys.power_state);

    // Power control
    client.power_on("1").await?;
    client.graceful_shutdown("1").await?;

    // Thermal monitoring
    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));
    }

    // Boot override
    client.set_boot_pxe("1").await?;

    client.logout().await?;
    Ok(())
}

Builder Pattern

use rufish::RedfishClient;

// Custom reqwest client (e.g. native-tls, http1_only)
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()?;

// Or restore a persisted session (no login needed)
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)
reset_bios_defaults(sys) Reset BIOS to factory defaults
get_bios_attributes_full(sys) Get BIOS attrs with registry metadata (UI-friendly)
get_secure_boot(sys) Get Secure Boot status
set_secure_boot(sys, enabled) Enable/disable Secure Boot

Registry Metadata (for UI)

Method Description
list_registries() List all available registries
get_registry(id) Get raw registry JSON by ID
get_message_registry(id) Get parsed message registry (events/errors)
get_attributes_full(reg_id, path) Get any attribute registry merged with current values

The get_bios_attributes_full() method returns Vec<RegistryAttribute> with:

  • Display names, descriptions, and grouping for form layout
  • Attribute types (Enum/String/Integer/Boolean/Password)
  • Allowed values with display names (for dropdowns)
  • Current and pending values
  • Read-only / hidden flags
  • Value bounds and string length limits

Enriched APIs (UI/Dashboard)

Method Description
get_system_health(sys, chassis) Aggregated health: CPU, memory, thermal, fans, PSU
get_enriched_logs(mgr, log) Log entries with message registry translation
get_storage_overview(sys) Controllers + volumes + unassigned drives
list_users() All user accounts as simplified structs
create_user(name, pass, role) Create a new user
change_password(id, pass) Change user password
set_user_role(id, role) Change user role
set_user_enabled(id, enabled) Enable/disable user
unlock_user(id) Unlock a locked account
delete_user(id) Delete a user account
subscribe(params) Simplified event subscription
subscribe_sse() Open SSE stream for real-time events
export_bios_config(sys) Export BIOS config as portable struct
import_bios_config(sys, config) Apply a BIOS config to a system
diff_bios_config(sys, config) Compare config vs current settings
get_topology(sys) Full hardware topology tree
update_firmware_with_progress(uri, timeout, cb) Firmware update with progress callback
get_with_retry(path, retries) GET with auto session renewal + backoff
patch_with_retry(path, body, retries) PATCH with auto retry
post_with_retry(path, body, retries) POST with auto retry

Multi-Host Pool

use rufish::RedfishPool;

let mut pool = RedfishPool::new(10); // max 10 concurrent
pool.add("bmc-01", "admin", "pass")?;
pool.add("bmc-02", "admin", "pass")?;
pool.login_all().await;

let results = pool.for_each(|client| async move {
    client.power_on("1").await
}).await;

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