use super::models::*;
use crate::error::AppError;
use lmrc_vault::{VaultClient, VaultConfig};
use std::collections::HashMap;
pub struct VaultService {
client: VaultClient,
}
impl VaultService {
pub fn new(vault_addr: String, vault_token: String) -> Result<Self, AppError> {
let config = VaultConfig {
address: vault_addr,
token: vault_token,
};
let client = VaultClient::new(config)
.map_err(|e| AppError::External(format!("Vault client error: {}", e)))?;
Ok(Self { client })
}
pub async fn read_secret(&self, path: &str) -> Result<SecretResponse, AppError> {
let secret = self.client
.read_secret(path)
.await
.map_err(|e| AppError::External(format!("Vault read error: {}", e)))?;
Ok(SecretResponse {
path: path.to_string(),
data: secret.data,
version: secret.metadata.as_ref().and_then(|m| m.version),
created_at: secret.metadata.as_ref().and_then(|m| m.created_time),
})
}
pub async fn write_secret(&self, path: &str, data: HashMap<String, String>) -> Result<SecretResponse, AppError> {
self.client
.write_secret(path, data.clone())
.await
.map_err(|e| AppError::External(format!("Vault write error: {}", e)))?;
Ok(SecretResponse {
path: path.to_string(),
data,
version: Some(1),
created_at: Some(chrono::Utc::now()),
})
}
pub async fn delete_secret(&self, path: &str) -> Result<(), AppError> {
self.client
.delete_secret(path)
.await
.map_err(|e| AppError::External(format!("Vault delete error: {}", e)))?;
Ok(())
}
pub async fn create_token(&self, policies: Vec<String>, ttl: Option<String>) -> Result<TokenResponse, AppError> {
let token_request = lmrc_vault::CreateTokenRequest {
policies: policies.clone(),
ttl,
renewable: Some(true),
display_name: Some("infra-api-service-token".to_string()),
};
let token_response = self.client
.create_token(token_request)
.await
.map_err(|e| AppError::External(format!("Vault token creation error: {}", e)))?;
Ok(TokenResponse {
token: token_response.client_token,
accessor: token_response.accessor,
policies,
ttl: token_response.lease_duration,
renewable: token_response.renewable,
})
}
}