use crate::{SecretError, SecretResult};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub mod env;
pub mod file;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecretValue {
value: String,
pub metadata: HashMap<String, String>,
pub retrieved_at: chrono::DateTime<chrono::Utc>,
}
impl SecretValue {
pub fn new(value: impl Into<String>) -> Self {
Self {
value: value.into(),
metadata: HashMap::new(),
retrieved_at: chrono::Utc::now(),
}
}
pub fn with_metadata(value: impl Into<String>, metadata: HashMap<String, String>) -> Self {
Self {
value: value.into(),
metadata,
retrieved_at: chrono::Utc::now(),
}
}
pub fn value(&self) -> &str {
&self.value
}
pub fn is_expired(&self, ttl_seconds: u64) -> bool {
let now = chrono::Utc::now();
let elapsed = now.signed_duration_since(self.retrieved_at);
elapsed.num_seconds() > ttl_seconds as i64
}
}
#[async_trait]
pub trait SecretProvider: Send + Sync {
async fn get_secret(&self, name: &str) -> SecretResult<SecretValue>;
async fn list_secrets(&self) -> SecretResult<Vec<String>> {
Err(SecretError::internal(
"list_secrets not supported by this provider",
))
}
async fn health_check(&self) -> SecretResult<()> {
match self.get_secret("__health_check__").await {
Err(SecretError::NotFound { .. }) => Ok(()),
Err(e) => Err(e),
Ok(_) => Ok(()), }
}
fn name(&self) -> &str;
}