use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use porkbun_api::{transport::DefaultTransport, ApiKey, CreateOrEditDnsRecord, DnsRecordType};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let force_ipv4 = false;
let file = std::fs::File::open("secrets/api_key.json")?;
let api_key: ApiKey = serde_json::from_reader(file)?;
let client =
porkbun_api::Client::new_with_transport(api_key.clone(), DefaultTransport::new(force_ipv4));
let domain = "fckn.gay";
let subdomain = Some("laptop");
let fqdn = if let Some(subdomain) = subdomain {
format!("{subdomain}.{domain}")
} else {
domain.to_owned()
};
println!("setting up {fqdn}...");
let existing_entries = client.get_all(domain).await?;
let my_ip: IpAddr = IpAddr::V6(Ipv6Addr::LOCALHOST);
let new_entry = CreateOrEditDnsRecord::A_or_AAAA(subdomain, my_ip);
if let Some(existing) = existing_entries
.iter()
.find(|e| e.record_type == new_entry.record_type && e.name.eq_ignore_ascii_case(&fqdn))
{
if existing.content == new_entry.content {
println!("identical entry, skipping.");
} else {
println!("updating {}", existing.id);
client.edit(domain, &existing.id, new_entry).await?;
}
} else {
println!("making new record {new_entry:?}");
client.create(domain, new_entry).await?;
}
if my_ip.is_ipv6() {
let my_ip = Ipv4Addr::LOCALHOST;
let new_entry = CreateOrEditDnsRecord::A(subdomain, my_ip);
if let Some(existing) = existing_entries
.iter()
.find(|e| e.record_type == new_entry.record_type && e.name.eq_ignore_ascii_case(&fqdn))
{
if existing.content == new_entry.content {
println!("identical entry, skipping.");
} else {
println!("updating {}", existing.id);
client.edit(domain, &existing.id, new_entry).await?;
}
} else {
println!("making new record {new_entry:?}");
client.create(domain, new_entry).await?;
}
} else {
if let Some(old) = existing_entries
.iter()
.find(|e| e.record_type == DnsRecordType::AAAA && e.name.eq_ignore_ascii_case(&fqdn))
{
println!("deleting old AAAA record");
client.delete(domain, &old.id).await?;
}
}
Ok(())
}