vector/secrets/
file.rs

1use std::collections::{HashMap, HashSet};
2use std::path::PathBuf;
3
4use vector_lib::configurable::{component::GenerateConfig, configurable_component};
5
6use crate::{config::SecretBackend, signal};
7
8/// Configuration for the `file` secrets backend.
9#[configurable_component(secrets("file"))]
10#[derive(Clone, Debug)]
11pub struct FileBackend {
12    /// File path to read secrets from.
13    pub path: PathBuf,
14}
15
16impl GenerateConfig for FileBackend {
17    fn generate_config() -> toml::Value {
18        toml::Value::try_from(FileBackend {
19            path: PathBuf::from("/path/to/secret"),
20        })
21        .unwrap()
22    }
23}
24
25impl SecretBackend for FileBackend {
26    async fn retrieve(
27        &mut self,
28        secret_keys: HashSet<String>,
29        _: &mut signal::SignalRx,
30    ) -> crate::Result<HashMap<String, String>> {
31        let contents = tokio::fs::read_to_string(&self.path).await?;
32        let output = serde_json::from_str::<HashMap<String, String>>(&contents)?;
33        let mut secrets = HashMap::new();
34        for k in secret_keys.into_iter() {
35            if let Some(secret) = output.get(&k) {
36                if secret.is_empty() {
37                    return Err(format!("secret for key '{k}' was empty").into());
38                }
39                secrets.insert(k, secret.to_string());
40            } else {
41                return Err(format!("secret for key '{k}' was not retrieved").into());
42            }
43        }
44        Ok(secrets)
45    }
46}