Add logging info for changes to interfaces.toml
All checks were successful
Run Tests on Code / run-tests (push) Successful in 12s
All checks were successful
Run Tests on Code / run-tests (push) Successful in 12s
This commit is contained in:
parent
251771f3c3
commit
9f48b76089
2 changed files with 100 additions and 21 deletions
|
@ -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,
|
||||||
|
|
115
src/main.rs
115
src/main.rs
|
@ -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() {
|
||||||
|
|
Loading…
Reference in a new issue