feat: add -v verbosity flag

This commit is contained in:
Jalil David Salamé Messina 2024-10-26 13:23:22 +02:00
parent 51f557c482
commit 442601f25a
Signed by: jalil
GPG key ID: F016B9E770737A0B
3 changed files with 50 additions and 14 deletions

13
Cargo.lock generated
View file

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "addr2line" name = "addr2line"
@ -237,6 +237,16 @@ dependencies = [
"clap_derive", "clap_derive",
] ]
[[package]]
name = "clap-verbosity-flag"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e099138e1807662ff75e2cebe4ae2287add879245574489f9b1588eb5e5564ed"
dependencies = [
"clap",
"log",
]
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.20" version = "4.5.20"
@ -1159,6 +1169,7 @@ dependencies = [
"axum-client-ip", "axum-client-ip",
"base64 0.22.1", "base64 0.22.1",
"clap", "clap",
"clap-verbosity-flag",
"http", "http",
"insta", "insta",
"miette", "miette",

View file

@ -7,27 +7,28 @@ version = "0.3.0-dev"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
axum = "0.7.7" axum = "0.7"
axum-auth = { version = "0.7.0", default-features = false, features = [ axum-auth = { version = "0.7", default-features = false, features = [
"auth-basic", "auth-basic",
] } ] }
axum-client-ip = "0.6.1" axum-client-ip = "0.6"
base64 = "0.22.1" base64 = "0.22"
clap = { version = "4.5.20", features = ["derive", "env"] } clap = { version = "4", features = ["derive", "env"] }
http = "1.1.0" clap-verbosity-flag = "2"
miette = { version = "7.2.0", features = ["fancy"] } http = "1"
ring = { version = "0.17.8", features = ["std"] } miette = { version = "7", features = ["fancy"] }
tokio = { version = "1.40.0", features = [ ring = { version = "0.17", features = ["std"] }
tokio = { version = "1", features = [
"macros", "macros",
"rt", "rt",
"process", "process",
"io-util", "io-util",
] } ] }
tracing = "0.1.40" tracing = "0.1"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] }
[dev-dependencies] [dev-dependencies]
insta = "1.40.0" insta = "1"
[profile.dev] [profile.dev]
debug = 0 debug = 0

View file

@ -12,6 +12,7 @@ use axum_auth::AuthBasic;
use axum_client_ip::{SecureClientIp, SecureClientIpSource}; use axum_client_ip::{SecureClientIp, SecureClientIpSource};
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine}; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use clap_verbosity_flag::Verbosity;
use http::StatusCode; use http::StatusCode;
use miette::{bail, ensure, Context, IntoDiagnostic, Result}; use miette::{bail, ensure, Context, IntoDiagnostic, Result};
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
@ -26,6 +27,9 @@ const DEFAULT_SALT: &str = "UpdateMyDNS";
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
struct Opts { struct Opts {
#[command(flatten)]
verbosity: Verbosity,
/// Ip address of the server /// Ip address of the server
#[arg(long, default_value = "127.0.0.1")] #[arg(long, default_value = "127.0.0.1")]
address: IpAddr, address: IpAddr,
@ -121,6 +125,7 @@ struct AppState<'a> {
} }
fn load_ip(path: &Path) -> Result<Option<IpAddr>> { fn load_ip(path: &Path) -> Result<Option<IpAddr>> {
debug!("loading last IP from {}", path.display());
let data = match std::fs::read_to_string(path) { let data = match std::fs::read_to_string(path) {
Ok(ip) => ip, Ok(ip) => ip,
Err(err) => { Err(err) => {
@ -146,13 +151,28 @@ fn main() -> Result<()> {
// parse cli arguments // parse cli arguments
let mut args = Opts::parse(); let mut args = Opts::parse();
debug!("{args:?}");
// configure logger // configure logger
let subscriber = tracing_subscriber::FmtSubscriber::builder() let subscriber = tracing_subscriber::FmtSubscriber::builder()
.without_time() .without_time()
.with_env_filter( .with_env_filter(
EnvFilter::builder() EnvFilter::builder()
.with_default_directive(LevelFilter::WARN.into()) .with_default_directive(
if args.verbosity.is_present() {
match args.verbosity.log_level_filter() {
clap_verbosity_flag::LevelFilter::Off => LevelFilter::OFF,
clap_verbosity_flag::LevelFilter::Error => LevelFilter::ERROR,
clap_verbosity_flag::LevelFilter::Warn => LevelFilter::WARN,
clap_verbosity_flag::LevelFilter::Info => LevelFilter::INFO,
clap_verbosity_flag::LevelFilter::Debug => LevelFilter::DEBUG,
clap_verbosity_flag::LevelFilter::Trace => LevelFilter::TRACE,
}
} else {
LevelFilter::WARN
}
.into(),
)
.from_env_lossy(), .from_env_lossy(),
) )
.finish(); .finish();
@ -166,6 +186,7 @@ fn main() -> Result<()> {
} }
let Opts { let Opts {
verbosity: _,
address: ip, address: ip,
port, port,
password_file, password_file,
@ -287,6 +308,7 @@ async fn update_records(
AuthBasic((username, pass)): AuthBasic, AuthBasic((username, pass)): AuthBasic,
SecureClientIp(ip): SecureClientIp, SecureClientIp(ip): SecureClientIp,
) -> axum::response::Result<&'static str> { ) -> axum::response::Result<&'static str> {
debug!("received update request from {ip}");
let Some(pass) = pass else { let Some(pass) = pass else {
return Err((StatusCode::UNAUTHORIZED, Json::from("no password provided")).into()); return Err((StatusCode::UNAUTHORIZED, Json::from("no password provided")).into());
}; };
@ -309,9 +331,11 @@ async fn update_records(
match nsupdate(ip, state.ttl, state.key_file, state.records).await { match nsupdate(ip, state.ttl, state.key_file, state.records).await {
Ok(status) if status.success() => { Ok(status) if status.success() => {
tokio::task::spawn_blocking(move || { tokio::task::spawn_blocking(move || {
info!("updating last ip to {ip}");
if let Err(err) = std::fs::write(state.ip_file, format!("{ip}")) { if let Err(err) = std::fs::write(state.ip_file, format!("{ip}")) {
error!("Failed to update last IP: {err}"); error!("Failed to update last IP: {err}");
} }
info!("updated last ip to {ip}");
}); });
Ok("successful update") Ok("successful update")
} }