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"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
quicli = "0.4"
|
quicli = "0.4.0"
|
||||||
structopt = "0.3.12"
|
structopt = "0.3.13"
|
||||||
reqwest= { version = "0.10.4", features = ["blocking", "json"] }
|
reqwest= { version = "0.10.4", features = ["blocking", "json"] }
|
||||||
serde = "1.0.105"
|
serde = "1.0.106"
|
||||||
serde_json = "1.0.48"
|
serde_json = "1.0.51"
|
||||||
toml = "0.5.6"
|
toml = "0.5.6"
|
||||||
human-panic = "1.0.2"
|
human-panic = "1.0.3"
|
||||||
serde_derive = "1.0.105"
|
serde_derive = "1.0.106"
|
||||||
anyhow = "1.0.27"
|
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)]
|
#[derive(Deserialize)]
|
||||||
struct Config {
|
struct Config {
|
||||||
email: String,
|
api_token: String,
|
||||||
auth_key: String,
|
|
||||||
zone: String,
|
zone: String,
|
||||||
domain: String,
|
domain: String,
|
||||||
}
|
}
|
||||||
|
@ -20,17 +19,13 @@ struct Config {
|
||||||
#[derive(Debug, StructOpt)]
|
#[derive(Debug, StructOpt)]
|
||||||
/// Inform Cloudflare's DDNS service of the current IP address for your domain
|
/// Inform Cloudflare's DDNS service of the current IP address for your domain
|
||||||
struct Cli {
|
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")]
|
#[structopt(long = "config", short = "f")]
|
||||||
config: Option<PathBuf>,
|
config: Option<PathBuf>,
|
||||||
|
|
||||||
/// Your Cloudflare login email
|
/// The api token you need to generate in your Cloudflare profile
|
||||||
#[structopt(long = "email", short = "e", required_unless = "config")]
|
#[structopt(long = "token", short = "t", required_unless = "config")]
|
||||||
email: Option<String>,
|
api_token: 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 zone in which your domain is (usually that is your base domain name)
|
/// The zone in which your domain is (usually that is your base domain name)
|
||||||
#[structopt(long = "zone", short = "z", required_unless = "config")]
|
#[structopt(long = "zone", short = "z", required_unless = "config")]
|
||||||
|
@ -49,6 +44,8 @@ fn main() -> Result<()> {
|
||||||
setup_panic!();
|
setup_panic!();
|
||||||
let args = Cli::from_args();
|
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 should_use_cache = args.cache.is_some();
|
||||||
let cached_ip: Option<String> = match args.cache.clone() {
|
let cached_ip: Option<String> = match args.cache.clone() {
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
|
@ -63,12 +60,32 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
let current_ip = get_current_ip()?;
|
let current_ip = get_current_ip()?;
|
||||||
if cached_ip.is_some() && current_ip == cached_ip.unwrap() {
|
if cached_ip.is_some() && current_ip == cached_ip.unwrap() {
|
||||||
println!("IP is unchanged. Exiting...");
|
log::info!("IP is unchanged. Exiting...");
|
||||||
return Ok(());
|
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 {
|
if should_use_cache {
|
||||||
println!(
|
log::info!(
|
||||||
"Saving current IP {} to cache file {:?}...",
|
"Saving current IP {} to cache file {:?}...",
|
||||||
¤t_ip,
|
¤t_ip,
|
||||||
&args.cache.clone().unwrap()
|
&args.cache.clone().unwrap()
|
||||||
|
@ -76,47 +93,24 @@ fn main() -> Result<()> {
|
||||||
write_file(&args.cache.unwrap(), ¤t_ip)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(
|
fn update(
|
||||||
current_ip: &str,
|
current_ip: &str,
|
||||||
email: &str,
|
api_token: &str,
|
||||||
auth_key: &str,
|
|
||||||
zone: &str,
|
zone: &str,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let zone_id = get_zone_identifier(&zone, &email, &auth_key).context("Error getting the zone identifier")?;
|
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, &email, &auth_key).context("Error getting the DNS record ID")?;
|
let record_id = get_dns_record_id(&zone_id, &domain, &api_token).context("Error getting the DNS record ID")?;
|
||||||
|
|
||||||
update_ddns(
|
update_ddns(
|
||||||
¤t_ip,
|
¤t_ip,
|
||||||
&domain,
|
&domain,
|
||||||
&zone_id,
|
&zone_id,
|
||||||
&record_id,
|
&record_id,
|
||||||
&email,
|
&api_token,
|
||||||
&auth_key,
|
|
||||||
).context("Error updating the DNS record")?;
|
).context("Error updating the DNS record")?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -28,14 +28,13 @@ struct UpdateIpData {
|
||||||
content: String,
|
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 client = reqwest::blocking::Client::new();
|
||||||
let url = format!("https://api.cloudflare.com/client/v4/zones?name={}", zone);
|
let url = format!("https://api.cloudflare.com/client/v4/zones?name={}", zone);
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.get(&url)
|
.get(&url)
|
||||||
.header("X-Auth-Email", email)
|
.header("Authorization", format!("Bearer {}", api_token))
|
||||||
.header("X-Auth-Key", key)
|
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.send()?;
|
.send()?;
|
||||||
|
|
||||||
|
@ -68,8 +67,7 @@ pub fn get_zone_identifier(zone: &str, email: &str, key: &str) -> anyhow::Result
|
||||||
pub fn get_dns_record_id(
|
pub fn get_dns_record_id(
|
||||||
zone_id: &str,
|
zone_id: &str,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
email: &str,
|
api_token: &str,
|
||||||
key: &str,
|
|
||||||
) -> anyhow::Result<String> {
|
) -> anyhow::Result<String> {
|
||||||
let client = reqwest::blocking::Client::new();
|
let client = reqwest::blocking::Client::new();
|
||||||
let url = format!(
|
let url = format!(
|
||||||
|
@ -79,8 +77,7 @@ pub fn get_dns_record_id(
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.get(&url)
|
.get(&url)
|
||||||
.header("X-Auth-Email", email)
|
.header("Authorization", format!("Bearer {}", api_token))
|
||||||
.header("X-Auth-Key", key)
|
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.send()?;
|
.send()?;
|
||||||
|
|
||||||
|
@ -132,8 +129,7 @@ pub fn update_ddns(
|
||||||
domain: &str,
|
domain: &str,
|
||||||
zone_id: &str,
|
zone_id: &str,
|
||||||
record_id: &str,
|
record_id: &str,
|
||||||
email: &str,
|
api_token: &str,
|
||||||
key: &str,
|
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let client = reqwest::blocking::Client::new();
|
let client = reqwest::blocking::Client::new();
|
||||||
let url = format!(
|
let url = format!(
|
||||||
|
@ -150,8 +146,7 @@ pub fn update_ddns(
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.put(&url)
|
.put(&url)
|
||||||
.header("X-Auth-Email", email)
|
.header("Authorization", format!("Bearer {}", api_token))
|
||||||
.header("X-Auth-Key", key)
|
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.json(&update_data)
|
.json(&update_data)
|
||||||
.send()?;
|
.send()?;
|
||||||
|
|
Loading…
Reference in a new issue