manta_server/
dispatcher.rs

1//! Runtime backend selector — wraps either a CSM or an OpenCHAMI backend
2//! behind a single enum so the rest of the codebase is backend-agnostic.
3
4use csm_rs::ShastaClient;
5use manta_backend_dispatcher::error::Error;
6use ochami_rs::backend_connector::Ochami;
7
8/// Routes API calls to either a CSM or OCHAMI backend.
9///
10/// All backend-specific trait methods are dispatched via
11/// the `dispatch!` macro defined in the
12/// [`crate::backend_dispatcher`] module.
13#[derive(Clone, Debug)]
14#[allow(clippy::upper_case_acronyms)]
15pub enum StaticBackendDispatcher {
16  /// HPE Cray System Management (CSM) backend, used by Alps-style
17  /// deployments. Wraps a `csm-rs` HTTP client (`ShastaClient`).
18  CSM(ShastaClient),
19  /// OpenCHAMI backend, used by sites running the open-source CSM
20  /// alternative. Wraps an `ochami-rs` HTTP client.
21  OCHAMI(Ochami),
22}
23
24impl StaticBackendDispatcher {
25  /// Returns `"csm"` or `"ochami"` for the currently-selected variant.
26  /// Cheap, infallible — intended for use as a structured `tracing` field.
27  pub fn backend_kind(&self) -> &'static str {
28    match self {
29      Self::CSM(_) => "csm",
30      Self::OCHAMI(_) => "ochami",
31    }
32  }
33
34  /// Create a new dispatcher for the given backend type.
35  ///
36  /// `backend_type` must be `"csm"` or `"ochami"`;
37  /// any other value returns an error.
38  pub fn new(
39    backend_type: &str,
40    base_url: &str,
41    root_cert: &[u8],
42    socks5_proxy: Option<&str>,
43  ) -> Result<Self, Error> {
44    match backend_type {
45      "csm" => Ok(Self::CSM(ShastaClient::new(
46        base_url,
47        root_cert,
48        socks5_proxy.map(str::to_string),
49      )?)),
50      "ochami" => {
51        Ok(Self::OCHAMI(Ochami::new(base_url, root_cert, socks5_proxy)))
52      }
53      _ => Err(Error::UnsupportedBackend(format!(
54        "Backend '{backend_type}' not supported"
55      ))),
56    }
57  }
58}