greentic_runner_host/
secrets.rs

1use std::sync::Arc;
2
3use anyhow::{Context, Result, anyhow};
4use greentic_secrets::SecretsManager;
5use greentic_secrets::env::EnvSecretsManager;
6use tokio::runtime::{Handle, Runtime};
7
8/// Shared secrets manager handle used by the host.
9pub type DynSecretsManager = Arc<dyn SecretsManager>;
10
11/// Supported secrets backend kinds recognised by the runner.
12#[derive(Clone, Debug)]
13pub enum SecretsBackend {
14    Env,
15}
16
17impl SecretsBackend {
18    pub fn from_env(value: Option<String>) -> Result<Self> {
19        match value
20            .unwrap_or_else(|| "env".into())
21            .trim()
22            .to_ascii_lowercase()
23            .as_str()
24        {
25            "" | "env" => Ok(SecretsBackend::Env),
26            other => Err(anyhow!("unsupported SECRETS_BACKEND `{other}`")),
27        }
28    }
29
30    pub fn from_config(cfg: &greentic_config_types::SecretsBackendRefConfig) -> Result<Self> {
31        match cfg.kind.trim().to_ascii_lowercase().as_str() {
32            "" | "none" | "env" => Ok(SecretsBackend::Env),
33            other => Err(anyhow!("unsupported secrets backend `{other}`")),
34        }
35    }
36
37    pub fn build_manager(&self) -> Result<DynSecretsManager> {
38        match self {
39            SecretsBackend::Env => Ok(Arc::new(EnvSecretsManager) as DynSecretsManager),
40        }
41    }
42}
43
44pub fn default_manager() -> DynSecretsManager {
45    Arc::new(EnvSecretsManager) as DynSecretsManager
46}
47
48pub fn read_secret_blocking(manager: &DynSecretsManager, key: &str) -> Result<Vec<u8>> {
49    let bytes = if let Ok(handle) = Handle::try_current() {
50        handle
51            .block_on(manager.read(key))
52            .map_err(|err| anyhow!(err.to_string()))?
53    } else {
54        Runtime::new()
55            .context("failed to initialise secrets runtime")?
56            .block_on(manager.read(key))
57            .map_err(|err| anyhow!(err.to_string()))?
58    };
59    Ok(bytes)
60}