From 4525eb1974d5fcdb46e302aca833858ed6ab2334 Mon Sep 17 00:00:00 2001 From: Neshura Date: Mon, 27 Feb 2023 15:56:24 +0100 Subject: [PATCH] Split up update function into smaller class functions --- src/main.rs | 192 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 111 insertions(+), 81 deletions(-) diff --git a/src/main.rs b/src/main.rs index 958a6df..9d1257c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,15 @@ +use cloudflare::{Instance, CloudflareDnsType}; use reqwest::blocking::get; use serde_derive::{Deserialize, Serialize}; -use std::{fs, process::exit, thread::{sleep}}; -use chrono::{Utc, Duration, Date}; +use std::{fs, thread::{sleep}}; +use chrono::{Utc, Duration}; mod cloudflare; fn default_key() -> String { return "".to_string(); } +#[derive(Clone)] struct ChangeTracker { created: u16, updated: u16, @@ -52,6 +54,76 @@ struct DnsEntry { interface: Option, } +impl DnsEntry { + fn update(&self, change4: &mut ChangeTracker, change6: &mut ChangeTracker, agent: &Instance, ips: &Ips) { + let mut found4 = false; + let mut found6 = false; + + for cloudflare_entry in &agent.dns_entries { + + // Update IPv4 Entry + if cloudflare_entry.is_equal(&self.name) { + found4 = true; + if cloudflare_entry.r#type == CloudflareDnsType::A && self.type4 { + let success = agent.update_entry(cloudflare_entry, &ips.ipv4); + if success { + change4.updated += 1; + } + else { + change4.error += 1; + } + } + else { + change4.unchanged += 1; + } + } + // Update IPv6 Entry + else if cloudflare_entry.r#type == CloudflareDnsType::AAAA && self.type6 { + found6 = true; + let ipv6 = ips.ipv6base.clone() + self.interface.as_ref().unwrap(); + + if cloudflare_entry.is_ip_new(&ipv6) { + let success = agent.update_entry(cloudflare_entry, &ipv6); + if success { + change6.updated += 1 + } + else { + change6.error += 1 + } + } + else { + change6.unchanged += 1; + } + } + // ignore otherwise + else { + + } + + if !found4 && self.type4 { + let success = agent.create_entry(&cloudflare_entry.zone_id, "A", &self.name, &ips.ipv4); + if success { + change4.created += 1; + } + else { + change4.error += 1; + }; + } + + if !found6 && self.type6 { + let ipv6 = ips.ipv6base.clone() + self.interface.as_ref().unwrap(); + let success = agent.create_entry(&cloudflare_entry.zone_id, "AAAA", &self.name, &ipv6); + if success { + change6.created += 1; + } + else { + change6.error += 1; + }; + } + } + } +} + #[derive(Serialize, Deserialize)] struct DnsZone { email: String, @@ -60,6 +132,18 @@ struct DnsZone { dns_entries: Vec, } +impl DnsZone { + fn update(&self, change4: &mut ChangeTracker, change6: &mut ChangeTracker, ips: &Ips, config: &DnsConfig ) { + let mut agent = Instance::new(&config.api_key); + + agent.load_entries(&self.email, &self.id); + + for entry in &self.dns_entries { + entry.update(change4, change6, &agent, &ips); + } + } +} + #[derive(Serialize, Deserialize)] struct DnsConfig { ipv6_interface: String, @@ -114,17 +198,21 @@ impl Ips { } } - fn get(&mut self, ipv6_interface: &str) { + fn get(&mut self, ipv6_interface: &str) -> bool { let ipv4uri = "https://am.i.mullvad.net/ip"; let ipv6uri = "https://ipv6.am.i.mullvad.net/ip"; + let mut ret; let response = get(ipv4uri); match response { - Ok(data) => self.ipv4 = data.text().expect("0.0.0.0").trim_end().to_owned(), - Err(e) => { - println!("Could not fetch IPv4, quitting"); - exit(75); + Ok(data) => { + self.ipv4 = data.text().expect("0.0.0.0").trim_end().to_owned(); + ret = true; + }, + Err(_e) => { + println!("Could not fetch IPv4"); + ret = false; } } @@ -141,12 +229,15 @@ impl Ips { None => ":".to_string(), }; self.ipv6base = stripped; + ret = true && ret; // Only set ret to true if previous ret is also true } - Err(e) => { - println!("Could not fetch IPv6, quitting"); - exit(75); + Err(_e) => { + println!("Could not fetch IPv6"); + ret = false; } } + + return ret; } } @@ -154,83 +245,22 @@ fn update_dns() { let mut config = DnsConfig::new(); config.load(); - /* while (true) {} */ - let mut ips = Ips::new(); - ips.get(&config.ipv6_interface); + if ips.get(&config.ipv6_interface) { + let mut change4 = ChangeTracker::new(); - let mut change4 = ChangeTracker::new(); + let mut change6 = ChangeTracker::new(); - let mut change6 = ChangeTracker::new(); - - for zone in config.zones { - let mut agent = cloudflare::Instance::new(&config.api_key); - - agent.load_entries(&zone.email, &zone.id); - - for entry in zone.dns_entries { - let mut found4 = false; - let mut found6 = false; - - for cloudflare_entry in &agent.dns_entries { - if cloudflare_entry.is_equal(&entry.name) { - if cloudflare_entry.r#type == cloudflare::CloudflareDnsType::A && entry.type4 { - found4 = true; - if cloudflare_entry.is_ip_new(&ips.ipv4) { - let success = agent.update_entry(cloudflare_entry, &ips.ipv4); - if success { - change4.updated += 1 - } else { - change4.error += 1 - } - } else { - change4.unchanged += 1; - } - } - - if cloudflare_entry.r#type == cloudflare::CloudflareDnsType::AAAA && entry.type6 - { - found6 = true; - let ipv6 = ips.ipv6base.clone() + entry.interface.as_ref().unwrap(); - - if cloudflare_entry.is_ip_new(&ipv6) { - let success = agent.update_entry(cloudflare_entry, &ipv6); - if success { - change6.updated += 1 - } else { - change6.error += 1 - } - } else { - change6.unchanged += 1; - } - } - } - - //println!("{:#?}", entry.subdomain); // DEBUG - } - - if !found4 && entry.type4 { - let success = agent.create_entry(&zone.id, "A", &entry.name, &ips.ipv4); - if success { - change4.created += 1 - }; - } - - if !found6 && entry.type6 { - let ipv6 = ips.ipv6base.clone() + entry.interface.as_ref().unwrap(); - let success = agent.create_entry(&zone.id, "AAAA", &entry.name, &ipv6); - if success { - change6.created += 1 - }; - } + // Iterator does not work here + for zone in &config.zones { + zone.update(&mut change4, &mut change6, &ips, &config) } - //println!("{:#?}", zone.domain); // DEBUG + println!("++++A Records+++"); + change4.print("simple"); + println!("++AAAA Records++"); + change6.print("simple") } - println!("++++A Records+++"); - change4.print("simple"); - println!("++AAAA Records++"); - change6.print("simple") } fn main() {