use crate::error::SealingError;
use crate::models::{SealedSecretManifest, SecretManifest, SecretRequest};
use crate::security::{CleanupGuard, SecureTempFile};
use std::process::Command;
pub fn check_kubeseal_exists() -> Result<(), SealingError> {
match which::which("kubeseal") {
Ok(_) => Ok(()),
Err(_) => Err(SealingError::KubesealNotFound {
message: "kubeseal binary not found in PATH. Please install kubeseal.".to_string(),
}),
}
}
pub fn seal_secret(request: &SecretRequest) -> Result<SealedSecretManifest, anyhow::Error> {
check_kubeseal_exists()?;
let manifest = SecretManifest::from_request(request);
let yaml = manifest.to_yaml()?;
let mut temp_file =
SecureTempFile::new().map_err(|e| SealingError::TempFileCreationFailed {
error: e.to_string(),
})?;
let temp_path = temp_file.path().to_path_buf();
let _cleanup = CleanupGuard::new(move || {
if temp_path.exists() {
let _ = std::fs::remove_file(&temp_path);
}
});
temp_file
.write_all(yaml.as_bytes())
.map_err(|e| SealingError::TempFileCreationFailed {
error: e.to_string(),
})?;
let output = Command::new("kubeseal")
.arg("--format")
.arg("yaml")
.stdin(
std::fs::File::open(temp_file.path())
.map_err(|e| SealingError::Other(e.to_string()))?,
)
.output()
.map_err(|e| SealingError::KubesealExecutionFailed {
stderr: e.to_string(),
exit_code: -1,
})?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Err(SealingError::KubesealExecutionFailed {
stderr: stderr.to_string(),
exit_code: output.status.code().unwrap_or(-1),
}
.into());
}
let stdout = String::from_utf8_lossy(&output.stdout);
let sealed_secret = SealedSecretManifest::from_yaml(&stdout).map_err(|e| {
SealingError::OutputValidationFailed {
reason: format!("Failed to parse kubeseal output: {}", e),
}
})?;
sealed_secret
.validate_against_request(request)
.map_err(|e| SealingError::OutputValidationFailed {
reason: e.to_string(),
})?;
Ok(sealed_secret)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_check_kubeseal_exists() {
let result = check_kubeseal_exists();
let _ = result;
}
}