rpki/src/bin/cir_extract_inputs.rs

83 lines
2.9 KiB
Rust

use std::path::PathBuf;
fn usage() -> &'static str {
"Usage: cir_extract_inputs --cir <path> --tals-dir <path> --meta-json <path>"
}
fn main() {
if let Err(err) = run(std::env::args().collect()) {
eprintln!("error: {err}");
std::process::exit(2);
}
}
fn run(argv: Vec<String>) -> Result<(), String> {
let mut cir_path: Option<PathBuf> = None;
let mut tals_dir: Option<PathBuf> = None;
let mut meta_json: Option<PathBuf> = None;
let mut i = 1usize;
while i < argv.len() {
match argv[i].as_str() {
"--help" | "-h" => return Err(usage().to_string()),
"--cir" => {
i += 1;
cir_path = Some(PathBuf::from(argv.get(i).ok_or("--cir requires a value")?));
}
"--tals-dir" => {
i += 1;
tals_dir = Some(PathBuf::from(
argv.get(i).ok_or("--tals-dir requires a value")?,
));
}
"--meta-json" => {
i += 1;
meta_json = Some(PathBuf::from(
argv.get(i).ok_or("--meta-json requires a value")?,
));
}
other => return Err(format!("unknown argument: {other}\n\n{}", usage())),
}
i += 1;
}
let cir_path = cir_path.ok_or_else(|| format!("--cir is required\n\n{}", usage()))?;
let tals_dir = tals_dir.ok_or_else(|| format!("--tals-dir is required\n\n{}", usage()))?;
let meta_json = meta_json.ok_or_else(|| format!("--meta-json is required\n\n{}", usage()))?;
let bytes = std::fs::read(&cir_path)
.map_err(|e| format!("read CIR failed: {}: {e}", cir_path.display()))?;
let cir = rpki::cir::decode_cir(&bytes).map_err(|e| e.to_string())?;
std::fs::create_dir_all(&tals_dir)
.map_err(|e| format!("create tals dir failed: {}: {e}", tals_dir.display()))?;
let mut tal_files = Vec::new();
for (idx, tal) in cir.tals.iter().enumerate() {
let filename = format!("tal-{:03}.tal", idx + 1);
let path = tals_dir.join(filename);
std::fs::write(&path, &tal.tal_bytes)
.map_err(|e| format!("write TAL failed: {}: {e}", path.display()))?;
tal_files.push(serde_json::json!({
"talUri": tal.tal_uri,
"path": path,
}));
}
let validation_time = cir
.validation_time
.format(&time::format_description::well_known::Rfc3339)
.map_err(|e| format!("format validationTime failed: {e}"))?;
let meta = serde_json::json!({
"validationTime": validation_time,
"talFiles": tal_files,
});
if let Some(parent) = meta_json.parent() {
std::fs::create_dir_all(parent)
.map_err(|e| format!("create meta parent failed: {}: {e}", parent.display()))?;
}
std::fs::write(&meta_json, serde_json::to_vec_pretty(&meta).unwrap())
.map_err(|e| format!("write meta json failed: {}: {e}", meta_json.display()))?;
Ok(())
}