79 lines
2.8 KiB
Rust
79 lines
2.8 KiB
Rust
#[cfg(feature = "secret-vault")]
|
|
use std::collections::HashMap;
|
|
use std::path::Path;
|
|
|
|
#[cfg(feature = "secret-vault")]
|
|
use secret_vault::{
|
|
errors::SecretVaultError, SecretMetadata, SecretSource, SecretVaultRef, SecretVaultResult,
|
|
};
|
|
|
|
#[cfg(feature = "secret-vault")]
|
|
use secrecy::ExposeSecret;
|
|
use secrecy::Secret;
|
|
|
|
#[derive(Debug)]
|
|
pub struct CredentialLoader(cap_std::fs::Dir);
|
|
|
|
impl CredentialLoader {
|
|
pub fn new() -> Option<Self> {
|
|
let credential_directory = std::env::var_os("CREDENTIALS_DIRECTORY")?;
|
|
let dir = std::fs::File::open(credential_directory).ok()?;
|
|
let dir = cap_std::fs::Dir::from_std_file(dir);
|
|
|
|
Some(Self(dir))
|
|
}
|
|
|
|
pub fn get_file<P: AsRef<Path>>(&self, credential: P) -> std::io::Result<cap_std::fs::File> {
|
|
self.0.open(credential)
|
|
}
|
|
|
|
pub fn get<P: AsRef<Path>>(&self, credential: P) -> std::io::Result<Secret<Vec<u8>>> {
|
|
Ok(Secret::from(self.0.read(credential)?))
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "secret-vault")]
|
|
#[async_trait::async_trait]
|
|
impl SecretSource for CredentialLoader {
|
|
fn name(&self) -> String {
|
|
"CredentialLoader".to_string()
|
|
}
|
|
|
|
async fn get_secrets(
|
|
&self,
|
|
references: &[SecretVaultRef],
|
|
) -> SecretVaultResult<HashMap<SecretVaultRef, secret_vault::Secret>> {
|
|
let mut result_map: HashMap<SecretVaultRef, secret_vault::Secret> = HashMap::default();
|
|
|
|
for secret_ref in references {
|
|
let secret_name = secret_ref.key.secret_name.as_ref();
|
|
let secret_version = secret_ref
|
|
.key
|
|
.secret_version
|
|
.as_ref()
|
|
.map(|sv| format!("_v{sv}"))
|
|
.unwrap_or_default();
|
|
let secret_file_name = format!("{secret_name}{secret_version}");
|
|
|
|
match self.get(secret_file_name) {
|
|
Ok(secret_value) => {
|
|
let secret_value = secret_vault_value::SecretValue::new(secret_value.expose_secret().clone());
|
|
let metadata = SecretMetadata::create_from_ref(secret_ref);
|
|
result_map.insert(secret_ref.clone(), secret_vault::Secret::new(secret_value, metadata));
|
|
}
|
|
Err(err) if secret_ref.required => {
|
|
return Err(SecretVaultError::DataNotFoundError(
|
|
secret_vault::errors::SecretVaultDataNotFoundError::new(
|
|
secret_vault::errors::SecretVaultErrorPublicGenericDetails::new("SECRET_NOT_FOUND".into()),
|
|
format!(
|
|
"Secret is required but corresponding file is not available {secret_file_name:?}: {err}"
|
|
))
|
|
))
|
|
}
|
|
Err(_err) => {}
|
|
}
|
|
}
|
|
todo!();
|
|
}
|
|
}
|