use super::{ANCHORS, LOOPBACK, PORT};
use crate::xdg::Env;
use std::path::{Path, PathBuf};
pub const SUBCMD: &str = "wire-certs";
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Plan {
pub dir: PathBuf,
pub address: String,
pub force: bool,
}
pub fn plan(
world: &Env,
dir: Option<String>,
host: Option<String>,
port: Option<String>,
force: Option<String>,
) -> Plan {
let host = stated(host).unwrap_or_else(|| LOOPBACK.to_owned());
let port = stated(port).unwrap_or_else(|| PORT.to_owned());
let dir = stated(dir).map_or_else(|| super::super::material::dir(world), PathBuf::from);
Plan {
dir,
address: format!("{host}:{port}"),
force: stated(force).is_some(),
}
}
fn stated(value: Option<String>) -> Option<String> {
value.filter(|v| !v.is_empty())
}
pub const READS: [&str; 4] = ["WIRE_DIR", "WIRE_HOST", "WIRE_PORT", "FORCE"];
pub fn perform(plan: &Plan) -> i32 {
if plan.dir.join(ANCHORS).is_file() && !plan.force {
eprintln!(
"yog {SUBCMD}: {} already holds material; rotating distrusts every certificate \
already issued. Re-run with FORCE=1 if that is what you mean.",
plan.dir.display()
);
return 1;
}
match super::mint(&plan.dir, &plan.address, plan.force) {
Ok(()) => {
report(&plan.dir, &plan.address);
0
}
Err(e) => {
eprintln!("yog {SUBCMD}: {e}");
1
}
}
}
fn report(dir: &Path, address: &str) {
println!(
"yog {SUBCMD}: {} holds {}",
dir.display(),
super::artifacts().join(", ")
);
println!(" the engine binds and a local seat dials {address}");
println!(
" issue another client with: openssl req … -CA {} -CAkey {}",
dir.join(ANCHORS).display(),
dir.join(super::CA_KEY).display()
);
}
#[cfg(test)]
mod tests;