Add logging info for changes to interfaces.toml

This commit is contained in:
Neshura 2023-12-27 17:18:56 +01:00
parent 151993c92a
commit 87a285bc2e
Signed by: Neshura
GPG key ID: B6983AAA6B9A7A6C
2 changed files with 100 additions and 21 deletions

View file

@ -10,7 +10,7 @@ use systemd_journal_logger::connected_to_journal;
use crate::cloudflare::DnsRecordType; use crate::cloudflare::DnsRecordType;
use crate::cloudflare::DnsRecordType::{A, AAAA}; use crate::cloudflare::DnsRecordType::{A, AAAA};
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub(crate) struct InterfaceConfig { pub(crate) struct InterfaceConfig {
pub(crate) host_address: Ipv6Addr, pub(crate) host_address: Ipv6Addr,
pub(crate) interfaces: HashMap<String, Ipv6Addr>, pub(crate) interfaces: HashMap<String, Ipv6Addr>,
@ -61,7 +61,7 @@ impl Default for InterfaceConfig {
/////////////// ///////////////
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub(crate) struct ZoneEntry { pub(crate) struct ZoneEntry {
pub(crate) name: String, pub(crate) name: String,
pub(crate) r#type: Vec<DnsRecordType>, pub(crate) r#type: Vec<DnsRecordType>,
@ -78,7 +78,7 @@ impl Default for ZoneEntry {
} }
} }
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub(crate) struct ZoneConfig { pub(crate) struct ZoneConfig {
pub(crate) email: String, pub(crate) email: String,
pub(crate) name: String, pub(crate) name: String,

View file

@ -163,11 +163,90 @@ fn main() {
loop { loop {
now = Utc::now(); now = Utc::now();
if now >= start + Duration::seconds(60) { if now >= start + Duration::seconds(10) { // DEBUG was 60
start = now; start = now;
match config::InterfaceConfig::load() { match config::InterfaceConfig::load() {
Ok(new) => ifaces = new, Ok(new_cfg) => {
if ifaces != new_cfg {
if ifaces.host_address != new_cfg.host_address {
let info_msg = format!("Host address in interfaces.toml changed from '{}' to '{}'", ifaces.host_address, new_cfg.host_address);
match connected_to_journal() {
true => info!("[INFO] {info_msg}"),
false => println!("[INFO] {info_msg}"),
}
}
if ifaces.interfaces != new_cfg.interfaces {
let mut new: Vec<(&String, &Ipv6Addr)> = vec![];
let mut deleted: Vec<(&String, &Ipv6Addr)>;
let mut modified: Vec<(&String, &Ipv6Addr)> = vec![];
new_cfg.interfaces.iter().for_each(|(interface, address)| {
if ifaces.interfaces.contains_key(interface) {
if ifaces.interfaces.get(interface) != Some(address) {
modified.push((interface, address));
}
}
else {
let matches: Vec<&Ipv6Addr> = ifaces.interfaces.values().filter(|addr| {
*addr == address
}).collect();
if matches.len() == 0 {
new.push((interface, address));
}
else {
modified.push((interface, address));
}
}
});
deleted = ifaces.interfaces.iter().filter(|(interface, address)| {
!new_cfg.interfaces.contains_key(*interface) && modified.iter().find(|(_, new_addr)| { new_addr == address }).is_none()
}).collect();
for (name, addr) in deleted {
let info_msg = format!("Deleted interface '{name}' with address '{addr}'");
match connected_to_journal() {
true => info!("[INFO] {info_msg}"),
false => println!("[INFO] {info_msg}"),
}
}
for (name, addr) in new {
let info_msg = format!("Added interface '{name}' with address '{addr}'");
match connected_to_journal() {
true => info!("[INFO] {info_msg}"),
false => println!("[INFO] {info_msg}"),
}
}
for (name, addr) in modified {
let info_msg;
if ifaces.interfaces.contains_key(name) {
let old_addr = ifaces.interfaces.get(name).expect("contains check on ifaces was successful");
info_msg = format!("Changed interface address of '{name}' from '{old_addr}' to '{addr}'");
}
else {
let old_name = ifaces.interfaces.iter()
.find(|(_, old_addr)| { old_addr == &addr })
.expect("modified entry should not exist if this fails")
.0;
info_msg = format!("Changed interface name for '{addr}' from '{old_name}' to '{name}'");
}
match connected_to_journal() {
true => info!("[INFO] {info_msg}"),
false => println!("[INFO] {info_msg}"),
}
}
}
ifaces = new_cfg
}
},
Err(e) => { Err(e) => {
let err_msg = format!("Unable to load ínterfaces.toml with error: {}", e); let err_msg = format!("Unable to load ínterfaces.toml with error: {}", e);
match connected_to_journal() { match connected_to_journal() {
@ -259,23 +338,23 @@ fn main() {
cf_entry.name == entry.name && &cf_entry.r#type == r#type cf_entry.name == entry.name && &cf_entry.r#type == r#type
}); });
match cf_entry.unwrap().r#type {
DnsRecordType::A => {
let cf_ip = Ipv4Addr::from_str(cf_entry.unwrap().content.as_str()).expect("Cloudflare return should always be valid IP");
if Some(cf_ip) == ipv4 {
continue
}
},
DnsRecordType::AAAA => {
let cf_ip = Ipv6Addr::from_str(cf_entry.unwrap().content.as_str()).expect("Cloudflare return should always be valid IP");
if Some(cf_ip) == ipv6 {
continue
}
},
_ => {},
}
if let Some(cf_entry) = cf_entry { if let Some(cf_entry) = cf_entry {
match cf_entry.r#type {
DnsRecordType::A => {
let cf_ip = Ipv4Addr::from_str(cf_entry.content.as_str()).expect("Cloudflare return should always be valid IP");
if Some(cf_ip) == ipv4 {
continue
}
},
DnsRecordType::AAAA => {
let cf_ip = Ipv6Addr::from_str(cf_entry.content.as_str()).expect("Cloudflare return should always be valid IP");
if Some(cf_ip) == ipv6 {
continue
}
},
_ => {},
}
if cf_zone.update(entry, r#type, &cf_entry.id, ipv6, ipv4).is_ok() { if cf_zone.update(entry, r#type, &cf_entry.id, ipv6, ipv4).is_ok() {
let info_msg = format!("Updated {} DNS Record for entry '{}' in zone '{}'", r#type, entry.name, zone.name); let info_msg = format!("Updated {} DNS Record for entry '{}' in zone '{}'", r#type, entry.name, zone.name);
match connected_to_journal() { match connected_to_journal() {