use std::sync::Arc; use log::warn; use opnsense_config_xml::{ Frontend, HAProxy, HAProxyBackend, HAProxyHealthCheck, HAProxyServer, OPNsense, }; use crate::{config::OPNsenseShell, Error}; pub struct LoadBalancerConfig<'a> { opnsense: &'a mut OPNsense, opnsense_shell: Arc, } impl<'a> LoadBalancerConfig<'a> { pub fn new(opnsense: &'a mut OPNsense, opnsense_shell: Arc) -> Self { Self { opnsense, opnsense_shell, } } pub fn get_full_config(&self) -> &Option { &self.opnsense.opnsense.haproxy } fn with_haproxy(&mut self, f: F) -> R where F: FnOnce(&mut HAProxy) -> R, { match &mut self.opnsense.opnsense.haproxy.as_mut() { Some(haproxy) => f(haproxy), None => unimplemented!( "Adding a backend is not supported when haproxy config does not exist yet" ), } } pub fn enable(&mut self, enabled: bool) { self.with_haproxy(|haproxy| haproxy.general.enabled = enabled as i32); } pub fn add_backend(&mut self, backend: HAProxyBackend) { warn!("TODO make sure this new backend does not refer non-existing entities like servers or health checks"); self.with_haproxy(|haproxy| haproxy.backends.backends.push(backend)); } pub fn add_frontend(&mut self, frontend: Frontend) { self.with_haproxy(|haproxy| haproxy.frontends.frontend.push(frontend)); } pub fn add_healthcheck(&mut self, healthcheck: HAProxyHealthCheck) { self.with_haproxy(|haproxy| haproxy.healthchecks.healthchecks.push(healthcheck)); } pub fn add_servers(&mut self, mut servers: Vec) { self.with_haproxy(|haproxy| haproxy.servers.servers.append(&mut servers)); } pub async fn reload_restart(&self) -> Result<(), Error> { self.opnsense_shell.exec("configctl haproxy stop").await?; self.opnsense_shell .exec("configctl template reload OPNsense/HAProxy") .await?; self.opnsense_shell .exec("configctl template reload OPNsense/Syslog") .await?; self.opnsense_shell .exec("/usr/local/sbin/haproxy -c -f /usr/local/etc/haproxy.conf.staging") .await?; // This script copies the staging config to production config. I am not 100% sure it is // required in the context self.opnsense_shell .exec("/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh deploy") .await?; self.opnsense_shell .exec("configctl haproxy configtest") .await?; self.opnsense_shell.exec("configctl haproxy start").await?; Ok(()) } }