feat: Add score and opnsense implementation to register dhcp leases in dns server

This commit is contained in:
Jean-Gabriel Gill-Couture
2024-12-18 12:38:04 -05:00
parent 51c6f1818c
commit 478fd9e941
13 changed files with 222 additions and 20 deletions

View File

@@ -1,6 +1,6 @@
use std::{net::Ipv4Addr, sync::Arc, time::Duration};
use crate::{config::{SshConfigManager, SshCredentials, SshOPNSenseShell}, error::Error, modules::dhcp::DhcpConfig};
use crate::{config::{SshConfigManager, SshCredentials, SshOPNSenseShell}, error::Error, modules::{dhcp::DhcpConfig, dns::DnsConfig}};
use log::trace;
use opnsense_config_xml::OPNsense;
use russh::client;
@@ -35,6 +35,25 @@ impl Config {
DhcpConfig::new(&mut self.opnsense, self.shell.clone())
}
pub fn dns(&mut self) -> DnsConfig {
DnsConfig::new(&mut self.opnsense, self.shell.clone())
}
pub async fn restart_dns(&self) -> Result<(), Error> {
self.shell.exec("configctl unbound restart").await?;
Ok(())
}
/// Save the config to the repository. This method is meant NOT to reload services, only save
/// the config to the live file/database and perhaps take a backup when relevant.
pub async fn save(&self) -> Result<(), Error> {
self.repository
.save_config(&self.opnsense.to_xml())
.await
}
/// Save the configuration and reload all services. Be careful with this one as it will cause
/// downtime in many cases, such as a PPPoE renegociation
pub async fn apply(&self) -> Result<(), Error> {
self.repository
.apply_new_config(&self.opnsense.to_xml())

View File

@@ -20,7 +20,11 @@ impl ConfigManager for LocalFileConfigManager {
Ok(fs::read_to_string(&self.file_path)?)
}
async fn apply_new_config(&self, content: &str) -> Result<(), Error> {
async fn save_config(&self, content: &str) -> Result<(), Error> {
Ok(fs::write(&self.file_path, content)?)
}
async fn apply_new_config(&self, content: &str) -> Result<(), Error> {
self.save_config(content).await
}
}

View File

@@ -9,5 +9,6 @@ use crate::Error;
#[async_trait]
pub trait ConfigManager: std::fmt::Debug + Send + Sync {
async fn load_as_str(&self) -> Result<String, Error>;
async fn save_config(&self, content: &str) -> Result<(), Error>;
async fn apply_new_config(&self, content: &str) -> Result<(), Error>;
}

View File

@@ -50,13 +50,18 @@ impl ConfigManager for SshConfigManager {
self.opnsense_shell.exec("cat /conf/config.xml").await
}
async fn apply_new_config(&self, content: &str) -> Result<(), Error> {
async fn save_config(&self, content: &str) -> Result<(), Error> {
let temp_filename = self
.opnsense_shell
.write_content_to_temp_file(content)
.await?;
self.backup_config_remote().await?;
self.move_to_live_config(&temp_filename).await?;
Ok(())
}
async fn apply_new_config(&self, content: &str) -> Result<(), Error> {
self.save_config(content).await?;
self.reload_all_services().await?;
Ok(())
}

View File

@@ -0,0 +1,29 @@
use std::sync::Arc;
use opnsense_config_xml::OPNsense;
use crate::config::OPNsenseShell;
pub struct DnsConfig<'a> {
opnsense: &'a mut OPNsense,
opnsense_shell: Arc<dyn OPNsenseShell>,
}
impl<'a> DnsConfig<'a> {
pub fn new(opnsense: &'a mut OPNsense, opnsense_shell: Arc<dyn OPNsenseShell>) -> Self {
Self {
opnsense,
opnsense_shell,
}
}
pub fn register_dhcp_leases(&mut self, register: bool) {
let unbound = match &mut self.opnsense.opnsense.unboundplus {
Some(unbound) => unbound,
None => todo!("Handle case where unboundplus is not used"),
};
unbound.general.regdhcp = register as i8;
unbound.general.regdhcpstatic = register as i8;
}
}

View File

@@ -1 +1,2 @@
pub mod dhcp;
pub mod dns;