rufish 0.4.1

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

rufish

Crates.io Docs.rs CI License

An asynchronous Redfish client library for BMC/server out-of-band management in Rust.

[dependencies]
rufish = "0.4"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

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 sys = client.get_system("1").await?;
    println!("{:?}{:?}", sys.model, sys.power_state);

    client.graceful_shutdown("1").await?;
    client.logout().await?;
    Ok(())
}

Features

Category Capabilities
Core Async HTTP/HTTPS, session auth (X-Auth-Token) + Basic Auth fallback, self-signed cert support, builder pattern
Resources Systems, Chassis, Managers, Processors, Memory, Storage, Drives, NICs, Virtual Media, Certificates
Actions Power control, boot override, BIOS settings, Secure Boot, RAID management, firmware update, log management
UI-Friendly Registry metadata parsing, system health summary, storage overview, enriched logs, hardware topology
Fleet Management Multi-host pool with concurrency control, BIOS config export/import/diff
Reliability Auto-retry with exponential backoff, session auto-renewal on 401
Real-time SSE event streaming, event subscriptions

Usage Examples

System Health Dashboard

// One call → aggregated health from System + Thermal + Power
let health = client.get_system_health("1", "1").await?;
println!("Overall: {:?}", health.overall);       // OK / Warning / Critical
println!("CPU: {:?}", health.processors);
for t in &health.temperatures {
    println!("  {} = {:?}°C ({:?})", t.name, t.reading, t.status);
}

BIOS Configuration (UI-Friendly)

// Get BIOS attributes with full metadata for rendering forms
let attrs = client.get_bios_attributes_full("1").await?;
for attr in &attrs {
    println!("[{}] {} = {:?}", attr.group.as_deref().unwrap_or("General"),
             attr.display_name, attr.current_value);
    if let Some(allowed) = &attr.allowed_values {
        println!("  Options: {:?}", allowed.iter().map(|v| &v.value).collect::<Vec<_>>());
    }
}

// Set BIOS attributes (applied on next boot)
client.set_bios_attributes("1", &serde_json::json!({
    "BootMode": "Uefi",
    "HyperThreading": "Enabled"
})).await?;

BIOS Config Export/Import (Fleet Deployment)

use rufish::BiosConfig;

// Export from golden image server
let config = client.export_bios_config("1").await?;
let json = config.to_json()?;
std::fs::write("bios_golden.json", &json)?;

// Import to other servers
let config = BiosConfig::from_json(&std::fs::read_to_string("bios_golden.json")?)?;
let diff = client.diff_bios_config("1", &config).await?;
println!("Changes needed: {}", diff.changed.len());
client.import_bios_config("1", &config).await?;

Storage Overview

let storage = client.get_storage_overview("1").await?;
for vol in &storage.volumes {
    println!("Volume {}{} {:?} ({} drives)",
             vol.name, vol.raid_type.as_deref().unwrap_or("?"),
             vol.status, vol.drive_count);
}
println!("Unassigned drives: {}", storage.unassigned_drives.len());

Enriched Logs (Auto-Translated)

let logs = client.get_enriched_logs("1", "Sel").await?;
for entry in &logs {
    println!("[{}] {}{}",
             entry.severity.as_deref().unwrap_or("?"),
             entry.message,
             entry.resolution.as_deref().unwrap_or(""));
}

Real-Time Events (SSE)

use tokio_stream::StreamExt;

let mut stream = client.subscribe_sse().await?;
while let Some(Ok(event)) = stream.next().await {
    println!("Event: {:?}", event.body);
}

Multi-Host Fleet Management

use rufish::RedfishPool;

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

// Power on all servers
let results = pool.for_each(|c| async move { c.power_on("1").await }).await;
for r in &results {
    println!("{}: {:?}", r.host, r.result.is_ok());
}

Firmware Update with Progress

client.update_firmware_with_progress(
    "http://fileserver/bmc_fw.bin",
    600, // timeout seconds
    |state, percent| {
        println!("State: {}{:?}%", state, percent);
    },
).await?;

Hardware Topology

let topo = client.get_topology("1").await?;
println!("System: {:?} ({:?})", topo.system.model, topo.system.power_state);
for cpu in &topo.system.processors {
    println!("  CPU: {:?}{:?}", cpu.name, cpu.status);
}
for dimm in &topo.system.memory {
    println!("  MEM: {:?}{:?}", dimm.name, dimm.description);
}

Auto-Retry (Session Renewal + Backoff)

// Automatically re-login on 401, exponential backoff on network errors
let val = client.get_with_retry("/redfish/v1/Systems/1", 3).await?;

User Account Management

let users = client.list_users().await?;
for u in &users {
    println!("{} (role={:?}, enabled={})", u.username, u.role, u.enabled);
}

client.create_user("operator", "SecureP@ss1", "Operator").await?;
client.change_password("3", "NewP@ss2").await?;
client.set_user_role("3", "Administrator").await?;

Builder Pattern (Advanced)

let custom = reqwest::Client::builder()
    .danger_accept_invalid_certs(true)
    .timeout(std::time::Duration::from_secs(60))
    .build()?;

let client = RedfishClient::builder("10.0.0.5")
    .credentials("admin", "password")
    .client(custom)
    .session("saved-token", "/redfish/v1/Sessions/1") // restore session
    .build()?;

Full API Reference

See docs.rs/rufish for complete API documentation.

Module Overview

Module Purpose
rufish (root) RedfishClient + all typed resource structs
rufish::registry BIOS/attribute/message registry parsing
rufish::enriched Health summary, storage overview, enriched logs
rufish::bios_config BIOS config export/import/diff
rufish::topology Hardware topology types
rufish::multi RedfishPool for fleet management
rufish::sse SSE event stream types

Supported Operations

Session: new, builder, login, logout, set_session, session_token, session_uri

Systems: list_systems, get_system, list_processors, get_processor, list_memory, get_memory, list_storage, get_storage, list_ethernet_interfaces, get_ethernet_interface

Chassis: list_chassis, get_chassis, get_power, get_thermal, get_chassis_indicator, set_chassis_indicator

Managers: list_managers, get_manager, get_network_protocol, set_network_protocol, list_manager_ethernet_interfaces, get_manager_ethernet_interface, patch_manager_ethernet_interface, list_serial_interfaces, get_serial_interface, list_virtual_media, get_virtual_media, insert_media, eject_media

Power: reset_system, power_on, power_off, graceful_shutdown, graceful_restart, force_restart, power_cycle, reset_manager

Boot: set_boot_override, set_boot_pxe, set_boot_bios

BIOS: get_bios, get_bios_settings, set_bios_attributes, reset_bios_defaults, get_bios_attributes_full, get_secure_boot, set_secure_boot

Storage: list_volumes, get_volume, create_volume, delete_volume, get_drive

Accounts: get_account_service, list_accounts, list_users, create_user, change_password, set_user_role, set_user_enabled, unlock_user, delete_user

Logs: list_log_entries, clear_log, get_enriched_logs

Events: get_event_service, list_subscriptions, create_subscription, delete_subscription, subscribe, subscribe_sse

Firmware: get_update_service, list_firmware_inventory, get_firmware_item, simple_update, update_firmware_with_progress

Certificates: list_certificates, get_certificate, replace_certificate

Tasks: list_tasks, get_task, wait_task

Registry: list_registries, get_registry, get_message_registry, get_attributes_full

Enriched: get_system_health, get_storage_overview, get_topology, export_bios_config, import_bios_config, diff_bios_config

Fleet: RedfishPool::new, add, add_client, remove, hosts, get, get_mut, login_all, logout_all, for_each

Retry: get_with_retry, patch_with_retry, post_with_retry

Raw: get, get_as, post, patch, delete, get_all_members


License

MIT OR Apache-2.0