Rewrite in Rust
This commit is contained in:
parent
331f0c092c
commit
e76c82492f
5 changed files with 1402 additions and 0 deletions
src
175
src/main.rs
Normal file
175
src/main.rs
Normal file
|
@ -0,0 +1,175 @@
|
|||
use serde_derive::{Deserialize, Serialize};
|
||||
use reqwest::blocking::get;
|
||||
use std::fs;
|
||||
mod cloudflare;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct DnsEntry {
|
||||
name: String,
|
||||
type4: bool,
|
||||
type6: bool,
|
||||
interface: Option<String>
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct DnsZone {
|
||||
email: String,
|
||||
name: String,
|
||||
id: String,
|
||||
dns_entries: Vec<DnsEntry>
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct DnsConfig {
|
||||
ipv6_interface: String,
|
||||
api_key: String,
|
||||
zones: Vec<DnsZone>
|
||||
}
|
||||
|
||||
impl DnsConfig {
|
||||
fn new() -> DnsConfig {
|
||||
DnsConfig {
|
||||
ipv6_interface: "".to_string(),
|
||||
api_key: "".to_string(),
|
||||
zones: Vec::new() }
|
||||
}
|
||||
|
||||
fn load(&mut self) {
|
||||
let file_contents = match fs::read_to_string("config.json") {
|
||||
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)
|
||||
};
|
||||
*self = config_parse;
|
||||
}
|
||||
}
|
||||
|
||||
struct Ips {
|
||||
ipv4: String,
|
||||
ipv6base: String
|
||||
}
|
||||
|
||||
impl Ips {
|
||||
fn new() -> Ips {
|
||||
Ips {
|
||||
ipv4: "0.0.0.0".to_string(),
|
||||
ipv6base: ":".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn get(&mut self, ipv6_interface: &str) {
|
||||
let ipv4uri = "https://am.i.mullvad.net/ip";
|
||||
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) => panic!("{:#?}", e)
|
||||
}
|
||||
|
||||
let response = get(ipv6uri);
|
||||
|
||||
match response {
|
||||
Ok(data) => {
|
||||
let ipv6 = data.text().expect(":");
|
||||
let stripped = match ipv6.strip_suffix(ipv6_interface) {
|
||||
Some(string) => {string.to_string()},
|
||||
None => {":".to_string()}
|
||||
};
|
||||
self.ipv6base = stripped;
|
||||
},
|
||||
Err(e) => panic!("{:#?}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
let mut config = DnsConfig::new();
|
||||
config.load();
|
||||
|
||||
let mut ips = Ips::new();
|
||||
ips.get(&config.ipv6_interface);
|
||||
|
||||
let mut created4: u16 = 0;
|
||||
let mut updated4: u16 = 0;
|
||||
let mut unchanged4: u16 = 0;
|
||||
let mut error4: u16 = 0;
|
||||
|
||||
let mut created6: u16 = 0;
|
||||
let mut updated6: u16 = 0;
|
||||
let mut unchanged6: u16 = 0;
|
||||
let mut error6: u16 = 0;
|
||||
|
||||
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 { updated4 += 1 } else { error4 += 1 }
|
||||
}
|
||||
else {
|
||||
unchanged4 += 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 { updated6 += 1 } else { error6 += 1 }
|
||||
}
|
||||
else {
|
||||
unchanged6 += 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//println!("{:#?}", entry.subdomain); // DEBUG
|
||||
}
|
||||
|
||||
if !found4 && entry.type4 {
|
||||
let success = agent.create_entry(&zone.id, "A", &entry.name, &ips.ipv4);
|
||||
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 };
|
||||
}
|
||||
}
|
||||
|
||||
//println!("{:#?}", zone.domain); // DEBUG
|
||||
}
|
||||
println!("++++A Records+++");
|
||||
println!("{} created", created4);
|
||||
println!("{} updated", updated4);
|
||||
println!("{} unchanged", unchanged4);
|
||||
println!("{} errors", error4);
|
||||
println!("++AAAA Records++");
|
||||
println!("{} created", created6);
|
||||
println!("{} updated", updated6);
|
||||
println!("{} unchanged", unchanged6);
|
||||
println!("{} errors", error6);
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue