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