mirror of https://github.com/breard-r/acmed.git
Failed to extract signature
5 changed files with 462 additions and 6 deletions
-
157Cargo.lock
-
1Cargo.toml
-
259src/cli.rs
-
30src/log.rs
-
21src/main.rs
@ -0,0 +1,259 @@ |
|||
use crate::log::Level;
|
|||
use clap::{Args, Parser};
|
|||
use std::path::{Path, PathBuf};
|
|||
|
|||
#[derive(Parser, Debug)]
|
|||
#[command(version, about, long_about = None)]
|
|||
pub struct CliArgs {
|
|||
/// Path to the main configuration file
|
|||
#[arg(short, long, value_name = "FILE", default_value = crate::DEFAULT_CONFIG_PATH)]
|
|||
pub config: PathBuf,
|
|||
|
|||
/// Specify the log level
|
|||
#[arg(long, value_name = "LEVEL", value_enum, default_value_t = crate::DEFAULT_LOG_LEVEL)]
|
|||
pub log_level: Level,
|
|||
|
|||
#[command(flatten)]
|
|||
pub log: Log,
|
|||
|
|||
/// Runs in the foreground
|
|||
#[arg(short, long, default_value_t = false)]
|
|||
pub foreground: bool,
|
|||
|
|||
#[command(flatten)]
|
|||
pub pid: Pid,
|
|||
|
|||
/// Add a root certificate to the trust store (can be set multiple times)
|
|||
#[arg(long, value_name = "FILE")]
|
|||
pub root_cert: Vec<PathBuf>,
|
|||
}
|
|||
|
|||
#[derive(Args, Debug)]
|
|||
#[group(multiple = false)]
|
|||
pub struct Log {
|
|||
/// Sends log messages via syslog
|
|||
#[arg(long)]
|
|||
pub log_syslog: bool,
|
|||
|
|||
/// Prints log messages to the standard error output
|
|||
#[arg(long)]
|
|||
pub log_stderr: bool,
|
|||
}
|
|||
|
|||
#[derive(Args, Debug)]
|
|||
#[group(multiple = false)]
|
|||
pub struct Pid {
|
|||
/// Path to the PID file
|
|||
#[arg(long, value_name = "FILE", default_value = crate::DEFAULT_PID_FILE)]
|
|||
pid_file: PathBuf,
|
|||
|
|||
/// Do not create any PID file
|
|||
#[arg(long)]
|
|||
no_pid_file: bool,
|
|||
}
|
|||
|
|||
impl Pid {
|
|||
pub fn get_pid_file(&self) -> Option<&Path> {
|
|||
if !self.no_pid_file {
|
|||
Some(self.pid_file.as_path())
|
|||
} else {
|
|||
None
|
|||
}
|
|||
}
|
|||
}
|
|||
|
|||
#[cfg(test)]
|
|||
mod tests {
|
|||
use super::*;
|
|||
use clap::CommandFactory;
|
|||
|
|||
#[test]
|
|||
fn verify_cli() {
|
|||
CliArgs::command().debug_assert();
|
|||
}
|
|||
|
|||
#[test]
|
|||
fn no_args() {
|
|||
let args: &[&str] = &[];
|
|||
let pa = CliArgs::try_parse_from(args).unwrap();
|
|||
assert_eq!(pa.config, PathBuf::from(crate::DEFAULT_CONFIG_PATH));
|
|||
assert_eq!(pa.log_level, Level::Warn);
|
|||
assert_eq!(pa.log.log_syslog, false);
|
|||
assert_eq!(pa.log.log_stderr, false);
|
|||
assert_eq!(pa.foreground, false);
|
|||
assert_eq!(pa.pid.pid_file, PathBuf::from(crate::DEFAULT_PID_FILE));
|
|||
assert_eq!(pa.pid.no_pid_file, false);
|
|||
assert_eq!(
|
|||
pa.pid.get_pid_file(),
|
|||
Some(PathBuf::from(crate::DEFAULT_PID_FILE).as_path())
|
|||
);
|
|||
assert!(pa.root_cert.is_empty());
|
|||
}
|
|||
|
|||
#[test]
|
|||
fn all_args_long_1() {
|
|||
let argv: &[&str] = &[
|
|||
"acmed",
|
|||
"--config",
|
|||
"/tmp/test.toml",
|
|||
"--log-level",
|
|||
"debug",
|
|||
"--log-syslog",
|
|||
"--foreground",
|
|||
"--pid-file",
|
|||
"/tmp/debug/acmed.pid",
|
|||
"--root-cert",
|
|||
"/tmp/certs/root_01.pem",
|
|||
"--root-cert",
|
|||
"/tmp/certs/root_02.pem",
|
|||
"--root-cert",
|
|||
"/tmp/certs/root_03.pem",
|
|||
];
|
|||
let pa = CliArgs::try_parse_from(argv).unwrap();
|
|||
assert_eq!(pa.config, PathBuf::from("/tmp/test.toml"));
|
|||
assert_eq!(pa.log_level, Level::Debug);
|
|||
assert_eq!(pa.log.log_syslog, true);
|
|||
assert_eq!(pa.log.log_stderr, false);
|
|||
assert_eq!(pa.foreground, true);
|
|||
assert_eq!(
|
|||
pa.pid.get_pid_file(),
|
|||
Some(PathBuf::from("/tmp/debug/acmed.pid").as_path())
|
|||
);
|
|||
assert_eq!(
|
|||
pa.root_cert,
|
|||
vec![
|
|||
PathBuf::from("/tmp/certs/root_01.pem"),
|
|||
PathBuf::from("/tmp/certs/root_02.pem"),
|
|||
PathBuf::from("/tmp/certs/root_03.pem")
|
|||
]
|
|||
);
|
|||
}
|
|||
|
|||
#[test]
|
|||
fn all_args_long_2() {
|
|||
let argv: &[&str] = &[
|
|||
"acmed",
|
|||
"--config",
|
|||
"/tmp/test.toml",
|
|||
"--log-level",
|
|||
"debug",
|
|||
"--log-stderr",
|
|||
"--foreground",
|
|||
"--no-pid-file",
|
|||
"--root-cert",
|
|||
"/tmp/certs/root_01.pem",
|
|||
"--root-cert",
|
|||
"/tmp/certs/root_02.pem",
|
|||
"--root-cert",
|
|||
"/tmp/certs/root_03.pem",
|
|||
];
|
|||
let pa = CliArgs::try_parse_from(argv).unwrap();
|
|||
assert_eq!(pa.config, PathBuf::from("/tmp/test.toml"));
|
|||
assert_eq!(pa.log_level, Level::Debug);
|
|||
assert_eq!(pa.log.log_syslog, false);
|
|||
assert_eq!(pa.log.log_stderr, true);
|
|||
assert_eq!(pa.foreground, true);
|
|||
assert_eq!(pa.pid.get_pid_file(), None);
|
|||
assert_eq!(
|
|||
pa.root_cert,
|
|||
vec![
|
|||
PathBuf::from("/tmp/certs/root_01.pem"),
|
|||
PathBuf::from("/tmp/certs/root_02.pem"),
|
|||
PathBuf::from("/tmp/certs/root_03.pem")
|
|||
]
|
|||
);
|
|||
}
|
|||
|
|||
#[test]
|
|||
fn all_args_short_1() {
|
|||
let argv: &[&str] = &[
|
|||
"acmed",
|
|||
"-c",
|
|||
"/tmp/test.toml",
|
|||
"--log-level",
|
|||
"debug",
|
|||
"--log-syslog",
|
|||
"-f",
|
|||
"--pid-file",
|
|||
"/tmp/debug/acmed.pid",
|
|||
"--root-cert",
|
|||
"/tmp/certs/root_01.pem",
|
|||
"--root-cert",
|
|||
"/tmp/certs/root_02.pem",
|
|||
"--root-cert",
|
|||
"/tmp/certs/root_03.pem",
|
|||
];
|
|||
let pa = CliArgs::try_parse_from(argv).unwrap();
|
|||
assert_eq!(pa.config, PathBuf::from("/tmp/test.toml"));
|
|||
assert_eq!(pa.log_level, Level::Debug);
|
|||
assert_eq!(pa.log.log_syslog, true);
|
|||
assert_eq!(pa.log.log_stderr, false);
|
|||
assert_eq!(pa.foreground, true);
|
|||
assert_eq!(
|
|||
pa.pid.get_pid_file(),
|
|||
Some(PathBuf::from("/tmp/debug/acmed.pid").as_path())
|
|||
);
|
|||
assert_eq!(
|
|||
pa.root_cert,
|
|||
vec![
|
|||
PathBuf::from("/tmp/certs/root_01.pem"),
|
|||
PathBuf::from("/tmp/certs/root_02.pem"),
|
|||
PathBuf::from("/tmp/certs/root_03.pem")
|
|||
]
|
|||
);
|
|||
}
|
|||
|
|||
#[test]
|
|||
fn all_args_short_2() {
|
|||
let argv: &[&str] = &[
|
|||
"acmed",
|
|||
"-c",
|
|||
"/tmp/test.toml",
|
|||
"--log-level",
|
|||
"debug",
|
|||
"--log-stderr",
|
|||
"-f",
|
|||
"--no-pid-file",
|
|||
"--root-cert",
|
|||
"/tmp/certs/root_01.pem",
|
|||
"--root-cert",
|
|||
"/tmp/certs/root_02.pem",
|
|||
"--root-cert",
|
|||
"/tmp/certs/root_03.pem",
|
|||
];
|
|||
let pa = CliArgs::try_parse_from(argv).unwrap();
|
|||
assert_eq!(pa.config, PathBuf::from("/tmp/test.toml"));
|
|||
assert_eq!(pa.log_level, Level::Debug);
|
|||
assert_eq!(pa.log.log_syslog, false);
|
|||
assert_eq!(pa.log.log_stderr, true);
|
|||
assert_eq!(pa.foreground, true);
|
|||
assert_eq!(pa.pid.get_pid_file(), None);
|
|||
assert_eq!(
|
|||
pa.root_cert,
|
|||
vec![
|
|||
PathBuf::from("/tmp/certs/root_01.pem"),
|
|||
PathBuf::from("/tmp/certs/root_02.pem"),
|
|||
PathBuf::from("/tmp/certs/root_03.pem")
|
|||
]
|
|||
);
|
|||
}
|
|||
|
|||
#[test]
|
|||
fn err_log_output() {
|
|||
let argv: &[&str] = &["acmed", "--log-stderr", "--log-syslog"];
|
|||
let pa = CliArgs::try_parse_from(argv);
|
|||
assert!(pa.is_err());
|
|||
}
|
|||
|
|||
#[test]
|
|||
fn err_pid_file() {
|
|||
let argv: &[&str] = &[
|
|||
"acmed",
|
|||
"--pid-file",
|
|||
"/tmp/debug/acmed.pid",
|
|||
"--no-pid-file",
|
|||
];
|
|||
let pa = CliArgs::try_parse_from(argv);
|
|||
assert!(pa.is_err());
|
|||
}
|
|||
}
|
@ -0,0 +1,30 @@ |
|||
use clap::ValueEnum;
|
|||
use tracing_subscriber::FmtSubscriber;
|
|||
|
|||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
|
|||
pub enum Level {
|
|||
Error,
|
|||
Warn,
|
|||
Info,
|
|||
Debug,
|
|||
Trace,
|
|||
}
|
|||
|
|||
impl Level {
|
|||
fn tracing(&self) -> tracing::Level {
|
|||
match self {
|
|||
Self::Error => tracing::Level::ERROR,
|
|||
Self::Warn => tracing::Level::WARN,
|
|||
Self::Info => tracing::Level::INFO,
|
|||
Self::Debug => tracing::Level::DEBUG,
|
|||
Self::Trace => tracing::Level::TRACE,
|
|||
}
|
|||
}
|
|||
}
|
|||
|
|||
pub fn init(level: Level, is_syslog: bool) {
|
|||
let subscriber = FmtSubscriber::builder()
|
|||
.with_max_level(level.tracing())
|
|||
.finish();
|
|||
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
|
|||
}
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue