Merge pull request #3 from jcgruenhage/various-updates
Some features/fixes/updates
This commit is contained in:
commit
4cf30631b6
390
Cargo.lock
generated
390
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
16
Cargo.toml
16
Cargo.toml
|
@ -13,12 +13,14 @@ documentation = "https://github.com/zbrox/cloudflare-ddns"
|
|||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
quicli = "0.4"
|
||||
structopt = "0.3.12"
|
||||
quicli = "0.4.0"
|
||||
structopt = "0.3.13"
|
||||
reqwest= { version = "0.10.4", features = ["blocking", "json"] }
|
||||
serde = "1.0.105"
|
||||
serde_json = "1.0.48"
|
||||
serde = "1.0.106"
|
||||
serde_json = "1.0.51"
|
||||
toml = "0.5.6"
|
||||
human-panic = "1.0.2"
|
||||
serde_derive = "1.0.105"
|
||||
anyhow = "1.0.27"
|
||||
human-panic = "1.0.3"
|
||||
serde_derive = "1.0.106"
|
||||
anyhow = "1.0.28"
|
||||
env_logger = "0.7.1"
|
||||
log = "0.4.8"
|
||||
|
|
72
src/main.rs
72
src/main.rs
|
@ -11,8 +11,7 @@ use anyhow::{Context, Result};
|
|||
|
||||
#[derive(Deserialize)]
|
||||
struct Config {
|
||||
email: String,
|
||||
auth_key: String,
|
||||
api_token: String,
|
||||
zone: String,
|
||||
domain: String,
|
||||
}
|
||||
|
@ -20,17 +19,13 @@ struct Config {
|
|||
#[derive(Debug, StructOpt)]
|
||||
/// Inform Cloudflare's DDNS service of the current IP address for your domain
|
||||
struct Cli {
|
||||
/// Your TOML config file containing all the required options (email, auth_key, zone, domain) which you can use instead of passing the arguments to the command line
|
||||
/// Your TOML config file containing all the required options (api_token, zone, domain) which you can use instead of passing the arguments to the command line
|
||||
#[structopt(long = "config", short = "f")]
|
||||
config: Option<PathBuf>,
|
||||
|
||||
/// Your Cloudflare login email
|
||||
#[structopt(long = "email", short = "e", required_unless = "config")]
|
||||
email: Option<String>,
|
||||
|
||||
/// The auth key you need to generate in your Cloudflare profile
|
||||
#[structopt(long = "key", short = "k", required_unless = "config")]
|
||||
auth_key: Option<String>,
|
||||
/// The api token you need to generate in your Cloudflare profile
|
||||
#[structopt(long = "token", short = "t", required_unless = "config")]
|
||||
api_token: Option<String>,
|
||||
|
||||
/// The zone in which your domain is (usually that is your base domain name)
|
||||
#[structopt(long = "zone", short = "z", required_unless = "config")]
|
||||
|
@ -49,6 +44,8 @@ fn main() -> Result<()> {
|
|||
setup_panic!();
|
||||
let args = Cli::from_args();
|
||||
|
||||
env_logger::from_env(env_logger::Env::default().default_filter_or("info")).init();
|
||||
|
||||
let should_use_cache = args.cache.is_some();
|
||||
let cached_ip: Option<String> = match args.cache.clone() {
|
||||
Some(v) => {
|
||||
|
@ -63,12 +60,32 @@ fn main() -> Result<()> {
|
|||
|
||||
let current_ip = get_current_ip()?;
|
||||
if cached_ip.is_some() && current_ip == cached_ip.unwrap() {
|
||||
println!("IP is unchanged. Exiting...");
|
||||
log::info!("IP is unchanged. Exiting...");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let (api_token, zone, domain) = match args.config {
|
||||
Some(c) => {
|
||||
let config_str = read_file(&c)?;
|
||||
let config: Config = toml::from_str(&config_str)?;
|
||||
(config.api_token, config.zone, config.domain)
|
||||
}
|
||||
None => (
|
||||
args.api_token.expect("API token is not set"),
|
||||
args.zone.expect("Zone is not set"),
|
||||
args.domain.expect("Domain is not set"),
|
||||
),
|
||||
};
|
||||
|
||||
update(¤t_ip, &api_token, &zone, &domain)?;
|
||||
|
||||
log::info!(
|
||||
"Successfully updated the A record for {} to {}",
|
||||
&domain, ¤t_ip
|
||||
);
|
||||
|
||||
if should_use_cache {
|
||||
println!(
|
||||
log::info!(
|
||||
"Saving current IP {} to cache file {:?}...",
|
||||
¤t_ip,
|
||||
&args.cache.clone().unwrap()
|
||||
|
@ -76,47 +93,24 @@ fn main() -> Result<()> {
|
|||
write_file(&args.cache.unwrap(), ¤t_ip)?;
|
||||
}
|
||||
|
||||
let (email, auth_key, zone, domain) = match args.config {
|
||||
Some(c) => {
|
||||
let config_str = read_file(&c)?;
|
||||
let config: Config = toml::from_str(&config_str)?;
|
||||
(config.email, config.auth_key, config.zone, config.domain)
|
||||
}
|
||||
None => (
|
||||
args.email.expect("Email is not set"),
|
||||
args.auth_key.expect("Auth key is not set"),
|
||||
args.zone.expect("Zone is not set"),
|
||||
args.domain.expect("Domain is not set"),
|
||||
),
|
||||
};
|
||||
|
||||
update(¤t_ip, &email, &auth_key, &zone, &domain)?;
|
||||
|
||||
println!(
|
||||
"Successfully updated the A record for {} to {}",
|
||||
&domain, ¤t_ip
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update(
|
||||
current_ip: &str,
|
||||
email: &str,
|
||||
auth_key: &str,
|
||||
api_token: &str,
|
||||
zone: &str,
|
||||
domain: &str,
|
||||
) -> Result<()> {
|
||||
let zone_id = get_zone_identifier(&zone, &email, &auth_key).context("Error getting the zone identifier")?;
|
||||
let record_id = get_dns_record_id(&zone_id, &domain, &email, &auth_key).context("Error getting the DNS record ID")?;
|
||||
let zone_id = get_zone_identifier(&zone, &api_token).context("Error getting the zone identifier")?;
|
||||
let record_id = get_dns_record_id(&zone_id, &domain, &api_token).context("Error getting the DNS record ID")?;
|
||||
|
||||
update_ddns(
|
||||
¤t_ip,
|
||||
&domain,
|
||||
&zone_id,
|
||||
&record_id,
|
||||
&email,
|
||||
&auth_key,
|
||||
&api_token,
|
||||
).context("Error updating the DNS record")?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -28,14 +28,13 @@ struct UpdateIpData {
|
|||
content: String,
|
||||
}
|
||||
|
||||
pub fn get_zone_identifier(zone: &str, email: &str, key: &str) -> anyhow::Result<String> {
|
||||
pub fn get_zone_identifier(zone: &str, api_token: &str) -> anyhow::Result<String> {
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let url = format!("https://api.cloudflare.com/client/v4/zones?name={}", zone);
|
||||
|
||||
let response = client
|
||||
.get(&url)
|
||||
.header("X-Auth-Email", email)
|
||||
.header("X-Auth-Key", key)
|
||||
.header("Authorization", format!("Bearer {}", api_token))
|
||||
.header("Content-Type", "application/json")
|
||||
.send()?;
|
||||
|
||||
|
@ -68,8 +67,7 @@ pub fn get_zone_identifier(zone: &str, email: &str, key: &str) -> anyhow::Result
|
|||
pub fn get_dns_record_id(
|
||||
zone_id: &str,
|
||||
domain: &str,
|
||||
email: &str,
|
||||
key: &str,
|
||||
api_token: &str,
|
||||
) -> anyhow::Result<String> {
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let url = format!(
|
||||
|
@ -79,8 +77,7 @@ pub fn get_dns_record_id(
|
|||
|
||||
let response = client
|
||||
.get(&url)
|
||||
.header("X-Auth-Email", email)
|
||||
.header("X-Auth-Key", key)
|
||||
.header("Authorization", format!("Bearer {}", api_token))
|
||||
.header("Content-Type", "application/json")
|
||||
.send()?;
|
||||
|
||||
|
@ -132,8 +129,7 @@ pub fn update_ddns(
|
|||
domain: &str,
|
||||
zone_id: &str,
|
||||
record_id: &str,
|
||||
email: &str,
|
||||
key: &str,
|
||||
api_token: &str,
|
||||
) -> anyhow::Result<()> {
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let url = format!(
|
||||
|
@ -150,8 +146,7 @@ pub fn update_ddns(
|
|||
|
||||
let response = client
|
||||
.put(&url)
|
||||
.header("X-Auth-Email", email)
|
||||
.header("X-Auth-Key", key)
|
||||
.header("Authorization", format!("Bearer {}", api_token))
|
||||
.header("Content-Type", "application/json")
|
||||
.json(&update_data)
|
||||
.send()?;
|
||||
|
|
Loading…
Reference in a new issue