diff --git a/Cargo.lock b/Cargo.lock index c8aba53..fa5b045 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -211,7 +211,7 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "dreamhost-ddns" -version = "0.2.0" +version = "0.2.1" dependencies = [ "anyhow", "clap", diff --git a/Cargo.toml b/Cargo.toml index 05edfb4..17e5026 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dreamhost-ddns" -version = "0.2.0" +version = "0.2.1" edition = "2021" [dependencies] diff --git a/binaries/linux-aarch64/dreamhost-ddns b/binaries/linux-aarch64/dreamhost-ddns index e47dfc8..93a4600 100644 Binary files a/binaries/linux-aarch64/dreamhost-ddns and b/binaries/linux-aarch64/dreamhost-ddns differ diff --git a/binaries/linux-rpi-armv7/dreamhost-ddns b/binaries/linux-rpi-armv7/dreamhost-ddns index 5ddde79..f68169e 100644 Binary files a/binaries/linux-rpi-armv7/dreamhost-ddns and b/binaries/linux-rpi-armv7/dreamhost-ddns differ diff --git a/binaries/linux-x86_64/dreamhost-ddns b/binaries/linux-x86_64/dreamhost-ddns index b636252..deee3f8 100644 Binary files a/binaries/linux-x86_64/dreamhost-ddns and b/binaries/linux-x86_64/dreamhost-ddns differ diff --git a/binaries/windows/dreamhost-ddns.exe b/binaries/windows/dreamhost-ddns.exe index 5bcc023..e2f7d87 100644 Binary files a/binaries/windows/dreamhost-ddns.exe and b/binaries/windows/dreamhost-ddns.exe differ diff --git a/src/main.rs b/src/main.rs index 494d7d4..932cdb4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -120,6 +120,32 @@ impl DreamhostClient { .ok_or_else(|| anyhow!("DreamHost error: DNS record '{}' not found", record_name)) } + fn list_records(&self) -> Result> { + + let resp = self.call(&[ + ("cmd", "dns-list_records"), + ])?; + + let records: Vec = serde_json::from_value(resp["data"].clone())?; + + Ok(records) + } + + fn record_exists( + &self, + record_name: &str, + ip: &str, + ) -> Result { + + let records = self.list_records()?; + + Ok(records.iter().any(|r| + r.record == record_name && + r.record_type == "A" && + r.value == ip + )) + } + fn update_dns(&self, record: &str, old_ip: &str, new_ip: &str) -> Result<()> { info!("Adding new DNS record {} -> {}", record, new_ip); @@ -134,6 +160,23 @@ impl DreamhostClient { info!("Waiting briefly for DNS propagation..."); std::thread::sleep(std::time::Duration::from_secs(3)); + for attempt in 1..=5 { + + if self.record_exists(record, new_ip)? { + info!("New DNS record verified"); + break; + } + + warn!("New record not visible yet (attempt {})", attempt); + std::thread::sleep(std::time::Duration::from_secs(2)); + + if attempt == 5 { + return Err(anyhow!( + "New DNS record never appeared; refusing to remove old record" + )); + } + } + info!("Removing old DNS record {} -> {}", record, old_ip); self.call(&[ @@ -145,6 +188,7 @@ impl DreamhostClient { Ok(()) } + } fn main() -> Result<()> {