Updated dependencies. Added sample config. Tried improving some stuff

This commit is contained in:
Vegard Berg 2023-06-07 21:45:21 +02:00
parent 85c4b0e847
commit f810677a43
6 changed files with 593 additions and 133 deletions

634
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -2,20 +2,21 @@
name = "gandi-dns-updater" name = "gandi-dns-updater"
version = "0.1.0" version = "0.1.0"
authors = ["Vegard Berg <vgberg@gmail.com>"] authors = ["Vegard Berg <vgberg@gmail.com>"]
edition = "2018" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
anyhow = "1.0.40" anyhow = "1.0.71"
dirs = "3.0.2" clap = { version = "4.3.2", features = ["derive"] }
nix = "0.20.0" dirs = "5.0.1"
serde = {version = "1.0.126", features = ["derive"]} nix = "0.26.2"
serde_json = "1.0.64" serde = {version = "1.0.163", features = ["derive"]}
toml = "0.5.8" serde_json = "1.0.96"
trust-dns-resolver = "0.20.3" toml = "0.7.4"
ureq = {version = "2.1.1", features = ["json"]} trust-dns-resolver = "0.22.0"
xdg = "2.2.0" ureq = {version = "2.6.2", features = ["json", "tls"]}
xdg = "2.5.0"
[profile.release] [profile.release]
opt-level = 'z' opt-level = 'z'

View File

@ -1,6 +0,0 @@
api_key = "YOUR API KEY"
[[domain]]
name = "YOUR DOMAIN"
subdomains = ["@", "foo", "bar"]

11
config.sample.toml Normal file
View File

@ -0,0 +1,11 @@
# api_key = "MY API KEY"
#
# [[domain]]
# name = "mydomain.com"
# subdomains = ["www", "ftp"]
# update_A = true # Update IPv4 A record
# update_AAAA = false # Update IPv6 AAAA record
#
# [[domain]]
# name = "example.com"
# subdomains = ["@", "www"]

View File

@ -1,5 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
const SAMPLE_CONFIG: &str = include_str!("../config.sample.toml");
#[derive(Debug, Serialize, Deserialize, std::cmp::PartialEq)] #[derive(Debug, Serialize, Deserialize, std::cmp::PartialEq)]
pub struct Configuration { pub struct Configuration {
pub api_key: String, pub api_key: String,
@ -30,28 +32,43 @@ fn bool_true() -> bool {
} }
impl Configuration { impl Configuration {
pub fn read_config() -> anyhow::Result<Configuration> { /// Read the configuration file from the default configuration directory.
pub fn read_config(config_path: Option<&str>) -> anyhow::Result<Configuration> {
use dirs::config_dir; use dirs::config_dir;
let conf_dir = { let conf_dir = 'conf: {
// Get the user's config dir if it is not a system user. if let Some(path) = config_path {
// If config path is explicitly passed, use it instead
break 'conf std::path::PathBuf::from(path)
}
// If running on Linux, try to get the user dir if UID >= 1000.
// Assume that it is a system/service user otherwise, and look for the
// global config file.
#[cfg(target_os = "linux")]
if nix::unistd::getuid().as_raw() as u32 >= 1000 { if nix::unistd::getuid().as_raw() as u32 >= 1000 {
config_dir() config_dir()
.expect("Failed to get the user's config dir") .expect("Expected config dir")
.join("gandi-dns") .join("gandi-dns")
} else { } else {
std::path::PathBuf::from("/etc/gandi-dns") std::path::PathBuf::from("/etc/gandi-dns")
} }
// If it is not a Linux system, just look for the user directory...
#[cfg(not(target_os = "linux"))]
config_dir()
.expect("Expected config dir")
.join("gandi-dns")
}; };
std::fs::create_dir_all(&conf_dir).expect("Failed to create config directory"); std::fs::create_dir_all(&conf_dir).expect("Failed to create config directory");
let config_str = std::fs::read_to_string(conf_dir.join("config.toml")).expect(&format!( let config_str = std::fs::read_to_string(conf_dir.join("config.toml"))?;
"Could not read config file at: {}",
conf_dir.join("config.toml").to_string_lossy()
));
let c: Configuration = toml::from_str(&config_str)?; let c: Configuration = toml::from_str(&config_str)?;
Ok(c) Ok(c)
} }
} }
pub fn print_config() {
println!("{}", SAMPLE_CONFIG);
}

View File

@ -2,8 +2,25 @@ mod config;
mod dns; mod dns;
mod gandi; mod gandi;
use clap::Parser;
#[derive(Debug, Parser)]
#[command(author, version, about)]
struct Args {
#[arg(short, long)]
config: Option<String>,
#[arg(long)]
print_template_config: bool,
}
fn main() -> anyhow::Result<()> { fn main() -> anyhow::Result<()> {
let conf: config::Configuration = config::Configuration::read_config()?; let args = Args::parse();
if args.print_template_config {
config::print_config();
return Ok(());
}
let conf: config::Configuration = config::Configuration::read_config(args.config.as_deref())?;
let (ip4, ip6) = dns::get_ext_ip()?; let (ip4, ip6) = dns::get_ext_ip()?;