Split up update function into smaller class functions

This commit is contained in:
Neshura 2023-02-27 15:56:24 +01:00
parent fdf2f53e8b
commit 4525eb1974
No known key found for this signature in database
GPG key ID: ACDF5B6EBECF6B0A

View file

@ -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<String>,
}
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<DnsEntry>,
}
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 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;
}
// Iterator does not work here
for zone in &config.zones {
zone.update(&mut change4, &mut change6, &ips, &config)
}
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
};
}
}
//println!("{:#?}", zone.domain); // DEBUG
}
println!("++++A Records+++");
change4.print("simple");
println!("++AAAA Records++");
change6.print("simple")
}
}
fn main() {