secret_vault/simple_sources/
files_source.rs1use crate::errors::*;
2use crate::*;
3use async_trait::*;
4use rsb_derive::*;
5use rvstruct::*;
6use secret_vault_value::SecretValue;
7use std::collections::HashMap;
8use std::path::Path;
9use tracing::*;
10
11#[derive(Debug, Clone, Eq, PartialEq, Builder)]
12pub struct FilesSourceOptions {
13 pub root_path: Option<Box<Path>>,
14}
15
16#[derive(Debug)]
17pub struct FilesSource {
18 options: FilesSourceOptions,
19}
20
21impl FilesSource {
22 pub fn new() -> Self {
23 Self::with_options(FilesSourceOptions::new())
24 }
25
26 pub fn with_options(options: FilesSourceOptions) -> Self {
27 Self { options }
28 }
29}
30
31#[async_trait]
32impl SecretsSource for FilesSource {
33 fn name(&self) -> String {
34 "FilesSource".to_string()
35 }
36
37 async fn get_secrets(
38 &self,
39 references: &[SecretVaultRef],
40 ) -> SecretVaultResult<HashMap<SecretVaultRef, Secret>> {
41 let mut result_map: HashMap<SecretVaultRef, Secret> = HashMap::new();
42
43 for secret_ref in references {
44 let secret_file_name: String = format!(
45 "{}{}{}",
46 self.options
47 .root_path
48 .as_ref()
49 .and_then(|rp| rp.to_str())
50 .map(|path| format!("{path}/"))
51 .unwrap_or_default(),
52 secret_ref.key.secret_name.value(),
53 secret_ref
54 .key
55 .secret_version
56 .as_ref()
57 .map(|sv| { format!("_v{}", sv.value()) })
58 .unwrap_or_else(|| "".to_string())
59 );
60
61 trace!("Loading a secret file from: {}", &secret_file_name);
62 match std::fs::read(Path::new(secret_file_name.as_str())) {
63 Ok(file_content) => {
64 let secret_value = SecretValue::from(file_content);
65 let metadata = SecretMetadata::create_from_ref(secret_ref);
66
67 result_map.insert(secret_ref.clone(), Secret::new(secret_value, metadata));
68 }
69 Err(err) if secret_ref.required => {
70 return Err(SecretVaultError::DataNotFoundError(
71 SecretVaultDataNotFoundError::new(
72 SecretVaultErrorPublicGenericDetails::new("SECRET_NOT_FOUND".into()),
73 format!(
74 "Secret is required but corresponding file is not available `{}`: {}",
75 &secret_file_name,
76 err
77 ),
78 ),
79 ));
80 }
81 Err(err) => {
82 debug!("Secret or secret version doesn't exist at {} and since it is not required it is skipped: {}",secret_file_name, err);
83 }
84 }
85 }
86
87 Ok(result_map)
88 }
89}