aboutsummaryrefslogtreecommitdiff
path: root/src/dns_updater.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/dns_updater.rs')
-rw-r--r--src/dns_updater.rs88
1 files changed, 69 insertions, 19 deletions
diff --git a/src/dns_updater.rs b/src/dns_updater.rs
index d781671..e65689d 100644
--- a/src/dns_updater.rs
+++ b/src/dns_updater.rs
@@ -8,16 +8,28 @@ use tokio::sync::watch;
use tracing::*;
use crate::dns_config::*;
-use crate::provider::DnsProvider;
+use crate::DomainProvider;
pub async fn dns_updater_task(
mut rx_dns_config: watch::Receiver<Arc<DnsConfig>>,
- provider: Box<dyn DnsProvider>,
+ providers: Vec<DomainProvider>,
allowed_domains: Vec<String>,
mut must_exit: watch::Receiver<bool>,
) {
+ for dom in allowed_domains.iter() {
+ info!(domain = dom, "allowing subdomains of domain");
+ }
+ for prov in providers.iter() {
+ info!(
+ domain = prov.domain,
+ provider = prov.provider.provider(),
+ "got provider for domain"
+ );
+ }
+
info!("DNS updater will start in 5 seconds");
tokio::time::sleep(Duration::from_secs(5)).await;
+
info!("DNS updater starting");
let mut config = Arc::new(DnsConfig::new());
@@ -32,21 +44,37 @@ pub async fn dns_updater_task(
);
let new_config: Arc<DnsConfig> = rx_dns_config.borrow().clone();
- for (k, v) in new_config.entries.iter() {
- if config.entries.get(k) != Some(v) {
- let fulldomain = format!("{}.{}", k.subdomain, k.domain);
- if !allowed_domains.iter().any(|d| fulldomain.ends_with(d)) {
+ for (key, value) in new_config.entries.iter() {
+ // Skip entries that haven't changed
+ if config.entries.get(key) == Some(value) {
+ continue;
+ }
+
+ // Skip entries for unallowed domains
+ if !allowed_domains.iter().any(|d| key.dns_path.ends_with(d)) {
+ error!(
+ domain = key.dns_path,
+ "domain/subdomain/hostname not in allowed list",
+ );
+ continue;
+ }
+
+ let provider = providers.iter().find(|p| key.dns_path.ends_with(&p.domain));
+
+ if let Some(provider) = provider {
+ if let Err(e) = update_dns_entry(key, value, provider).await {
error!(
- "Got an entry for domain {} which is not in allowed list",
- k.domain
+ record = key.to_string(),
+ target = value.to_string(),
+ error = e.to_string(),
+ "unable to update record"
);
- continue;
- }
-
- info!("Updating {} {}", k, v);
- if let Err(e) = update_dns_entry(k, v, provider.as_ref()).await {
- error!("Unable to update entry {} {}: {}", k, v, e);
}
+ } else {
+ error!(
+ domain = key.dns_path,
+ "no provider matches this domain/subdomain/hostname"
+ );
}
}
@@ -57,8 +85,22 @@ pub async fn dns_updater_task(
async fn update_dns_entry(
key: &DnsEntryKey,
value: &DnsEntryValue,
- provider: &dyn DnsProvider,
+ provider: &DomainProvider,
) -> Result<()> {
+ let subdomain = key
+ .dns_path
+ .strip_suffix(&provider.domain)
+ .unwrap()
+ .trim_end_matches('.');
+ info!(
+ record = key.to_string(),
+ target = value.to_string(),
+ domain = provider.domain,
+ subdomain = &subdomain,
+ provider = provider.provider.provider(),
+ "updating record"
+ );
+
if value.targets.is_empty() {
bail!("zero targets (internal error)");
}
@@ -73,7 +115,8 @@ async fn update_dns_entry(
);
}
provider
- .update_a(&key.domain, &key.subdomain, &targets)
+ .provider
+ .update_a(&provider.domain, &subdomain, &targets)
.await?;
}
DnsRecordType::AAAA => {
@@ -85,17 +128,24 @@ async fn update_dns_entry(
);
}
provider
- .update_aaaa(&key.domain, &key.subdomain, &targets)
+ .provider
+ .update_aaaa(&provider.domain, &subdomain, &targets)
.await?;
}
DnsRecordType::CNAME => {
let mut targets = value.targets.iter().cloned().collect::<Vec<_>>();
if targets.len() > 1 {
targets.sort();
- warn!("Several CNAME targets for {}: {:?}. Taking first one in alphabetical order. Consider switching to a single global target instead.", key, targets);
+ warn!(
+ record = key.to_string(),
+ all_targets = value.to_string(),
+ selected_target = targets[0],
+ "Several CNAME targets, taking first one in alphabetical order. Consider switching to a single global target instead."
+ );
}
provider
- .update_cname(&key.domain, &key.subdomain, &targets[0])
+ .provider
+ .update_cname(&provider.domain, &subdomain, &targets[0])
.await?;
}
}