use std::path::PathBuf;
use std::sync::Arc;
use async_trait::async_trait;
use mz_repr::GlobalId;
use mz_secrets::{SecretsController, SecretsReader};
use tokio::fs::{self, OpenOptions};
use tokio::io::AsyncWriteExt;
use crate::ProcessOrchestrator;
#[async_trait]
impl SecretsController for ProcessOrchestrator {
async fn ensure(&self, id: GlobalId, contents: &[u8]) -> Result<(), anyhow::Error> {
let file_path = self.secrets_dir.join(id.to_string());
let mut file = OpenOptions::new()
.mode(0o600)
.create(true)
.write(true)
.truncate(true)
.open(file_path)
.await?;
file.write_all(contents).await?;
file.sync_all().await?;
Ok(())
}
async fn delete(&self, id: GlobalId) -> Result<(), anyhow::Error> {
fs::remove_file(self.secrets_dir.join(id.to_string())).await?;
Ok(())
}
async fn list(&self) -> Result<Vec<GlobalId>, anyhow::Error> {
let mut ids = Vec::new();
let mut entries = fs::read_dir(&self.secrets_dir).await?;
while let Some(dir) = entries.next_entry().await? {
let id: GlobalId = dir.file_name().to_string_lossy().parse()?;
ids.push(id);
}
Ok(ids)
}
fn reader(&self) -> Arc<dyn SecretsReader> {
Arc::new(ProcessSecretsReader {
secrets_dir: self.secrets_dir.clone(),
})
}
}
#[derive(Debug)]
pub struct ProcessSecretsReader {
secrets_dir: PathBuf,
}
impl ProcessSecretsReader {
pub fn new(secrets_dir: PathBuf) -> ProcessSecretsReader {
ProcessSecretsReader { secrets_dir }
}
}
#[async_trait]
impl SecretsReader for ProcessSecretsReader {
async fn read(&self, id: GlobalId) -> Result<Vec<u8>, anyhow::Error> {
let contents = fs::read(self.secrets_dir.join(id.to_string())).await?;
Ok(contents)
}
}