manta_server/server/common/app_context.rs
1//! Server-side runtime infrastructure context.
2//!
3//! [`InfraContext`] is the bundle of per-site connection data passed
4//! through the service layer for every request: backend dispatcher,
5//! API base URLs, TLS cert, optional vault/k8s URLs, SOCKS proxy.
6//! It depends on `StaticBackendDispatcher`, which is server-only —
7//! the CLI never instantiates this.
8//!
9//! ## Lifetime
10//!
11//! `InfraContext<'a>` borrows everything from `ServerState`:
12//! the backend dispatcher, URLs, root cert bytes, etc. live for the
13//! whole server lifetime, but the borrow is taken anew per request.
14//! Handlers obtain a context via
15//! `state.infra_context(&site_name)` (returning
16//! [`Result<InfraContext<'_>, Error>`]), then pass it by reference
17//! into the service layer:
18//!
19//! ```ignore
20//! let infra = state.infra_context(&site_name)?;
21//! service::group::get_groups(&infra, &token, ¶ms).await
22//! ```
23//!
24//! The `_` lifetime is tied to the `state` borrow, so an
25//! `InfraContext` cannot outlive the `Arc<ServerState>` that produced
26//! it.
27//!
28//! ## Typical usage
29//!
30//! Service functions reach the backend through `infra.backend.*`
31//! (calling the trait method belonging to the desired interface, e.g.
32//! `infra.backend.get_bootparameters(...)`). When a function needs to
33//! build a direct CSM HTTP client — e.g. for IMS customize jobs that
34//! aren't routed through the dispatcher — it uses
35//! `infra.shasta_base_url`, `infra.shasta_root_cert`, and
36//! `infra.socks5_proxy` together. Vault- and k8s-dependent paths
37//! gate on `infra.vault_base_url` / `infra.k8s_api_url` being
38//! `Some`; when either is `None` the handler returns 501.
39
40use crate::dispatcher::StaticBackendDispatcher;
41
42/// Infrastructure context needed by the service layer: backend
43/// dispatcher, API endpoints, and TLS certificates.
44///
45/// Constructed per-request by `ServerState::infra_context(site_name)`
46/// from the matching `[sites.X]` block in `server.toml`. The borrows
47/// live for the duration of the handler call.
48#[derive(Debug)]
49pub struct InfraContext<'a> {
50 /// Backend client (CSM or OCHAMI) for this site.
51 pub backend: &'a StaticBackendDispatcher,
52 /// Name of the site this context belongs to, sourced from the
53 /// `X-Manta-Site` header on the inbound request.
54 pub site_name: &'a str,
55 /// Base URL of the site's CSM / OpenCHAMI API
56 /// (e.g. `https://api.alps.cscs.ch`).
57 pub shasta_base_url: &'a str,
58 /// DER- or PEM-encoded root CA bytes for verifying TLS against
59 /// `shasta_base_url`.
60 pub shasta_root_cert: &'a [u8],
61 /// Optional per-site SOCKS5 proxy URL forwarded to every outbound
62 /// HTTP request for this site's backend.
63 pub socks5_proxy: Option<&'a str>,
64 /// Optional Vault base URL; `None` makes Vault-dependent handlers
65 /// return 501.
66 pub vault_base_url: Option<&'a str>,
67 /// Base URL of the site's Gitea VCS, used by SAT-file rendering
68 /// and `run session` to resolve repository references.
69 pub gitea_base_url: &'a str,
70 /// Optional Kubernetes API URL; `None` makes k8s-dependent handlers
71 /// (console, session-logs SSE) return 501.
72 pub k8s_api_url: Option<&'a str>,
73}