use std::env;
use std::fs::{self, File};
use std::io::{self, BufReader, Read};
use std::path::Path;
const DEFAULT_SECRET_PATH: &str = "/run/secrets";
fn get_secrets_path() -> String {
env::var("DOCKER_SECRETS_DIR").unwrap_or_else(|_| DEFAULT_SECRET_PATH.to_string())
}
pub fn get_list() -> io::Result<Vec<String>> {
let secret_path = get_secrets_path();
let path = Path::new(&secret_path);
let entries = fs::read_dir(path)?;
let list: Vec<String> = entries
.filter_map(|entry| entry.ok().and_then(|e| e.file_name().into_string().ok()))
.collect();
Ok(list)
}
pub fn get(secret_name: &str) -> io::Result<String> {
let secret_path = get_secrets_path();
let path = Path::new(&secret_path).join(secret_name);
let file = File::open(path)?;
let mut buf_reader = BufReader::new(file);
let mut contents = String::new();
buf_reader.read_to_string(&mut contents)?;
Ok(contents.trim().to_string())
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs::File;
use std::io::Write;
use std::sync::Mutex;
use tempfile::TempDir;
static TEST_MUTEX: Mutex<()> = Mutex::new(());
fn setup_secrets() -> (TempDir, std::sync::MutexGuard<'static, ()>) {
let guard = TEST_MUTEX.lock().unwrap();
let temp_dir = TempDir::new().expect("Failed to create temp dir");
unsafe {
env::set_var("DOCKER_SECRETS_DIR", temp_dir.path());
}
(temp_dir, guard)
}
#[test]
fn test_get_list() {
let (temp_dir, _guard) = setup_secrets();
let secret1_path = temp_dir.path().join("secret1");
let secret2_path = temp_dir.path().join("secret2");
File::create(&secret1_path).unwrap();
File::create(&secret2_path).unwrap();
let list = get_list().expect("Failed to get list");
assert!(list.contains(&"secret1".to_string()));
assert!(list.contains(&"secret2".to_string()));
assert_eq!(list.len(), 2);
}
#[test]
fn test_get_secret() {
let (temp_dir, _guard) = setup_secrets();
let secret_path = temp_dir.path().join("my_secret");
let mut file = File::create(&secret_path).unwrap();
writeln!(file, "super_secret_value").unwrap();
let value = get("my_secret").expect("Failed to get secret");
assert_eq!(value, "super_secret_value");
}
#[test]
fn test_get_non_existent_secret() {
let (_temp_dir, _guard) = setup_secrets();
let result = get("non_existent");
assert!(result.is_err());
}
}