vector/secrets/
directory.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 `directory` secrets backend.
9#[configurable_component(secrets("directory"))]
10#[derive(Clone, Debug)]
11pub struct DirectoryBackend {
12    /// Directory path to read secrets from.
13    pub path: PathBuf,
14
15    /// Remove trailing whitespace from file contents.
16    #[serde(default)]
17    pub remove_trailing_whitespace: bool,
18}
19
20impl GenerateConfig for DirectoryBackend {
21    fn generate_config() -> toml::Value {
22        toml::Value::try_from(DirectoryBackend {
23            path: PathBuf::from("/path/to/secrets"),
24            remove_trailing_whitespace: false,
25        })
26        .unwrap()
27    }
28}
29
30impl SecretBackend for DirectoryBackend {
31    async fn retrieve(
32        &mut self,
33        secret_keys: HashSet<String>,
34        _: &mut signal::SignalRx,
35    ) -> crate::Result<HashMap<String, String>> {
36        let mut secrets = HashMap::new();
37        for k in secret_keys.into_iter() {
38            let file_path = self.path.join(&k);
39            let contents = tokio::fs::read_to_string(&file_path).await?;
40            let secret = if self.remove_trailing_whitespace {
41                contents.trim_end()
42            } else {
43                &contents
44            };
45            if secret.is_empty() {
46                return Err(format!("secret in file '{k}' was empty").into());
47            }
48            secrets.insert(k, secret.to_string());
49        }
50        Ok(secrets)
51    }
52}