A Rust library for interacting with the HPE Cray Shasta CSM (Cray System Management) API.
csm-rs (formerly Mesa) is the foundation used by applications like
Manta to integrate with Shasta-based
systems. It avoids unsafe code and aims to provide a safe, ergonomic
async interface to the CSM control plane.
Typical use cases:
- Building applications that integrate Shasta/CSM systems into your ecosystem.
- Simplifying or scripting common CSM operations.
- Extending CSM functionality beyond what the official CLIs expose.
The crate currently wraps the following CSM components:
- HSM (Hardware State Manager) —
hsm - CFS (Configuration Framework Service) — configurations & sessions
- BOS (Boot Orchestration Service) —
bos - BSS (Boot Script Service) —
bss - CAPMC (Cray Advanced Platform Monitoring and Control) —
capmc - IMS (Image Management Service) —
ims - PCS (Power Control Service) —
pcs - Node operations —
node - Kubernetes & Keycloak helpers —
common
Add the crate to your Cargo.toml:
[dependencies]
csm-rs = "0.108"
tokio = { version = "1", features = ["full"] }All HTTP calls are exposed as methods on [ShastaClient]. Construct one
per Shasta installation and reuse it — it caches a pre-built
reqwest::Client (connection pool, TLS context, DNS resolver). The
bearer token is supplied per call, so one client can serve many tokens:
use csm_rs::ShastaClient;
#[tokio::main]
async fn main() -> Result<(), csm_rs::error::Error> {
let client = ShastaClient::new(
"https://api.shasta.example.com",
std::fs::read("/etc/shasta/ca.crt").unwrap()
)?;
let token = "your-bearer-token";
// Methods are namespaced by API module: `<module>_<resource>_<verb>`.
// The first argument is always the bearer token.
let images = client.ims_image_get_all(token).await?;
let groups = client.hsm_group_get_all(token).await?;
let configs = client.cfs_configuration_v2_get_all(token).await?;
Ok(())
}Method names are versioned where the underlying API is — e.g.
cfs_session_v2_get vs cfs_session_v3_get. See each module's rustdoc
for the full list.
Runnable programs under examples/:
list_hsm_groups— minimal client construction plus one GET.list_cfs_sessions— paginated CFS v3 session listing.power_cycle_nodes— PCS transition with synchronous wait.
Each reads CSM_BASE_URL, CSM_TOKEN, and CSM_ROOT_CERT_PATH from
the environment. Run with cargo run --example <name>.
- ≤ 0.106: exposed each HTTP call as a free function taking a
4-parameter auth quartet (
token,base_url,root_cert,proxy). Removed in 0.107. - 0.107.x: free functions replaced by methods on [
ShastaClient]; the token was stored on the client. - 0.108: the token was removed from [
ShastaClient] — it is now passed per call as the method's first argument. One client can serve many tokens; the underlyingreqwest::Client(and its connection pool) is reused across all of them.
// 0.107.x
let client = ShastaClient::new(base_url, token, cert, proxy)?;
client.ims_image_get_all().await?;
// 0.108 – 1.0.0-beta.19
let client = ShastaClient::new(base_url, cert, proxy)?;
client.ims_image_get_all(token).await?;-
1.0.0-beta.20:
ShastaClient::newno longer accepts asocks5_proxyargument; call sites drop the third positional argument. -
1.0.0-beta (current): HSM, CFS, BSS, BOS, and PCS are now generated from the upstream OpenAPI specs via
progenitorat build time. A thin wrapper layer atsrc/<module>/wrapper/preserves the historical<module>_<resource>_<verb>method names, but a handful of return types tightened where the hand-written shapes had silently diverged from the spec:pcs_power_cap_getreturnsPowerCapTaskList(was wrongly typed as a singlePowerCapTaskInfo; the endpoint always returned a list).pcs_power_cap_get_task_idreturnsPowerCapsRetdata.pcs_power_cap_post_snapshotandpcs_power_cap_patchreturnOpTaskStartResponse(the{taskID: …}envelope) instead of the fullPowerCapTaskInfo.pcs_power_cap_patchcorrectly issuesPATCH /power-cap(the previous code sentPUT /power-cap/snapshot).- Several HSM types adopted spec-conformant casing (
MACAddress,IPAddresses,RediscoverOnUpdate); fields likeEthernetInterface.ip_addressesare nowVec<IpAddressMapping>instead of the broken singularip_address: Option<String>. - HSM
Group.label,Group.exclusive_group, andMembers.idsbecame newtypes (ResourceName,XNameRw100); access the innerStringvia.0orDeref.
No
ShastaClient::*method signature changed beyond return-type swaps; per-call signatures are preserved. The CapMC module is currently disabled inlib.rswhile it waits for its own migration pass.
hyper 0.14 remains as a transitive dependency via aws-smithy-http-client 1.1.13 → hyper-rustls 0.24.2. It will drop once aws-smithy-http-client migrates to hyper 1.x. csm-rs itself no longer depends on hyper 0.14 directly.
Build:
cargo buildRun the test suite (some tests require access to a live Shasta backend and are gated accordingly):
cargo test -- --show-outputGenerate API documentation locally:
cargo doc --openReleases are cut with cargo-release:
cargo release patch --executecargo audit currently reports three advisories against
rustls-webpki 0.101.7, all pulled in transitively through the AWS
SDK chain:
- RUSTSEC-2026-0098 — name constraints for URI names were incorrectly accepted.
- RUSTSEC-2026-0099 — name constraints accepted for certificates asserting a wildcard name.
- RUSTSEC-2026-0104 — reachable panic in certificate revocation list parsing.
Dependency chain:
csm-rs
└─ aws-smithy-runtime
└─ aws-smithy-http-client 1.1.12
└─ hyper-rustls 0.24.2
└─ rustls 0.21.12
└─ rustls-webpki 0.101.7 ← vulnerable
These advisories are reachable only through TLS validation performed
by the IMS S3 client (src/ims/s3_client.rs). In the standard
Manta-style deployment, the S3 endpoint is on the CSM-internal
network with a CSM-provisioned certificate chain, so the
attacker-controlled-cert preconditions are weak. Downstream users
should still make their own call.
Build without the ims-s3 feature, which removes the AWS SDK
entirely:
[dependencies]
csm-rs = { version = "1.0.0-beta", default-features = false, features = ["manta-dispatcher", "k8s-console"] }The advisories are allowlisted in .cargo/audit.toml with a comment
linking back here, so CI cargo audit runs stay actionable. Delete
the three IDs from that file once the AWS chain ships a fix.
See CONTRIBUTING.md.
Licensed under the terms of the LICENSE file in the repository root.