diff --git a/.gitignore b/.gitignore index 04a070b..060076d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ target/ venv/ .idea/ .vscode/ -config.json +api-key.json diff --git a/config.json b/config.json new file mode 100644 index 0000000..4951766 --- /dev/null +++ b/config.json @@ -0,0 +1,50 @@ +{ + "ipv6_interface": ":da5e:d3ff:feeb:4346", + "zones": [ + { + "email": "neshura@proton.me", + "name": "neshura.net", + "id": "0183f167a051f1e432c0d931478638b5", + "dns_entries": [ + { + "name": "*.neshura.net", + "type4": true, + "type6": true, + "interface": ":da5e:d3ff:feeb:4346" + }, + { + "name": "neshura.net", + "type4": true, + "type6": true, + "interface": ":da5e:d3ff:feeb:4346" + }, + { + "name": "test.neshura.net", + "type4": false, + "type6": true, + "interface": ":da5e:d3ff:feeb:4346" + }, + { + "name": "test2.neshura.net", + "type4": true, + "type6": false, + "interface": ":da5e:d3ff:feeb:4346" + } + ] + }, + { + "email": "neshura@proton.me", + "name": "neshura-server.net", + "id": "146d4cd6a1777376b423aaedc6824818", + "dns_entries": [ + ] + }, + { + "email": "neshura@proton.me", + "name": "neshweb.net", + "id": "75b0d52229357478b734ae0f6d075c15", + "dns_entries": [ + ] + } + ] +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 621e1ce..25a6627 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,18 @@ -use serde_derive::{Deserialize, Serialize}; use reqwest::blocking::get; +use serde_derive::{Deserialize, Serialize}; use std::{fs, process::exit}; mod cloudflare; +fn default_key() -> String { + return "".to_string(); +} + #[derive(Serialize, Deserialize)] struct DnsEntry { name: String, type4: bool, type6: bool, - interface: Option + interface: Option, } #[derive(Serialize, Deserialize)] @@ -16,47 +20,60 @@ struct DnsZone { email: String, name: String, id: String, - dns_entries: Vec + dns_entries: Vec, } #[derive(Serialize, Deserialize)] struct DnsConfig { ipv6_interface: String, + #[serde(default = "default_key")] api_key: String, - zones: Vec + zones: Vec, } impl DnsConfig { fn new() -> DnsConfig { - DnsConfig { - ipv6_interface: "".to_string(), + DnsConfig { + ipv6_interface: "".to_string(), api_key: "".to_string(), - zones: Vec::new() } + zones: Vec::new(), + } } fn load(&mut self) { let file_contents = match fs::read_to_string("config.json") { - Ok(data) => {data}, - Err(e) => panic!("{:#?}", e) + Ok(data) => data, + Err(e) => panic!("{:#?}", e), }; - let config_parse: DnsConfig = match serde_json::from_str(&file_contents) { - Ok(data) => {data}, - Err(e) => panic!("{:#?}", e) + let config_parse: DnsConfig = match serde_json::from_str(&file_contents) { + Ok(data) => data, + Err(e) => panic!("{:#?}", e), }; + + let key_file_contents = match fs::read_to_string("api-key.json") { + Ok(data) => data, + Err(e) => panic!("{:#?}", e), + }; + let api_key_parse: serde_json::Value = match serde_json::from_str(&key_file_contents) { + Ok(data) => data, + Err(e) => panic!("{:#?}", e), + }; + *self = config_parse; + self.api_key = api_key_parse["api_key"].as_str().unwrap().to_owned(); } } struct Ips { ipv4: String, - ipv6base: String + ipv6base: String, } impl Ips { fn new() -> Ips { - Ips { - ipv4: "0.0.0.0".to_string(), - ipv6base: ":".to_string() + Ips { + ipv4: "0.0.0.0".to_string(), + ipv6base: ":".to_string(), } } @@ -65,7 +82,7 @@ impl Ips { let ipv6uri = "https://ipv6.am.i.mullvad.net/ip"; let response = get(ipv4uri); - + match response { Ok(data) => self.ipv4 = data.text().expect("0.0.0.0").trim_end().to_owned(), Err(e) => { @@ -80,11 +97,11 @@ impl Ips { Ok(data) => { let ipv6 = data.text().expect(":"); let stripped = match ipv6.strip_suffix(ipv6_interface) { - Some(string) => {string.to_string()}, - None => {":".to_string()} + Some(string) => string.to_string(), + None => ":".to_string(), }; self.ipv6base = stripped; - }, + } Err(e) => { println!("Could not fetch IP6, quitting"); exit(75); @@ -94,10 +111,11 @@ impl Ips { } fn main() { - let mut config = DnsConfig::new(); config.load(); + /* while (true) {} */ + let mut ips = Ips::new(); ips.get(&config.ipv6_interface); @@ -116,38 +134,42 @@ fn main() { 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 { updated4 += 1 } else { error4 += 1 } - } - else { + if success { + updated4 += 1 + } else { + error4 += 1 + } + } else { unchanged4 += 1; } } - if cloudflare_entry.r#type == cloudflare::CloudflareDnsType::AAAA && entry.type6 { + 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 { updated6 += 1 } else { error6 += 1 } - } - else { + if success { + updated6 += 1 + } else { + error6 += 1 + } + } else { unchanged6 += 1; } } - } //println!("{:#?}", entry.subdomain); // DEBUG @@ -155,16 +177,20 @@ fn main() { if !found4 && entry.type4 { let success = agent.create_entry(&zone.id, "A", &entry.name, &ips.ipv4); - if success { created4 += 1 }; + if success { + created4 += 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 { created6 += 1 }; + if success { + created6 += 1 + }; } } - + //println!("{:#?}", zone.domain); // DEBUG } println!("++++A Records+++"); @@ -177,5 +203,4 @@ fn main() { println!("{} updated", updated6); println!("{} unchanged", unchanged6); println!("{} errors", error6); - }