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("configctl haproxy configtest").await?; self.opnsense_shell.exec("configctl haproxy start").await?; Ok(()) } }