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}