From 9978acf16d016910f73f5a946b606c75d8a962e9 Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Sun, 18 Jan 2026 10:06:15 -0500 Subject: [PATCH 01/14] feat: change staticroutes->route to Option instead of MaybeString --- examples/sttest/Cargo.toml | 21 +++ examples/sttest/src/main.rs | 159 +++++++++++++++++++++++ opnsense-config-xml/src/data/opnsense.rs | 4 +- 3 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 examples/sttest/Cargo.toml create mode 100644 examples/sttest/src/main.rs diff --git a/examples/sttest/Cargo.toml b/examples/sttest/Cargo.toml new file mode 100644 index 00000000..5b41e512 --- /dev/null +++ b/examples/sttest/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "sttest" +edition = "2024" +version.workspace = true +readme.workspace = true +license.workspace = true +publish = false + +[dependencies] +harmony = { path = "../../harmony" } +harmony_tui = { path = "../../harmony_tui" } +harmony_types = { path = "../../harmony_types" } +cidr = { workspace = true } +tokio = { workspace = true } +harmony_macros = { path = "../../harmony_macros" } +harmony_secret = { path = "../../harmony_secret" } +log = { workspace = true } +env_logger = { workspace = true } +url = { workspace = true } +serde = { workspace = true } +brocade = { path = "../../brocade" } diff --git a/examples/sttest/src/main.rs b/examples/sttest/src/main.rs new file mode 100644 index 00000000..fe40e8e8 --- /dev/null +++ b/examples/sttest/src/main.rs @@ -0,0 +1,159 @@ +use std::{ + net::{IpAddr, Ipv4Addr}, + sync::{Arc, OnceLock}, +}; + +use cidr::Ipv4Cidr; +use harmony::{ + config::secret::SshKeyPair, + data::{FileContent, FilePath}, + hardware::{HostCategory, Location, PhysicalHost, SwitchGroup}, + infra::{brocade::UnmanagedSwitch, opnsense::OPNSenseManagementInterface}, + inventory::Inventory, + modules::{ + http::StaticFilesHttpScore, + okd::{ + bootstrap_dhcp::OKDBootstrapDhcpScore, + bootstrap_load_balancer::OKDBootstrapLoadBalancerScore, dhcp::OKDDhcpScore, + dns::OKDDnsScore, ipxe::OKDIpxeScore, + }, + tftp::TftpScore, + }, + topology::{LogicalHost, UnmanagedRouter}, +}; +use harmony_macros::{ip, mac_address}; +use harmony_secret::{Secret, SecretManager}; +use harmony_types::net::Url; +use serde::{Deserialize, Serialize}; + +#[tokio::main] +async fn main() { + let firewall = harmony::topology::LogicalHost { + ip: ip!("192.168.40.1"), + name: String::from("fw0"), // settings -> general -> hostname on the opnsense firewall + }; + + let switch_client = UnmanagedSwitch::init() + .await + .expect("Failed to connect to switch"); + + let switch_client = Arc::new(switch_client); + + let opnsense = Arc::new( + harmony::infra::opnsense::OPNSenseFirewall::new(firewall, None, "root", "opnsense").await, + ); + let lan_subnet = Ipv4Addr::new(192, 168, 40, 0); + let gateway_ipv4 = Ipv4Addr::new(192, 168, 40, 1); + let gateway_ip = IpAddr::V4(gateway_ipv4); + let topology = harmony::topology::HAClusterTopology { + kubeconfig: None, + domain_name: "sttest0.harmony.mcd".to_string(), // TODO this must be set manually correctly + // when setting up the opnsense firewall in settings -> general -> domain + router: Arc::new(UnmanagedRouter::new( + gateway_ip, + Ipv4Cidr::new(lan_subnet, 24).unwrap(), + )), + load_balancer: opnsense.clone(), + firewall: opnsense.clone(), + tftp_server: opnsense.clone(), + http_server: opnsense.clone(), + dhcp_server: opnsense.clone(), + dns_server: opnsense.clone(), + control_plane: vec![ + LogicalHost { + ip: ip!("192.168.40.20"), + name: "cp0".to_string(), + }, + LogicalHost { + ip: ip!("192.168.40.21"), + name: "cp1".to_string(), + }, + LogicalHost { + ip: ip!("192.168.40.22"), + name: "cp2".to_string(), + }, + ], + bootstrap_host: LogicalHost { + ip: ip!("192.168.40.66"), + name: "bootstrap".to_string(), + }, + workers: vec![ + LogicalHost { + ip: ip!("192.168.40.30"), + name: "wk0".to_string(), + }, + ], + node_exporter: opnsense.clone(), + switch_client: switch_client.clone(), + network_manager: OnceLock::new(), + }; + + let inventory = Inventory { + location: Location::new("I am mobile".to_string(), "earth".to_string()), + switch: SwitchGroup::from([]), + firewall_mgmt: Box::new(OPNSenseManagementInterface::new()), + storage_host: vec![], + worker_host: vec![ + PhysicalHost::empty(HostCategory::Server) + .mac_address(mac_address!("64:00:6A:88:A3:50")), + ], + control_plane_host: vec![ + PhysicalHost::empty(HostCategory::Server) + .mac_address(mac_address!("F4:39:09:16:65:33")), + PhysicalHost::empty(HostCategory::Server) + .mac_address(mac_address!("F4:39:09:07:C8:F2")), + PhysicalHost::empty(HostCategory::Server) + .mac_address(mac_address!("F4:39:09:16:65:EA")), + ], + }; + + // TODO regroup smaller scores in a larger one such as this + // let okd_boostrap_preparation(); + + let bootstrap_dhcp_score = OKDBootstrapDhcpScore::new(&topology, &inventory); + let bootstrap_load_balancer_score = OKDBootstrapLoadBalancerScore::new(&topology); + let dhcp_score = OKDDhcpScore::new(&topology, &inventory); + let dns_score = OKDDnsScore::new(&topology); + let load_balancer_score = + harmony::modules::okd::load_balancer::OKDLoadBalancerScore::new(&topology); + + let ssh_key = SecretManager::get_or_prompt::().await.unwrap(); + + let tftp_score = TftpScore::new(Url::LocalFolder("./data/watchguard/tftpboot".to_string())); + let http_score = StaticFilesHttpScore { + folder_to_serve: Some(Url::LocalFolder( + "./data/watchguard/pxe-http-files".to_string(), + )), + files: vec![], + remote_path: None, + }; + + let kickstart_filename = "inventory.kickstart".to_string(); + let harmony_inventory_agent = "harmony_inventory_agent".to_string(); + + let ipxe_score = OKDIpxeScore { + kickstart_filename, + harmony_inventory_agent, + cluster_pubkey: FileContent { + path: FilePath::Relative("cluster_ssh_key.pub".to_string()), + content: ssh_key.public, + }, + }; + + harmony_tui::run( + inventory, + topology, + vec![ + // Box::new(dns_score), + Box::new(bootstrap_dhcp_score), + // Box::new(bootstrap_load_balancer_score), + // Box::new(load_balancer_score), + // Box::new(tftp_score), + // Box::new(http_score), + // Box::new(ipxe_score), + // Box::new(dhcp_score), + ], + ) + .await + .unwrap(); +} diff --git a/opnsense-config-xml/src/data/opnsense.rs b/opnsense-config-xml/src/data/opnsense.rs index ae277dc5..26a83c03 100644 --- a/opnsense-config-xml/src/data/opnsense.rs +++ b/opnsense-config-xml/src/data/opnsense.rs @@ -1153,7 +1153,7 @@ pub struct UnboundGeneral { pub local_zone_type: String, pub outgoing_interface: MaybeString, pub enable_wpad: MaybeString, - pub safesearch: MaybeString, + pub safesearch: Option, } #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] @@ -1421,7 +1421,7 @@ pub struct StaticRoutes { #[yaserde(attribute = true)] pub version: String, #[yaserde(rename = "route")] - pub route: Option, + pub route: Option, } #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] -- 2.39.5 From 001dd5269cacfea68f33f6aafabb2fa9b0824328 Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Sun, 18 Jan 2026 10:07:28 -0500 Subject: [PATCH 02/14] add (now commented) line to init env_logger --- examples/sttest/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/sttest/src/main.rs b/examples/sttest/src/main.rs index fe40e8e8..eafe2e77 100644 --- a/examples/sttest/src/main.rs +++ b/examples/sttest/src/main.rs @@ -28,6 +28,7 @@ use serde::{Deserialize, Serialize}; #[tokio::main] async fn main() { + // env_logger::init(); let firewall = harmony::topology::LogicalHost { ip: ip!("192.168.40.1"), name: String::from("fw0"), // settings -> general -> hostname on the opnsense firewall -- 2.39.5 From 0b55a6fb5389947824f2e0c02e3c533d8cdb7271 Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Tue, 20 Jan 2026 14:27:28 -0500 Subject: [PATCH 03/14] fix: add new xml fields after updating opnsense --- opnsense-config-xml/src/data/dnsmasq.rs | 2 ++ opnsense-config-xml/src/data/opnsense.rs | 3 +++ 2 files changed, 5 insertions(+) diff --git a/opnsense-config-xml/src/data/dnsmasq.rs b/opnsense-config-xml/src/data/dnsmasq.rs index fe76b663..7e8e74fd 100644 --- a/opnsense-config-xml/src/data/dnsmasq.rs +++ b/opnsense-config-xml/src/data/dnsmasq.rs @@ -73,6 +73,8 @@ pub struct Dhcp { pub reply_delay: MaybeString, pub enable_ra: u8, pub nosync: u8, + pub log_dhcp: u8, + pub log_quiet: u8, } // Represents a single element. diff --git a/opnsense-config-xml/src/data/opnsense.rs b/opnsense-config-xml/src/data/opnsense.rs index 26a83c03..028d5d57 100644 --- a/opnsense-config-xml/src/data/opnsense.rs +++ b/opnsense-config-xml/src/data/opnsense.rs @@ -30,6 +30,7 @@ pub struct OPNsense { pub staticroutes: StaticRoutes, pub ca: MaybeString, pub gateways: Option, + pub hostwatch: Option, pub cert: Vec, pub dhcpdv6: DhcpDv6, pub virtualip: VirtualIp, @@ -463,6 +464,8 @@ pub struct OPNsenseXmlSection { pub openvpn: ConfigOpenVPN, #[yaserde(rename = "Gateways")] pub gateways: RawXml, + #[yaserde(rename = "Hostwatch")] + pub hostwatch: RawXml, #[yaserde(rename = "HAProxy")] pub haproxy: Option, } -- 2.39.5 From d2d18205e9f99753ed34926b50b1339582106412 Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Wed, 21 Jan 2026 13:09:26 -0500 Subject: [PATCH 04/14] fix deps in Cargo.toml, create env.sh file --- examples/sttest/Cargo.toml | 3 ++- examples/sttest/env.sh | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 examples/sttest/env.sh diff --git a/examples/sttest/Cargo.toml b/examples/sttest/Cargo.toml index 5b41e512..b8f90f8c 100644 --- a/examples/sttest/Cargo.toml +++ b/examples/sttest/Cargo.toml @@ -8,12 +8,13 @@ publish = false [dependencies] harmony = { path = "../../harmony" } -harmony_tui = { path = "../../harmony_tui" } +harmony_cli = { path = "../../harmony_cli" } harmony_types = { path = "../../harmony_types" } cidr = { workspace = true } tokio = { workspace = true } harmony_macros = { path = "../../harmony_macros" } harmony_secret = { path = "../../harmony_secret" } +harmony_secret_derive = { path = "../../harmony_secret_derive" } log = { workspace = true } env_logger = { workspace = true } url = { workspace = true } diff --git a/examples/sttest/env.sh b/examples/sttest/env.sh new file mode 100644 index 00000000..45410958 --- /dev/null +++ b/examples/sttest/env.sh @@ -0,0 +1,4 @@ +export HARMONY_SECRET_NAMESPACE=sttest0 +export HARMONY_SECRET_STORE=file +export HARMONY_DATABASE_URL=sqlite://harmony_sttest0.sqlite RUST_LOG=info +export RUST_LOG=info -- 2.39.5 From 2ef2d9f0646aaa8c18483780ce7cd832cc5d1bce Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Wed, 21 Jan 2026 13:56:28 -0500 Subject: [PATCH 05/14] Fix HostRole (ControlPlane -> Worker) in workers score, fix main, add topology.rs --- examples/sttest/src/main.rs | 156 +++--------------- examples/sttest/src/topology.rs | 112 +++++++++++++ .../src/modules/okd/bootstrap_04_workers.rs | 2 +- 3 files changed, 134 insertions(+), 136 deletions(-) create mode 100644 examples/sttest/src/topology.rs diff --git a/examples/sttest/src/main.rs b/examples/sttest/src/main.rs index eafe2e77..622a3925 100644 --- a/examples/sttest/src/main.rs +++ b/examples/sttest/src/main.rs @@ -1,159 +1,45 @@ -use std::{ - net::{IpAddr, Ipv4Addr}, - sync::{Arc, OnceLock}, -}; +mod topology; -use cidr::Ipv4Cidr; +use crate::topology::{get_inventory, get_topology}; use harmony::{ config::secret::SshKeyPair, data::{FileContent, FilePath}, - hardware::{HostCategory, Location, PhysicalHost, SwitchGroup}, - infra::{brocade::UnmanagedSwitch, opnsense::OPNSenseManagementInterface}, - inventory::Inventory, modules::{ - http::StaticFilesHttpScore, - okd::{ - bootstrap_dhcp::OKDBootstrapDhcpScore, - bootstrap_load_balancer::OKDBootstrapLoadBalancerScore, dhcp::OKDDhcpScore, - dns::OKDDnsScore, ipxe::OKDIpxeScore, - }, - tftp::TftpScore, + inventory::HarmonyDiscoveryStrategy, + okd::{installation::OKDInstallationPipeline, ipxe::OKDIpxeScore}, }, - topology::{LogicalHost, UnmanagedRouter}, + score::Score, + topology::HAClusterTopology, }; -use harmony_macros::{ip, mac_address}; -use harmony_secret::{Secret, SecretManager}; -use harmony_types::net::Url; -use serde::{Deserialize, Serialize}; +use harmony_secret::SecretManager; #[tokio::main] async fn main() { // env_logger::init(); - let firewall = harmony::topology::LogicalHost { - ip: ip!("192.168.40.1"), - name: String::from("fw0"), // settings -> general -> hostname on the opnsense firewall - }; - - let switch_client = UnmanagedSwitch::init() - .await - .expect("Failed to connect to switch"); - - let switch_client = Arc::new(switch_client); - - let opnsense = Arc::new( - harmony::infra::opnsense::OPNSenseFirewall::new(firewall, None, "root", "opnsense").await, - ); - let lan_subnet = Ipv4Addr::new(192, 168, 40, 0); - let gateway_ipv4 = Ipv4Addr::new(192, 168, 40, 1); - let gateway_ip = IpAddr::V4(gateway_ipv4); - let topology = harmony::topology::HAClusterTopology { - kubeconfig: None, - domain_name: "sttest0.harmony.mcd".to_string(), // TODO this must be set manually correctly - // when setting up the opnsense firewall in settings -> general -> domain - router: Arc::new(UnmanagedRouter::new( - gateway_ip, - Ipv4Cidr::new(lan_subnet, 24).unwrap(), - )), - load_balancer: opnsense.clone(), - firewall: opnsense.clone(), - tftp_server: opnsense.clone(), - http_server: opnsense.clone(), - dhcp_server: opnsense.clone(), - dns_server: opnsense.clone(), - control_plane: vec![ - LogicalHost { - ip: ip!("192.168.40.20"), - name: "cp0".to_string(), - }, - LogicalHost { - ip: ip!("192.168.40.21"), - name: "cp1".to_string(), - }, - LogicalHost { - ip: ip!("192.168.40.22"), - name: "cp2".to_string(), - }, - ], - bootstrap_host: LogicalHost { - ip: ip!("192.168.40.66"), - name: "bootstrap".to_string(), - }, - workers: vec![ - LogicalHost { - ip: ip!("192.168.40.30"), - name: "wk0".to_string(), - }, - ], - node_exporter: opnsense.clone(), - switch_client: switch_client.clone(), - network_manager: OnceLock::new(), - }; - - let inventory = Inventory { - location: Location::new("I am mobile".to_string(), "earth".to_string()), - switch: SwitchGroup::from([]), - firewall_mgmt: Box::new(OPNSenseManagementInterface::new()), - storage_host: vec![], - worker_host: vec![ - PhysicalHost::empty(HostCategory::Server) - .mac_address(mac_address!("64:00:6A:88:A3:50")), - ], - control_plane_host: vec![ - PhysicalHost::empty(HostCategory::Server) - .mac_address(mac_address!("F4:39:09:16:65:33")), - PhysicalHost::empty(HostCategory::Server) - .mac_address(mac_address!("F4:39:09:07:C8:F2")), - PhysicalHost::empty(HostCategory::Server) - .mac_address(mac_address!("F4:39:09:16:65:EA")), - ], - }; - - // TODO regroup smaller scores in a larger one such as this - // let okd_boostrap_preparation(); - - let bootstrap_dhcp_score = OKDBootstrapDhcpScore::new(&topology, &inventory); - let bootstrap_load_balancer_score = OKDBootstrapLoadBalancerScore::new(&topology); - let dhcp_score = OKDDhcpScore::new(&topology, &inventory); - let dns_score = OKDDnsScore::new(&topology); - let load_balancer_score = - harmony::modules::okd::load_balancer::OKDLoadBalancerScore::new(&topology); + + let inventory = get_inventory(); + let topology = get_topology().await; let ssh_key = SecretManager::get_or_prompt::().await.unwrap(); - let tftp_score = TftpScore::new(Url::LocalFolder("./data/watchguard/tftpboot".to_string())); - let http_score = StaticFilesHttpScore { - folder_to_serve: Some(Url::LocalFolder( - "./data/watchguard/pxe-http-files".to_string(), - )), - files: vec![], - remote_path: None, - }; - - let kickstart_filename = "inventory.kickstart".to_string(); - let harmony_inventory_agent = "harmony_inventory_agent".to_string(); - - let ipxe_score = OKDIpxeScore { - kickstart_filename, - harmony_inventory_agent, + let mut scores: Vec>> = vec![Box::new(OKDIpxeScore { + kickstart_filename: "inventory.kickstart".to_string(), + harmony_inventory_agent: "harmony_inventory_agent".to_string(), cluster_pubkey: FileContent { path: FilePath::Relative("cluster_ssh_key.pub".to_string()), content: ssh_key.public, }, - }; + })]; - harmony_tui::run( + // let mut scores: Vec>> = vec![]; + scores + .append(&mut OKDInstallationPipeline::get_all_scores(HarmonyDiscoveryStrategy::MDNS).await); + + harmony_cli::run( inventory, topology, - vec![ - // Box::new(dns_score), - Box::new(bootstrap_dhcp_score), - // Box::new(bootstrap_load_balancer_score), - // Box::new(load_balancer_score), - // Box::new(tftp_score), - // Box::new(http_score), - // Box::new(ipxe_score), - // Box::new(dhcp_score), - ], + scores, + None ) .await .unwrap(); diff --git a/examples/sttest/src/topology.rs b/examples/sttest/src/topology.rs new file mode 100644 index 00000000..dba94be9 --- /dev/null +++ b/examples/sttest/src/topology.rs @@ -0,0 +1,112 @@ +use brocade::BrocadeOptions; +use cidr::Ipv4Cidr; +use harmony::{ + hardware::{Location, SwitchGroup}, + infra::{ + brocade::{BrocadeSwitchClient, UnmanagedSwitch}, + opnsense::OPNSenseManagementInterface, + }, + inventory::Inventory, + topology::{HAClusterTopology, LogicalHost, UnmanagedRouter}, +}; +use harmony_macros::{ip, ipv4}; +use harmony_secret::{Secret, SecretManager}; +use serde::{Deserialize, Serialize}; +use std::{ + net::IpAddr, + sync::{Arc, OnceLock}, +}; + +#[derive(Secret, Serialize, Deserialize, Debug, PartialEq)] +struct OPNSenseFirewallConfig { + username: String, + password: String, +} + +pub async fn get_topology() -> HAClusterTopology { + let firewall = harmony::topology::LogicalHost { + ip: ip!("192.168.40.1"), + name: String::from("fw0"), + }; + + let switch_client = UnmanagedSwitch::init() + .await + .expect("Failed to connect to switch"); + + let switch_client = Arc::new(switch_client); + + let config = SecretManager::get_or_prompt::().await; + let config = config.unwrap(); + + let opnsense = Arc::new( + harmony::infra::opnsense::OPNSenseFirewall::new( + firewall, + None, + &config.username, + &config.password, + ) + .await, + ); + let lan_subnet = ipv4!("192.168.40.0"); + let gateway_ipv4 = ipv4!("192.168.40.1"); + let gateway_ip = IpAddr::V4(gateway_ipv4); + harmony::topology::HAClusterTopology { + kubeconfig: None, + domain_name: "sttest0.harmony.mcd".to_string(), + router: Arc::new(UnmanagedRouter::new( + gateway_ip, + Ipv4Cidr::new(lan_subnet, 24).unwrap(), + )), + load_balancer: opnsense.clone(), + firewall: opnsense.clone(), + tftp_server: opnsense.clone(), + http_server: opnsense.clone(), + dhcp_server: opnsense.clone(), + dns_server: opnsense.clone(), + control_plane: vec![ + LogicalHost { + ip: ip!("192.168.40.20"), + name: "cp0".to_string(), + }, + LogicalHost { + ip: ip!("192.168.40.21"), + name: "cp1".to_string(), + }, + LogicalHost { + ip: ip!("192.168.40.22"), + name: "cp2".to_string(), + }, + ], + bootstrap_host: LogicalHost { + ip: ip!("192.168.40.10"), + name: "bootstrap".to_string(), + }, + workers: vec![LogicalHost { + ip: ip!("192.168.40.30"), + name: "wk0".to_string(), + }], + node_exporter: opnsense.clone(), + switch_client: switch_client.clone(), + network_manager: OnceLock::new(), + } +} + +pub fn get_inventory() -> Inventory { + Inventory { + location: Location::new( + "Sylvain's basement".to_string(), + "Charlesbourg".to_string(), + ), + switch: SwitchGroup::from([]), + firewall_mgmt: Box::new(OPNSenseManagementInterface::new()), + storage_host: vec![], + worker_host: vec![], + control_plane_host: vec![], + } +} + +#[derive(Secret, Serialize, Deserialize, Debug)] +pub struct BrocadeSwitchAuth { + pub username: String, + pub password: String, +} diff --git a/harmony/src/modules/okd/bootstrap_04_workers.rs b/harmony/src/modules/okd/bootstrap_04_workers.rs index 53e32c5e..4dbfdecb 100644 --- a/harmony/src/modules/okd/bootstrap_04_workers.rs +++ b/harmony/src/modules/okd/bootstrap_04_workers.rs @@ -22,7 +22,7 @@ pub struct OKDSetup04WorkersScore { impl Score for OKDSetup04WorkersScore { fn create_interpret(&self) -> Box> { Box::new(OKDNodeInterpret::new( - HostRole::ControlPlane, + HostRole::Worker, self.discovery_strategy.clone(), )) } -- 2.39.5 From de3c8e9a41734fcea7e02b33fdf494081b4a611e Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Wed, 21 Jan 2026 13:59:22 -0500 Subject: [PATCH 06/14] adding data symlink --- examples/sttest/data | 1 + 1 file changed, 1 insertion(+) create mode 120000 examples/sttest/data diff --git a/examples/sttest/data b/examples/sttest/data new file mode 120000 index 00000000..b8fb52e7 --- /dev/null +++ b/examples/sttest/data @@ -0,0 +1 @@ +../../data/ \ No newline at end of file -- 2.39.5 From eb492f3ca96c3f23d8e0288b5022d7aae60d3ac4 Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Wed, 21 Jan 2026 14:02:58 -0500 Subject: [PATCH 07/14] fix: remove double definition of RUST_LOG in env.sh --- examples/sttest/env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/sttest/env.sh b/examples/sttest/env.sh index 45410958..4a3c24ee 100644 --- a/examples/sttest/env.sh +++ b/examples/sttest/env.sh @@ -1,4 +1,4 @@ export HARMONY_SECRET_NAMESPACE=sttest0 export HARMONY_SECRET_STORE=file -export HARMONY_DATABASE_URL=sqlite://harmony_sttest0.sqlite RUST_LOG=info +export HARMONY_DATABASE_URL=sqlite://harmony_sttest0.sqlite export RUST_LOG=info -- 2.39.5 From 0ecadbfb971790279117b90331a1b35dbc682c9d Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Wed, 21 Jan 2026 15:07:35 -0500 Subject: [PATCH 08/14] chore: remove unused import --- examples/sttest/src/topology.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/sttest/src/topology.rs b/examples/sttest/src/topology.rs index dba94be9..d13a7a70 100644 --- a/examples/sttest/src/topology.rs +++ b/examples/sttest/src/topology.rs @@ -1,9 +1,8 @@ -use brocade::BrocadeOptions; use cidr::Ipv4Cidr; use harmony::{ hardware::{Location, SwitchGroup}, infra::{ - brocade::{BrocadeSwitchClient, UnmanagedSwitch}, + brocade::UnmanagedSwitch, opnsense::OPNSenseManagementInterface, }, inventory::Inventory, -- 2.39.5 From 74252ded5ccaf11bcdc28e811bec44939e6ac4c5 Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Wed, 21 Jan 2026 15:12:23 -0500 Subject: [PATCH 09/14] chore: remove useless brocade stuff --- examples/sttest/src/topology.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/examples/sttest/src/topology.rs b/examples/sttest/src/topology.rs index d13a7a70..52629035 100644 --- a/examples/sttest/src/topology.rs +++ b/examples/sttest/src/topology.rs @@ -103,9 +103,3 @@ pub fn get_inventory() -> Inventory { control_plane_host: vec![], } } - -#[derive(Secret, Serialize, Deserialize, Debug)] -pub struct BrocadeSwitchAuth { - pub username: String, - pub password: String, -} -- 2.39.5 From 25a45096f8bc19ba293ddfa17227af971716faa0 Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Wed, 21 Jan 2026 16:22:59 -0500 Subject: [PATCH 10/14] doc: adding installation notes file --- examples/sttest/installation-notes.txt | 137 +++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 examples/sttest/installation-notes.txt diff --git a/examples/sttest/installation-notes.txt b/examples/sttest/installation-notes.txt new file mode 100644 index 00000000..82b6e4e3 --- /dev/null +++ b/examples/sttest/installation-notes.txt @@ -0,0 +1,137 @@ +# Outside Dependency + +[] Get a RedHat PullSecret (free but require registering) + +# Hardware setup + +[] Set clock (watch out UTC vs Local...) +[] No SecureBoot +[] Empty disks +[] Boot order : disk, pxe (as long as when no OS found it falls back to pxe) + +# Opnsense manual stuff + +[] System -> Firmware -> Status : [Check for updates] -> Install all available updates (button down the page) + +[] System -> Settings -> Administration -> TCP port : 443 -> 8443 +[] System -> Settings -> Administration -> Secure Shell Server : [Check] Enable Secure Shell +[] System -> Settings -> Administration -> Root Login : [Check] Permit root user login +[] System -> Settings -> Administration -> Authentication Method : [Check] Permit password login + +[] System -> Settings -> General -> Hostname : fw0 +[] System -> Settings -> General -> Domain : sttest0.harmony.mcd + +[] System -> Services -> Unbound DNS -> General : [UNCHECK] Enable Unbound + +[] System -> Services -> Dnsmasq DNS & DHCP -> General -> Default -> Enable : [Check] +[] System -> Services -> Dnsmasq DNS & DHCP -> General -> DNS -> Listen port : leave blank (remove 0), it will default to 53 + +# Base setup + +[] Create a folder for your installation +[] Copy everything from `harmony/examples/sttest` in your new folder +[] Update `Cargo.toml` -> package name +[] Make sure symlink `data` points to harmony`s `data` folder +[] Update `env.sh` + -> HARMONY_SECRET_NAMESPACE : prefix given to the files containing the secrets in `$HOME/.local/share/harmony` + -> HARMONY_DATABASE_URL : `sqlite://` +[] Update `env.sh` +[] Create an ssh keypair, keep it in your project's root folder (never commit that) +[] Update `src/main.rs` : make sure `cluster's pubkey path` points to your public key + (I think we should change that to take it from the secret instead...? Unless a file is really required...? to check...) +[] Update `src/topology.rs` : replace `IPs`, `Names`, `Domain Name` (match opnsense config), Inventory's `Location` +[] Update `harmony/src/modules/okd/okd_nodes.rs` : impl OKDRoleProperties for WorkerRole : set `required_hosts` to the number of workers you will configure +[] Prepare some json to copy/paste later to feed the secrets (use proper values, these are examples): + opnsense creds: {"username":"root","password":"opnsense"} + ssh keypair: {"private":"-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----","public":"ssh-ed25519 ..."} + redhat pullsecret: {"pull_secret":"{\"auths\":{\"cloud.openshift.com\":{\"auth\":\"...",\"email\":\"...\"},\"quay.io\":{\"auth\":\"...",\"email\":\"..."},\"registry.connect.redhat.com\":{\"auth\":\"...",\"email\":\"..."},\"registry.redhat.io\":{\"auth\":\"...",\"email\":\"..."}}}"} +[] Create an sqlite database (you need sqlite3 on your machine) with two tables + ``` + $ sqlite3 + sqlite> CREATE TABLE IF NOT EXISTS physical_hosts ( + version_id TEXT PRIMARY KEY NOT NULL, + id TEXT NOT NULL, + data JSON NOT NULL); + + sqlite> CREATE INDEX IF NOT EXISTS idx_host_id_time + ON physical_hosts (id, version_id DESC); + CREATE TABLE IF NOT EXISTS host_role_mapping ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + host_id TEXT NOT NULL, + role TEXT NOT NULL + ); + ``` + +# Installation + +## pxe and bootstrap + +[] cd to folder +[] source env file : `. env.sh` +[] `cargo run` +[] feed the secrets when asked (opnsense and sshKeyPair for now) +[] create the hosts as asked on opnsense : Services -> Dnsmasq DNS & DHCP -> Hosts, make sure they dig properly +[] manual copy from the data folder when asked + ** ISSUE ** There is currently a public key in there which will overwrite your own key. We will remove it. + Until then, you can ctrl-c and restart `cargo run`, it will re-copy the right key +[] PXE boot the `bootstrap node`, it should boot the discovery agent image +[] The discovery process should kick in, select the bootstrap node +[] Feed the redhat pull-secret when asked +[] OKD installer will run, prepare all the files in `data/okd/installation_files_` +[] When asked for, do the manual copy of the generated files +[] When asked to reboot the bootstrap node, do it (not automated yet) and make sure it starts in PXE again. If you monitor the console, you should see iPXE finding the byMAC file and boot using the bootstrap ignition file +[] Harmony will then crash on a todo!, the bootstrap process should now be started + +[] edit your main.rs : comment the OKDIpxeScore block and define an empty vec instead +``` + /* + let mut scores: Vec>> = vec![Box::new(OKDIpxeScore { + kickstart_filename: "inventory.kickstart".to_string(), + harmony_inventory_agent: "harmony_inventory_agent".to_string(), + cluster_pubkey: FileContent { + path: FilePath::Relative("cluster_ssh_key.pub".to_string()), + content: ssh_key.public, + }, + })]; + */ + + let mut scores: Vec>> = vec![]; +``` + +## control planes + +[] edit `harmony/src/modules/okd/installation.rs` to comment the scores 01, 02, and `OKDSetupPersistNetworkBondScore` +[] PXE boot the 3 control planes. They should boot the discovery agent image +[] restart harmony : `cargo run` +[] the discovery should find your control planes. select them one by one + -> To check : the first time I made a mistake and selected the bootstrap node. I did ctrl-c and restarted. + Later on, when the dnsmasq have been updated, one of the CPs was wrong, using the mac of the bootstrap. + There may be an issue with the data in the sqllite db when this occurs +[] the byMAC files will be copied +[] when asked for, manually reboot the 3 control planes. They should reboot in pxe with their byMAC files and start the installation process + -> If you have a clock issue (timezone, bad date, whatever) they will loop on a certificate error +[] This will then end harmony in a panic on a todo! because its time to wait for the installation to complete + +## bootstrap cleanup + +[] When the installation is completed, remove the bootstrap node from Dnsmasq : Services ->Dnsmasq DNS & DHCP -> Hosts +[] If you want to recycle the bootstrap as a worker, ssh to it and clean the disk (sgdisk --zap-all, wipefs won't work) + +## workers + +[] pxe boot your workers (reboot the cleaned up bootstrap node), they should boot the inventory agent +[] edit `harmony/src/modules/okd/installation.rs` to comment the score 03 +[] restart harmony +[] select your workers from the discoverInventoryAgent +[] the byMAC files will be copied +[] when asked, reboot your workers. They should now boot on their byMAC configured images +[] harmony will then do its sanity check, installation report and end +[] monitor the cluster for csr `oc get csr` for the new worker nodes (you need to manually approve certs) + you should get two certs to approve for each worker node, in two batches. `oc adm certificate approve ` + + +# Things to know +- Folder where stuff will be saved on your machine (i.e.: local secrets) : `$HOME/.local/share/harmony` +- Folder where generated stuff related to your installation will be saved (including auth infos for the cluster) : `data/okd/installation_files_` +- When hosts are booted with the inventory agent image, you can ssh with `root@host` using the cluster privkey your defined +- When hosts are booted with an okd image, you can ssh with `core@host` using the cluster privkey your defined -- 2.39.5 From 5ed14b75eda9da545b5d7e029ce8c2cf68940166 Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Thu, 22 Jan 2026 08:47:56 -0500 Subject: [PATCH 11/14] chore: fix formatting --- examples/sttest/src/main.rs | 13 ++++--------- examples/sttest/src/topology.rs | 10 ++-------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/examples/sttest/src/main.rs b/examples/sttest/src/main.rs index 622a3925..ba049cfa 100644 --- a/examples/sttest/src/main.rs +++ b/examples/sttest/src/main.rs @@ -16,7 +16,7 @@ use harmony_secret::SecretManager; #[tokio::main] async fn main() { // env_logger::init(); - + let inventory = get_inventory(); let topology = get_topology().await; @@ -35,12 +35,7 @@ async fn main() { scores .append(&mut OKDInstallationPipeline::get_all_scores(HarmonyDiscoveryStrategy::MDNS).await); - harmony_cli::run( - inventory, - topology, - scores, - None - ) - .await - .unwrap(); + harmony_cli::run(inventory, topology, scores, None) + .await + .unwrap(); } diff --git a/examples/sttest/src/topology.rs b/examples/sttest/src/topology.rs index 52629035..ca797eb0 100644 --- a/examples/sttest/src/topology.rs +++ b/examples/sttest/src/topology.rs @@ -1,10 +1,7 @@ use cidr::Ipv4Cidr; use harmony::{ hardware::{Location, SwitchGroup}, - infra::{ - brocade::UnmanagedSwitch, - opnsense::OPNSenseManagementInterface, - }, + infra::{brocade::UnmanagedSwitch, opnsense::OPNSenseManagementInterface}, inventory::Inventory, topology::{HAClusterTopology, LogicalHost, UnmanagedRouter}, }; @@ -92,10 +89,7 @@ pub async fn get_topology() -> HAClusterTopology { pub fn get_inventory() -> Inventory { Inventory { - location: Location::new( - "Sylvain's basement".to_string(), - "Charlesbourg".to_string(), - ), + location: Location::new("Sylvain's basement".to_string(), "Charlesbourg".to_string()), switch: SwitchGroup::from([]), firewall_mgmt: Box::new(OPNSenseManagementInterface::new()), storage_host: vec![], -- 2.39.5 From c9e39d11ad7c83af6caf7bdb78cbe7d1f2f8be38 Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Thu, 22 Jan 2026 14:52:29 -0500 Subject: [PATCH 12/14] fix: fix opnsense stuff for opnsense 25.1 test file --- opnsense-config-xml/Cargo.toml | 1 + opnsense-config-xml/src/data/dnsmasq.rs | 8 +- opnsense-config-xml/src/data/opnsense.rs | 44 +- opnsense-config/src/config/config.rs | 3 +- opnsense-config/src/modules/dns.rs | 7 +- .../src/tests/data/config-full-25.7.11_2.xml | 2376 +++++++++++++++++ .../src/tests/data/config-opnsense-25.1.xml | 22 +- 7 files changed, 2419 insertions(+), 42 deletions(-) create mode 100644 opnsense-config/src/tests/data/config-full-25.7.11_2.xml diff --git a/opnsense-config-xml/Cargo.toml b/opnsense-config-xml/Cargo.toml index ef0d4265..26efa50e 100644 --- a/opnsense-config-xml/Cargo.toml +++ b/opnsense-config-xml/Cargo.toml @@ -9,6 +9,7 @@ license.workspace = true serde = { version = "1.0.123", features = [ "derive" ] } log = { workspace = true } env_logger = { workspace = true } +#yaserde = { path = "../../yaserde/yaserde" } yaserde = { git = "https://github.com/jggc/yaserde.git" } yaserde_derive = { git = "https://github.com/jggc/yaserde.git" } xml-rs = "0.8" diff --git a/opnsense-config-xml/src/data/dnsmasq.rs b/opnsense-config-xml/src/data/dnsmasq.rs index 7e8e74fd..d66ba2df 100644 --- a/opnsense-config-xml/src/data/dnsmasq.rs +++ b/opnsense-config-xml/src/data/dnsmasq.rs @@ -8,6 +8,8 @@ pub struct DnsMasq { pub version: String, #[yaserde(attribute = true)] pub persisted_at: Option, + #[yaserde(attribute = true)] + pub description: Option, pub enable: u8, pub regdhcp: u8, @@ -23,7 +25,7 @@ pub struct DnsMasq { pub dnssec: u8, pub regdhcpdomain: MaybeString, pub interface: Option, - pub port: Option, + pub port: Option, pub dns_forward_max: MaybeString, pub cache_size: MaybeString, pub local_ttl: MaybeString, @@ -73,8 +75,8 @@ pub struct Dhcp { pub reply_delay: MaybeString, pub enable_ra: u8, pub nosync: u8, - pub log_dhcp: u8, - pub log_quiet: u8, + pub log_dhcp: Option, + pub log_quiet: Option, } // Represents a single element. diff --git a/opnsense-config-xml/src/data/opnsense.rs b/opnsense-config-xml/src/data/opnsense.rs index 028d5d57..9798d8f5 100644 --- a/opnsense-config-xml/src/data/opnsense.rs +++ b/opnsense-config-xml/src/data/opnsense.rs @@ -163,11 +163,15 @@ pub struct Username { #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] pub struct Sysctl { + #[yaserde(attribute = true)] + pub version: Option, pub item: Vec, } #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] pub struct SysctlItem { + #[yaserde(attribute = true)] + pub uuid: Option, pub descr: Option, pub tunable: Option, pub value: Option, @@ -175,6 +179,8 @@ pub struct SysctlItem { #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] pub struct System { + #[yaserde(attribute = true)] + pub uuid: Option, pub use_mfs_tmp: Option, pub use_mfs_var: Option, pub serialspeed: u32, @@ -269,6 +275,8 @@ pub struct Bogons { #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] pub struct Group { + #[yaserde(attribute = true)] + pub uuid: Option, pub name: String, pub description: Option, pub scope: String, @@ -281,6 +289,8 @@ pub struct Group { #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] pub struct User { + #[yaserde(attribute = true)] + pub uuid: Option, pub name: String, pub descr: MaybeString, pub scope: String, @@ -465,7 +475,7 @@ pub struct OPNsenseXmlSection { #[yaserde(rename = "Gateways")] pub gateways: RawXml, #[yaserde(rename = "Hostwatch")] - pub hostwatch: RawXml, + pub hostwatch: Option, #[yaserde(rename = "HAProxy")] pub haproxy: Option, } @@ -1146,9 +1156,9 @@ pub struct UnboundGeneral { pub dns64: MaybeString, pub dns64prefix: MaybeString, pub noarecords: MaybeString, - pub regdhcp: Option, + pub regdhcp: Option, pub regdhcpdomain: MaybeString, - pub regdhcpstatic: Option, + pub regdhcpstatic: Option, pub noreglladdr6: MaybeString, pub noregrecords: MaybeString, pub txtsupport: MaybeString, @@ -1161,22 +1171,22 @@ pub struct UnboundGeneral { #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] pub struct Advanced { - pub hideidentity: Option, - pub hideversion: Option, - pub prefetch: Option, - pub prefetchkey: Option, - pub dnssecstripped: Option, + pub hideidentity: Option, + pub hideversion: Option, + pub prefetch: Option, + pub prefetchkey: Option, + pub dnssecstripped: Option, pub aggressivensec: Option, - pub serveexpired: Option, + pub serveexpired: Option, pub serveexpiredreplyttl: MaybeString, pub serveexpiredttl: MaybeString, - pub serveexpiredttlreset: Option, + pub serveexpiredttlreset: Option, pub serveexpiredclienttimeout: MaybeString, - pub qnameminstrict: Option, - pub extendedstatistics: Option, - pub logqueries: Option, - pub logreplies: Option, - pub logtagqueryreply: Option, + pub qnameminstrict: Option, + pub extendedstatistics: Option, + pub logqueries: Option, + pub logreplies: Option, + pub logtagqueryreply: Option, pub logservfail: MaybeString, pub loglocalactions: MaybeString, pub logverbosity: i32, @@ -1219,12 +1229,12 @@ pub struct Dnsbl { pub blocklists: Option, pub wildcards: Option, pub address: Option, - pub nxdomain: Option, + pub nxdomain: Option, } #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] pub struct Forwarding { - pub enabled: Option, + pub enabled: Option, } #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] diff --git a/opnsense-config/src/config/config.rs b/opnsense-config/src/config/config.rs index 7c292c8e..1454292d 100644 --- a/opnsense-config/src/config/config.rs +++ b/opnsense-config/src/config/config.rs @@ -234,7 +234,7 @@ mod tests { #[tokio::test] async fn test_load_config_from_local_file() { for path in [ - // "src/tests/data/config-opnsense-25.1.xml", + "src/tests/data/config-opnsense-25.1.xml", // "src/tests/data/config-vm-test.xml", "src/tests/data/config-structure.xml", "src/tests/data/config-full-1.xml", @@ -242,6 +242,7 @@ mod tests { // "src/tests/data/config-full-25.7.xml", // "src/tests/data/config-full-25.7-dummy-dnsmasq-options.xml", "src/tests/data/config-25.7-dnsmasq-static-host.xml", + "src/tests/data/config-full-25.7.11_2.xml", ] { let mut test_file_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); test_file_path.push(path); diff --git a/opnsense-config/src/modules/dns.rs b/opnsense-config/src/modules/dns.rs index 517b5ea6..42c8b54b 100644 --- a/opnsense-config/src/modules/dns.rs +++ b/opnsense-config/src/modules/dns.rs @@ -1,4 +1,4 @@ -use opnsense_config_xml::{Host, OPNsense}; +use opnsense_config_xml::{Host, MaybeString, OPNsense}; pub struct UnboundDnsConfig<'a> { opnsense: &'a mut OPNsense, @@ -31,7 +31,8 @@ impl<'a> UnboundDnsConfig<'a> { None => todo!("Handle case where unboundplus is not used"), }; - unbound.general.regdhcp = Some(register as i8); - unbound.general.regdhcpstatic = Some(register as i8); + unbound.general.regdhcp = Some(MaybeString::from_bool_as_int("regdhcp", register)); + unbound.general.regdhcpstatic = + Some(MaybeString::from_bool_as_int("regdhcpstatic", register)); } } diff --git a/opnsense-config/src/tests/data/config-full-25.7.11_2.xml b/opnsense-config/src/tests/data/config-full-25.7.11_2.xml new file mode 100644 index 00000000..690844f3 --- /dev/null +++ b/opnsense-config/src/tests/data/config-full-25.7.11_2.xml @@ -0,0 +1,2376 @@ + + + opnsense + + + 115200 + video + normal + fw0 + sttest0.harmony.mcd + + admins + System Administrators + system + 1999 + 0 + page-all + + + + root + System Administrator + system + $2y$10$YRVoF4SgskIsrXOvOQjGieB9XqHPRra9R7d80B3BZdbY/j21TwBfS + + 0 + 0 + + + + + + + + + + + + + Etc/UTC + 0.opnsense.pool.ntp.org 1.opnsense.pool.ntp.org 2.opnsense.pool.ntp.org 3.opnsense.pool.ntp.org + + https + 69355bf776c20 + 8443 + + + + + 1 + yes + 1 + 1 + 1 + 1 + 1 + 1 + hadp + hadp + hadp + + monthly + + 1 + 1 + + admins + 1 + + + + + + enabled + 1 + + 1 + + + -1 + -1 + + + + os-caddy,os-haproxy,os-tftp + + + 0 + + 1 + + en_US + + none + none + none + none + none + none + none + none + + + + em0 + + 1 + + dhcp + + + 32 + 1 + + 60 + 10 + + + + + SavedCfg + + + + + advanced + + + + + bge0 + 1 + 192.168.40.1 + 24 + + + + + + + + + 1 + lo0 + Loopback + 1 + 127.0.0.1 + none + 1 + 8 + ::1 + 128 + + + bge1 + 1 + + + + + + + public + + + + + automatic + + + + + pass + lan + inet + Default allow LAN to any rule + + lan + + + + + + + pass + lan + inet6 + Default allow LAN IPv6 to any rule + + lan + + + + + + + pass + lan + inet + keep state + Allow from 192.168.2.0/24 + in + 1 + tcp + +
192.168.2.0/24
+ + + 1 + + + root@192.168.40.112 + + /firewall_rules_edit.php made changes + + + root@192.168.40.112 + + /firewall_rules_edit.php made changes + +
+
+ + + + + 0.opnsense.pool.ntp.org + + + root@192.168.40.112 + /system_general.php made changes + + + + + + + + + + + + + + + v9 + + + + 0 + + 1800 + 15 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + wan + 192.168.0.0/16,10.0.0.0/8,172.16.0.0/12 + + + W0D23 + 4 + + + + + + + 0 + 0 + 0 + + + + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + 16 + 32 + 4 + 1000 + 1 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + + + + + + + + + 0 + + + + + + + 0 + 0 + + + ipsec + 0 + 1 + + + + + + + + + + + + + 0 + 127.0.0.1 + 8000 + + + + + 0 + 0 + + 4000 + 1 + raw + + + 0 + + 2 + + + + + + + + 0 + 0 + + 4000 + 1 + + + 0 + + 2 + + + + + + + + + + 0 + 120 + 120 + 127.0.0.1 + 25 + + + 0 + auto + 1 + + + + + 0 + root + + 2812 + + + 5 + 1 + + + 0 + root@localhost.local + 0 + + + + + + + 1 + $HOST + + system + + + + 300 + 30 +
+ + + + 0c5ad352-6965-4fc3-81a6-6b7d68db1e1c,bed84737-9833-4356-b3f2-e6be29222bf9,d494e04e-72a2-44f9-bdee-84b0b762390a,e15baa92-7793-4e7c-900c-526f3bf443bf + + + + + 1 + RootFs + + filesystem + + + / + 300 + 30 +
+ + + + 491c5187-e8f8-4ac0-b17e-4981ce765e5c + + + + + 0 + carp_status_change + + custom + + + /usr/local/opnsense/scripts/monit/carp_status.php + 300 + 30 +
+ + + + 33846c3c-4b3d-426c-88fc-8010ae579fbb + + + + + 0 + gateway_alert + + custom + + + /usr/local/opnsense/scripts/monit/gateway_alert.php + 300 + 30 +
+ + + + ef40e63c-036c-4874-b322-a53667179644 + + + + + Ping + NetworkPing + failed ping + alert + + + + NetworkLink + NetworkInterface + failed link + alert + + + + NetworkSaturation + NetworkInterface + saturation is greater than 75% + alert + + + + MemoryUsage + SystemResource + memory usage is greater than 75% + alert + + + + CPUUsage + SystemResource + cpu usage is greater than 75% + alert + + + + LoadAvg1 + SystemResource + loadavg (1min) is greater than 12 + alert + + + + LoadAvg5 + SystemResource + loadavg (5min) is greater than 9 + alert + + + + LoadAvg15 + SystemResource + loadavg (15min) is greater than 6 + alert + + + + SpaceUsage + SpaceUsage + space usage is greater than 75% + alert + + + + ChangedStatus + ProgramStatus + changed status + alert + + + + NonZeroStatus + ProgramStatus + status != 0 + alert + + + + + + + + + 1 + 1 + 31 + + + + + + + + + + + + 0 + 53 + 0 + + 0 + 0 + + 0 + 0 + + 0 + 0 + 0 + 0 + 0 + transparent + + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + + 0.0.0.0/8,10.0.0.0/8,100.64.0.0/10,169.254.0.0/16,172.16.0.0/12,192.0.2.0/24,192.168.0.0/16,198.18.0.0/15,198.51.100.0/24,203.0.113.0/24,233.252.0.0/24,::1/128,2001:db8::/32,fc00::/8,fd00::/8,fe80::/10 + + + + + + + + + + + + + + 0 + + + + + allow + + + + 0 + + + + + + + + + 0 + 0 + 0 + 1 + 0 + + + + + + + + + + + 1 + 192.168.40.1 + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + 0 + Pi_Jumpbox + + lan + inet + 192.168.40.112 + 0 + 0 + 1 + 0 + 0 + 0 + + 0 + 255 + 1 + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + 1 + 0 + 60s + + 0 + 0 + 1 + + 0 + + + 1024 + + + 1024 + + + 0 + + 1 + ipv4 + ignore + 2048 + 16384 + 2 + 0 + 0 + + 0 + 300 + 3600 + 0 + prefer-client-ciphers + TLSv1.2 + + ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256 + TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 + + + + + + + + + + + 30s + 30s + + 30s + 3 + x-1 + last,libc + + + + 127.0.0.1 + local0 + info + + + + 0 + 8822 + 0 + + 0 + + + + + 0 + *:8404 + /metrics + + + 0 + 4 + 60 + + 0 + 10 + + + + + c77e5c9d9c020af5.a2cb2ff3 + 1 + frontend_192.168.40.1:80 + + 192.168.40.1:80 + + tcp + 74e016a6-7b3a-4612-9905-3cbfc0caea87 + 0 + + + + 0 + + + + + + 0 + 0 + 0 + 0 + 0 + + + + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 0 + + + + + 0 + + + + + + + + + 0 + 0 + + 0 + 0 + + + + + + + + b1679ba2eb842e5.b30d0330 + 1 + frontend_192.168.40.1:443 + + 192.168.40.1:443 + + tcp + d49fdd12-5bf3-4f61-92f4-85aa61031a05 + 0 + + + + 0 + + + + + + 0 + 0 + 0 + 0 + 0 + + + + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 0 + + + + + 0 + + + + + + + + + 0 + 0 + + 0 + 0 + + + + + + + + 12a94182c74eaacc.cb520a04 + 1 + frontend_192.168.40.1:22623 + + 192.168.40.1:22623 + + tcp + e2c97e7d-f255-4c94-ae16-222d9100132b + 0 + + + + 0 + + + + + + 0 + 0 + 0 + 0 + 0 + + + + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 0 + + + + + 0 + + + + + + + + + 0 + 0 + + 0 + 0 + + + + + + + + 13d6ac21ee3ccc60.96cd4b70 + 1 + frontend_192.168.40.1:6443 + + 192.168.40.1:6443 + + tcp + 4dcf78bf-2543-4c2c-bc0c-8a0d594d3248 + 0 + + + + 0 + + + + + + 0 + 0 + 0 + 0 + 0 + + + + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 0 + + + + + 0 + + + + + + + + + 0 + 0 + + 0 + 0 + + + + + + + + + + f08894401df05ad8.3d5c30db + 1 + backend_192.168.40.1:80 + + tcp + roundrobin + 2 + + 3c7b4f9e-7c71-4599-928c-a245d3967be7,3cb381bd-cd9b-44d1-96b2-35c53849ff93,51b5b214-59cd-4bf4-9787-213079b95744,f6a3ea11-3d67-4096-ac22-112cf7d69e6e,3572b374-5516-4ef1-8c65-9f905f396165 + + + + + + 1 + 11ec6494-d394-406a-9768-08148134e3eb + 0 + + + + + + 0 + 0 + + + + + 0 + + + 30m + 50k + + + 10s + 10s + 10s + 10s + 1m + 1m + 0 + + + + + + + + + 0 + + 0 + + + + + 53b09184e47806ad.6062e3bd + 1 + backend_192.168.40.1:443 + + tcp + roundrobin + 2 + + 4098fdb2-ba6d-4edd-ab05-e997c9cef626,af439509-7e75-40bd-9c72-8f6a2710498c,e8467e26-1c2d-4fd8-a67e-e17b1f619967,fea2cfee-2dd9-4046-b172-ae2b941063d5,4a8587cc-d3a4-4fa6-97e9-c079d0d22240 + + + + + + 1 + a5d88192-aef3-42f0-aec4-cb6eaebca84f + 0 + + + + + + 0 + 0 + + + + + 0 + + + 30m + 50k + + + 10s + 10s + 10s + 10s + 1m + 1m + 0 + + + + + + + + + 0 + + 0 + + + + + fb3d213167709bf2.f6d030ee + 1 + backend_192.168.40.1:22623 + + tcp + roundrobin + 2 + + b1a99d0e-75c9-42a8-a0ea-91ee1bfbc508,7a606821-2d1f-41f1-8edb-3a8bebbe0aa4,4e091504-977f-4e83-bf90-678d68ad4816,741e99a1-fe92-4b6d-b6c2-3bd039934a7f,dd5f78b0-e083-4080-972b-73b53924d059 + + + + + + 1 + 17bc9250-d232-4e99-b77c-9cbcc0fb633e + 0 + + + + + + 0 + 0 + + + + + 0 + + + 30m + 50k + + + 10s + 10s + 10s + 10s + 1m + 1m + 0 + + + + + + + + + 0 + + 0 + + + + + f3bf483e1e76c8b8.78ae61ca + 1 + backend_192.168.40.1:6443 + + tcp + roundrobin + 2 + + a817a002-3892-47a3-82ac-f28a3c357ffe,25906935-b3e3-482f-b0ba-a082d5316d6b,ee918485-01b0-462b-ad1b-1b35f4e871a6,cced84b6-f99f-49e7-af31-c71f7478405d,e1ab9bb3-4c4a-4a20-96e2-0710fa3d4fc2 + + + + + + 1 + 25bfdc19-6d79-41c6-951e-74bac3d249e8 + 0 + + + + + + 0 + 0 + + + + + 0 + + + 30m + 50k + + + 10s + 10s + 10s + 10s + 1m + 1m + 0 + + + + + + + + + 0 + + 0 + + + + + + + e659e683eb4f8cbf.bc6647fd + 1 + 192.168.40.20_80 + +
192.168.40.20
+ 80 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 98e07b8c2cf4e121.f80ffb86 + 1 + 192.168.40.21_80 + +
192.168.40.21
+ 80 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 6d610bd3274928f0.772b633a + 1 + 192.168.40.22_80 + +
192.168.40.22
+ 80 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 4e766be7687ff1b2.9f602 + 1 + 192.168.40.30_80 + +
192.168.40.30
+ 80 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 96f86eff29c19586.899c8c7d + 1 + 192.168.40.10_80 + +
192.168.40.10
+ 80 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + b1ef1eac98733197.75fa14c7 + 1 + 192.168.40.20_443 + +
192.168.40.20
+ 443 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 7b8e5951eea6c199.a6da8696 + 1 + 192.168.40.21_443 + +
192.168.40.21
+ 443 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + a8a3af8568459ef8.ce390541 + 1 + 192.168.40.22_443 + +
192.168.40.22
+ 443 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 993b27c0684e9142.41d99327 + 1 + 192.168.40.30_443 + +
192.168.40.30
+ 443 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 7ed96373b629946d.a2234a79 + 1 + 192.168.40.10_443 + +
192.168.40.10
+ 443 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + ebfb123745ab99fa.56b7e81 + 1 + 192.168.40.20_22623 + +
192.168.40.20
+ 22623 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 5b336dfe21d70db0.de1c1873 + 1 + 192.168.40.21_22623 + +
192.168.40.21
+ 22623 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + aa954ffc2004a428.3f979125 + 1 + 192.168.40.22_22623 + +
192.168.40.22
+ 22623 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 2c5ad4987d529880.8404a1cb + 1 + 192.168.40.30_22623 + +
192.168.40.30
+ 22623 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + f61263456cb23546.1b8fc725 + 1 + 192.168.40.10_22623 + +
192.168.40.10
+ 22623 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 2c76a5e648a22d31.acb00182 + 1 + 192.168.40.20_6443 + +
192.168.40.20
+ 6443 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 1dec35d79dc64d6d.35d924e9 + 1 + 192.168.40.21_6443 + +
192.168.40.21
+ 6443 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 8fec2b81ef16ac1.c768ff85 + 1 + 192.168.40.22_6443 + +
192.168.40.22
+ 6443 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 9c142802a8b9a550.b0ae2086 + 1 + 192.168.40.30_6443 + +
192.168.40.30
+ 6443 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+ + 2773c715be07db11.6ce4873a + 1 + 192.168.40.10_6443 + +
192.168.40.10
+ 6443 + + active + + static + + + + + + 0 + + 0 + + + + + + + + + +
+
+ + + TCP_serverport + + tcp + 2s + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + TCP_serverport + + tcp + 2s + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + TCP_serverport + + tcp + 2s + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + HTTP_GET_/readyz + + http + 2s + ssl + + 0 + + GET + /readyz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + 0 + + 0 + + 0 + + + +
+ + + + 192.168.2.62/32 + Pi_Jumpbox + Route to 192.168.2.0 ... + 0 + + + + + 69355bf776c20 + Web GUI TLS certificate + LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUhFakNDQlBxZ0F3SUJBZ0lVQlJrcksrdWdLSXFITkdjNEFCVVM0NmxNZDZZd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2dZWXhHakFZQmdOVkJBTU1FVTlRVG5ObGJuTmxMbWx1ZEdWeWJtRnNNUXN3Q1FZRFZRUUdFd0pPVERFVgpNQk1HQTFVRUNBd01XblZwWkMxSWIyeHNZVzVrTVJVd0V3WURWUVFIREF4TmFXUmtaV3hvWVhKdWFYTXhMVEFyCkJnTlZCQW9NSkU5UVRuTmxibk5sSUhObGJHWXRjMmxuYm1Wa0lIZGxZaUJqWlhKMGFXWnBZMkYwWlRBZUZ3MHkKTlRFeU1EY3hNRFV3TXpKYUZ3MHlOekF4TURneE1EVXdNekphTUlHR01Sb3dHQVlEVlFRRERCRlBVRTV6Wlc1egpaUzVwYm5SbGNtNWhiREVMTUFrR0ExVUVCaE1DVGt3eEZUQVRCZ05WQkFnTURGcDFhV1F0U0c5c2JHRnVaREVWCk1CTUdBMVVFQnd3TVRXbGtaR1ZzYUdGeWJtbHpNUzB3S3dZRFZRUUtEQ1JQVUU1elpXNXpaU0J6Wld4bUxYTnAKWjI1bFpDQjNaV0lnWTJWeWRHbG1hV05oZEdVd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJSwpBb0lDQVFDclF3Q29XZitzMUl3UjdqZ0twcTlRVUhlbEtxbDNzWkZjSk5iU2lKMWdlL2ZLM2ZheVEvMkJOZzVhCkhFOWp1Vk1SOTJiSzZrS3NnajJQb1M2d21aVE5zMVJtYkljd29qUVRCdlh3ZElheG5jbTZkRzc5TkFwZ3pPYmMKNDNBaTNnVG1KdTUybndzSEVqUWtHUzlhWnhSTzNuTVB5UUFNWDFjRW1WM2FjTGdmbGtadHdLSjQ3OEVHSVpFSwpIbzhHbE5YNUs1eDNmZFEreGpzQ2I3Wk9hMU5vYU9ZTm0xMmt6V21qelRISmd6eFdKbTlhUU05Mi9rUm1JU0VLClZjU1N1UDMvTzAyd2J0cDJZMDE1TTNyOU1kc2lLUTRVOHhuVlNoMG1ZajBYNXJ1TmJpZVVydVRMRHRQU0NwaksKQmZCTjRtNFl6R2NFTTEyZ2pITHN5TCt4WEN5bmI1MDJmNTVnb2ZDNHFuWlFLOWdOUFRzR1dMU3FXYVdGY3hSLwpoNjJmdVE4VnZYMmJsSGRRenNveXhXSXRzci9xbTJtYUY3NGdOTWRacFpMamFkQ3JOWVY1SDlPVVZ6b0hWTmd2CmxjTWFaaEcxQkUwV3R5THNhcjFwU2IzdVhPcmFRdXlHM0ZaS1dNQnl4VmRRUGR6WmgrMk1sMDU4Tnp1V3dyZ2wKN085V3ZWa3YwREwzZStXRzE0TlAwOFJEa0JyRjk2SUpJM2hoRkRwMk1TR3BVWitYZW1TN1pVQ2o5b2NWdGVocworcXlIeWxZMkQyU2FYZG1SUmNwK3l5RkFNYmhDeHBoMnI4WFMvTXgrZXRaSDU4ZFU3emlZdEQvNUJsSzBkRGRzCmZ4eGcwSG5QL2lGOEpuSU1sK3BWWXVpdk1wRnh0RFJtRUNZSnZMWi9RTHNxU3AvSUhRSURBUUFCbzRJQmREQ0MKQVhBd0NRWURWUjBUQkFJd0FEQVJCZ2xnaGtnQmh2aENBUUVFQkFNQ0JrQXdOQVlKWUlaSUFZYjRRZ0VOQkNjVwpKVTlRVG5ObGJuTmxJRWRsYm1WeVlYUmxaQ0JUWlhKMlpYSWdRMlZ5ZEdsbWFXTmhkR1V3SFFZRFZSME9CQllFCkZNWXI5NGdMS2doZDVYT2RXWGV3R3BMd0ZlZEZNSUd3QmdOVkhTTUVnYWd3Z2FXaGdZeWtnWWt3Z1lZeEdqQVkKQmdOVkJBTU1FVTlRVG5ObGJuTmxMbWx1ZEdWeWJtRnNNUXN3Q1FZRFZRUUdFd0pPVERFVk1CTUdBMVVFQ0F3TQpXblZwWkMxSWIyeHNZVzVrTVJVd0V3WURWUVFIREF4TmFXUmtaV3hvWVhKdWFYTXhMVEFyQmdOVkJBb01KRTlRClRuTmxibk5sSUhObGJHWXRjMmxuYm1Wa0lIZGxZaUJqWlhKMGFXWnBZMkYwWllJVUJSa3JLK3VnS0lxSE5HYzQKQUJVUzQ2bE1kNll3SFFZRFZSMGxCQll3RkFZSUt3WUJCUVVIQXdFR0NDc0dBUVVGQ0FJQ01Bc0dBMVVkRHdRRQpBd0lGb0RBY0JnTlZIUkVFRlRBVGdoRlBVRTV6Wlc1elpTNXBiblJsY201aGJEQU5CZ2txaGtpRzl3MEJBUXNGCkFBT0NBZ0VBVVlJQ1FXUHdkR25FNHdUVG9MUVg4Mm1GbzdreWlneGpIMGlrenJDclZFZlUxcE1CakNldUl0WFEKZnpmS0NXSFplVVhWeE1uNkwyWkxpaE9lalZRVVM3c0psWW9PZGdiYUJmRm9Zd1dTTTMrSHZGQWtWelI3ZW1uUQpMbDh6U0lnN3B3UFgrOTBLcVNRRnhPOUdKcWE0MWEvc1hCZlAvVkxxZHh4SFhsb3dsK1JpRmJZMDRhdFo3a0xtCjI4R1AwSTFMVEYyRnRzNXhsN2EzNzRLdm9wSFNici9LQmV0b1ZJb3pSVXN6WGE1ODI3alBOZVBGQTlsS2lPNUkKSkNLS1pZVVpsM2F4NkF5a2FsOHJ5SFlIVWUwaGZaaFZyWDZLNDFEQjBoL210SWxOSm9sLzBqdnI2aDgySFhaNAo4dVJQNHNWZGxwOXVQTVVKcVNWRW84aGo0ajc1b0dSU3JHSEpKMk0zUXhKVE1ITTQ5UkpCT1EzRmtQOVBaakprCkRFRjc1UUttZGZxWGo4OXZnNUhQUTBzU0owbGpTVVVQVGR6Vlc2cUFtYll0T3ZwTWV0MVcxMjAyNFd2RitlNkEKMG4rMUU0Ri9oNEdyVWg3NmFmSG1LcTRrNXVBU1daOUNFbTF1Wm9mZjZSdVk2N3ZPVXdpVkgzUlpTWEN2aDluUQppZVhtWXMya09KMzNnUUpHTE1qNEhNeWw1ZTFudW9wekhkR0xmNVJ1bFdvbS8yL21YckpXQXNVL3AxY2dGMW5sClJ6em1hZ0NSeUE2RzBFRWMyZW9FODFYMjQ0azJwa3NRcUIrL3VibmxNa0VGaE1JQWtOeDU2N3dON2hDUTFvQ0IKbW51cWpBRkc3NE5jUFYyT0w1KzhlQmJaa3FONTNBMDVzQngrTG41ZnlEZEd4VzN1eVZrPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + + + LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRUUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1Nzd2dna25BZ0VBQW9JQ0FRQ3JRd0NvV2YrczFJd1IKN2pnS3BxOVFVSGVsS3FsM3NaRmNKTmJTaUoxZ2UvZkszZmF5US8yQk5nNWFIRTlqdVZNUjkyYks2a0tzZ2oyUApvUzZ3bVpUTnMxUm1iSWN3b2pRVEJ2WHdkSWF4bmNtNmRHNzlOQXBnek9iYzQzQWkzZ1RtSnU1Mm53c0hFalFrCkdTOWFaeFJPM25NUHlRQU1YMWNFbVYzYWNMZ2Zsa1p0d0tKNDc4RUdJWkVLSG84R2xOWDVLNXgzZmRRK3hqc0MKYjdaT2ExTm9hT1lObTEya3pXbWp6VEhKZ3p4V0ptOWFRTTkyL2tSbUlTRUtWY1NTdVAzL08wMndidHAyWTAxNQpNM3I5TWRzaUtRNFU4eG5WU2gwbVlqMFg1cnVOYmllVXJ1VExEdFBTQ3BqS0JmQk40bTRZekdjRU0xMmdqSExzCnlMK3hYQ3luYjUwMmY1NWdvZkM0cW5aUUs5Z05QVHNHV0xTcVdhV0ZjeFIvaDYyZnVROFZ2WDJibEhkUXpzb3kKeFdJdHNyL3FtMm1hRjc0Z05NZFpwWkxqYWRDck5ZVjVIOU9VVnpvSFZOZ3ZsY01hWmhHMUJFMFd0eUxzYXIxcApTYjN1WE9yYVF1eUczRlpLV01CeXhWZFFQZHpaaCsyTWwwNThOenVXd3JnbDdPOVd2Vmt2MERMM2UrV0cxNE5QCjA4UkRrQnJGOTZJSkkzaGhGRHAyTVNHcFVaK1hlbVM3WlVDajlvY1Z0ZWhzK3F5SHlsWTJEMlNhWGRtUlJjcCsKeXlGQU1iaEN4cGgycjhYUy9NeCtldFpINThkVTd6aVl0RC81QmxLMGREZHNmeHhnMEhuUC9pRjhKbklNbCtwVgpZdWl2TXBGeHREUm1FQ1lKdkxaL1FMc3FTcC9JSFFJREFRQUJBb0lDQUJSRERoaUhqLzlEcFByRGJnVkhQcENkCnBJOTVvbFBUUWZrSk1XZjJoU0FTMVUzcGF0N0x1bm9IWDRxbVgzZDk4cEpsUWRmRXFzb1JjcC9EN2NFenVtNHkKY2FHRE9qb0tjV2R3T0dLNnkrdHhycG5pWFVzKy8vSC9RVnBsaDRaOTIvaUZmS0JlSlZ1RnozNFhMZ29LWTFXeQp3eUdIOTFCL2F5SitmcU1jYmp4QklaTlVsTThDd1VTQ0dOQitBdy9xbTFJcWZiZzBFK0N3RlVVdTJ2NTJKakpyCnpybFNFTEhjZDZETE9HdTRuTWZZZzVqRm90dFhnOWQ0R0pwS0ZzS3J6bFBjWnFSTUhvbEpLd2orMytYYXpkYVgKSXQrMFQwY2VjMHB2bWFqSDdKZjBBMklpT3dGbktnVVIvemVrOGptcURnL2RzYkViM3FUakE2bk4vOEtkRkNTSAp2VHpNZUVEbzV5eEJuWlBHaTE1OS9LSUYyQU5yLzI1K2pPWVZibnpoZjZHQkxNSjZObDhjc1BLdWgzRkg4MTNBCkhyVUZZckQ1OERYQm1aUFdUYXFacWRxSkhIS25DVThnRUZoTDFFYVNlbWhnMHhPSGcwQjNuUXFPT25aMG1aSm0KZ3BsTy9GemxTN1dGSVB5NGU5RFhJRldoUDRCNWpGaDhubXB6bHZ4cXJSaXkvYUc2VmVSS2hTY3FMTksyOE53Qgo2OWNuM25NdFlDOCs0azhhR0ducDBLeWRDcFU4MFcwVW9PZzJCNHMzSDdHZENUbnZpK2ZwdithNFJ5ZE8yNCtXCmo4Wk15UUpHaFY1TTMwckpaZ1R2MmVxVHhpVjlYVEswV2JrQ1JUNHFTeVJxY2dwYm1IM3dNcGdXbmRqc3dGTVQKOUhrSllMVEFqeEppM09KeVdha0ZBb0lCQVFEeFU3dWQwUlJGVVI1cE1uRzRBeTk2U0hscG1VU0ltZVpzWXlwcQpmamtUL0J6Y1VnZ3Bzam80bnJpMnZBbEN0a3VEWW45K3ovSVR1RzA5Wng1RitmMlRiTUw5L0YvZTZIdUM1NXpTCjBBQ003K3d2QVNLaDdJbVYveit2dVYrSkxud2FISU4xeWh4U2ZLdFF3czBpc2ZsT21EMzUrS054Uk40NUQvbDAKR0tmcm5XcVZGQ29GSTNaN2xiWCszZnpURDdkdEY1ZkFCSTlVdnVaTXNMVis3Uk9lbXhvMXlnN0QyLzFiNnRQSwpONzVwR1d2QzUvbHZnSnMzZ2tmdmlEMi91b3hZM0hrQjFuUU55Sis2clNMajJyUjh2TWl1UCtMeHFvMnZEMVFhCitCYjNmWDRqMDQrMGxOdDRYaGRaSXVGNThKamF5ZzlGZnFQVnBlTnVGNkE2QVhMekFvSUJBUUMxckxNQ1RMSnMKRE8wbjI5cUh6VUtkbHl2USs5QmsxLzByRFpVQVZPNDQrNVhXQ081TlFndWxIOWUxclJJekVVZTZEdXlYVlVTbwpvU1JvenkxUHVSd0tldXNhWVNKZk5JVHJGVGlMRnEzOXJwcnVzWWl4Zk1jM2tSeDVYKyszeFJLOFY0ZlNiMDRkCjdjRStHNkhYRHZkVGxqRmRXRUZRTmRqMkUyWC9jYW1yT0JsRU16RzBGL0VHRWZrLytRNHdVWDUydkY5ZSthVXUKYUJoQ2dtSzhEWXFwMWdlY3hscFE1cEtMVndORFNLVjFLK2ZIMGYwVHRKOUhCWlVNWU9KSlpWdnYzN3NDNk9BawpyYzA0eTRKNVAvWHVlaHFFNmhhbHFrdVdiSW0wV2xWVXArSS9oTEdXajcwK3ZmSG41bFJCVjR0MXhtYVVHTTVRCmdQb2tlbWJBV2Z5dkFvSUJBQkxhZDgzY2g3amluWDJhYzBmczk4aVY0T1pmRXZ1WkNtZHRWK0w1K1h1V05xci8KdmFPRVNRZ2pYa3JvWmREUWJSWFduQjlNSDUxcXl4NEE4RnlISzBoWk51S2cxTnlWVFJEdEIxTnc3Sm9XSkYySAp1U3p0VGRKcUhvK2I2OXJMeHVaRFZBSGZ5RmFwWnJqb2Z4NDJ5VU5hb1h6bDc5N3Bnbkx5eklwRll0a0ZjMDR5ClJSWWhyeC80a2o5WEdHbGswTyswNkNZWU5ScHB6NVF1T2Yrd2hkZmVSaTN0bXpteDloazRQMU9OQjFNdXFUeVEKNHV2VElFMDE0R2pXTy95K2xqaGJBUmtqcCsxcnZ3N1dkK05WTXNTTCt5R2gzQmtGT2d4ekpoNzFRdFlTOThmVQp2MlZjTzhrcmtLZG1FamQwbEh5RFRLNGhOcXQ2U2twUGpqVDU2QUVDZ2dFQUNLcGlKM3Z0RHNaWEVZMmxFTkV6Cm1qeTV0RkF1a29EUzdKakxRS2JNYmg5aCtFR1l6RXFZTDVvak9lRTFld1laKzcvMmZRbHVLdlQwdmFNVU1EZE8KSlJuVDJRQkZHWEZ4M1p5M2c3cmpOYlI4WTJKSWVON1F5Yys4SWZYM2d6WjlQRXFZaWVzUk9OQThaVy8vK2pnVwppQUFqL3FYVkI3UnAwdUw5L0g4NWJwZFFiVFpiNnBFeHgrNVhpenVmOTZJTGZESmtBaTI2T1VweHpjcFdWMDMyCkRUL09RU1ljN0xyeXhuNnlBeVdWN3M3WFVXcXN2YUhoN3d0UEhyWUlWU1Btakx5Sk9ReE9sTEZObHFYdVpVWXQKdnVCSUg0cmk1YWdIenZjQ1luM2trQk1wOFltc3h0ZTRXU1BLUkJ0eWJXTjFuWHFITGcwNDJoSXMzRXlTVmg1MAp0UUtDQVFBdEVtbDVEQWVncjZyaWlHdnVBWkJDa3JuV1YweUZjN2NIbEVHMkFYaCs0OGkxQjNhQXRPNCttZVlzCkZzdERGdHJITGVOd2tKckhzOG0xbXhsWUVjZzdZYy96MmhNQXlNVk9ONWRuMW13QVA1dEViVzllb2NYYUUyamMKeXREbXFsUmMxMk5uRGprT1pIWWRQZ1lORHg2UkhsSHJEVUdKN1BnaHB0SkFFOVhBNk5YQTMrYkZrZGN6RVZNRgpuY2NERGlWNE1yenJib1lZS2xCMzdNWG40S3dVQWdlaFMvdXZBSGUvZjVTLzBUTG1GVkVqWC9nTnNma0tyMzgwCnhoSTJxb2RmbGMvRHRBcFUvU0hJSFZjUklteGFtTHZWZUFSS2c3eFJJejZjY2hET24vbUlEOVRqZUQ1NjJzQWoKRkJwOWNoL3ZObm9IMXhLZWVGUWJWa2FHRFpsVgotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg== + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + 0 + + 1400 + + + + + + 1 + 0 + 8080 + 8443 + + + + + 0 + + + + + + 0 + 10 + h1,h2 + + + + + 0 + 0 + 10 + + + + + + + 0 + + + + 0 + + + + + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + lan + + + + + + 0 + 0 + + + 1 + + 1 + + 0 + 1 + + 0 + 0 + 0 + 0 + + 1 + + * + apps.sttest0.harmony.mcd + 0 + 192.168.40.1 + + + + + 0 + + + + + + + api + sttest0.harmony.mcd + 0 + 192.168.40.1 + + + + + 0 + + + + + + + api-int + sttest0.harmony.mcd + 0 + 192.168.40.1 + + + + + 0 + + + + + + + cp0 + sttest0.harmony.mcd + 1 + 192.168.40.20 + + + f4:39:09:16:65:ea + + 0 + + + + + + + cp1 + sttest0.harmony.mcd + 1 + 192.168.40.21 + + + f4:39:09:16:65:33 + + 0 + + + + + + + cp2 + sttest0.harmony.mcd + 1 + 192.168.40.22 + + + f4:39:09:07:c8:f2 + + 0 + + + + + + + wk0 + sttest0.harmony.mcd + 1 + 192.168.40.30 + + + 64:00:6a:88:a3:50 + + 0 + + + + + + + lan + + 192.168.40.101 + 192.168.40.151 + + + + + + range + + 0 + + + + + + + + + diff --git a/opnsense-config/src/tests/data/config-opnsense-25.1.xml b/opnsense-config/src/tests/data/config-opnsense-25.1.xml index 0c9a6f11..1df9dc10 100644 --- a/opnsense-config/src/tests/data/config-opnsense-25.1.xml +++ b/opnsense-config/src/tests/data/config-opnsense-25.1.xml @@ -30,28 +30,17 @@ net.inet.ip.sourceroute default - - Source routing is another way for an attacker to try to reach non-routable addresses behind your box. - It can also be used to probe for information about your internal networks. These functions come enabled - as part of the standard FreeBSD core system. - + Source routing is another way for an attacker to try to reach non-routable addresses behind your box. It can also be used to probe for information about your internal networks. These functions come enabled as part of the standard FreeBSD core system. net.inet.ip.accept_sourceroute default - - Source routing is another way for an attacker to try to reach non-routable addresses behind your box. - It can also be used to probe for information about your internal networks. These functions come enabled - as part of the standard FreeBSD core system. - + Source routing is another way for an attacker to try to reach non-routable addresses behind your box. It can also be used to probe for information about your internal networks. These functions come enabled as part of the standard FreeBSD core system. net.inet.icmp.log_redirect default - - This option turns off the logging of redirect packets because there is no limit and this could fill - up your logs consuming your whole hard drive. - + This option turns off the logging of redirect packets because there is no limit and this could fill up your logs consuming your whole hard drive. net.inet.tcp.drop_synfin @@ -181,9 +170,7 @@ net.inet.ip.redirect default - Enable/disable sending of ICMP redirects in response to IP packets for which a better, - and for the sender directly reachable, route and next hop is known. - + Enable/disable sending of ICMP redirects in response to IP packets for which a better, and for the sender directly reachable, route and next hop is known. net.local.dgram.maxdgram @@ -938,4 +925,3 @@ - -- 2.39.5 From 3e2d94cff0561e209bb72283a94c06ff8ff89d34 Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Thu, 22 Jan 2026 14:54:39 -0500 Subject: [PATCH 13/14] adding Cargo.lock --- Cargo.lock | 100 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aabfb9d2..1c7e1d69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1754,6 +1754,24 @@ dependencies = [ "url", ] +[[package]] +name = "example-ha-cluster" +version = "0.1.0" +dependencies = [ + "brocade", + "cidr", + "env_logger", + "harmony", + "harmony_macros", + "harmony_secret", + "harmony_tui", + "harmony_types", + "log", + "serde", + "tokio", + "url", +] + [[package]] name = "example-kube-rs" version = "0.1.0" @@ -1942,9 +1960,28 @@ dependencies = [ "cidr", "env_logger", "harmony", + "harmony_cli", "harmony_macros", "harmony_secret", - "harmony_tui", + "harmony_types", + "log", + "serde", + "tokio", + "url", +] + +[[package]] +name = "example-opnsense-node-exporter" +version = "0.1.0" +dependencies = [ + "async-trait", + "cidr", + "env_logger", + "harmony", + "harmony_cli", + "harmony_macros", + "harmony_secret", + "harmony_secret_derive", "harmony_types", "log", "serde", @@ -1982,25 +2019,6 @@ dependencies = [ "url", ] -[[package]] -name = "example-opnsense-node-exporter" -version = "0.1.0" -dependencies = [ - "async-trait", - "cidr", - "env_logger", - "harmony", - "harmony_cli", - "harmony_macros", - "harmony_secret", - "harmony_secret_derive", - "harmony_types", - "log", - "serde", - "tokio", - "url", -] - [[package]] name = "example-pxe" version = "0.1.0" @@ -3464,6 +3482,25 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "json-prompt" +version = "0.1.0" +dependencies = [ + "brocade", + "cidr", + "env_logger", + "harmony", + "harmony_cli", + "harmony_macros", + "harmony_secret", + "harmony_secret_derive", + "harmony_types", + "log", + "serde", + "tokio", + "url", +] + [[package]] name = "jsonpath-rust" version = "0.7.5" @@ -6062,6 +6099,25 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "sttest" +version = "0.1.0" +dependencies = [ + "brocade", + "cidr", + "env_logger", + "harmony", + "harmony_cli", + "harmony_macros", + "harmony_secret", + "harmony_secret_derive", + "harmony_types", + "log", + "serde", + "tokio", + "url", +] + [[package]] name = "subtle" version = "2.6.1" @@ -7357,7 +7413,7 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yaserde" version = "0.12.0" -source = "git+https://github.com/jggc/yaserde.git#adfdb1c5f4d054f114e5bd0ea7bda9c07a369def" +source = "git+https://github.com/jggc/yaserde.git#2eacb304113beee7270a10b81046d40ed3a99550" dependencies = [ "log", "xml-rs", @@ -7366,7 +7422,7 @@ dependencies = [ [[package]] name = "yaserde_derive" version = "0.12.0" -source = "git+https://github.com/jggc/yaserde.git#adfdb1c5f4d054f114e5bd0ea7bda9c07a369def" +source = "git+https://github.com/jggc/yaserde.git#2eacb304113beee7270a10b81046d40ed3a99550" dependencies = [ "heck", "log", -- 2.39.5 From c631b3aef9fbd0b57290215e16ff46c369af0648 Mon Sep 17 00:00:00 2001 From: Sylvain Tremblay Date: Thu, 22 Jan 2026 15:54:19 -0500 Subject: [PATCH 14/14] fix more opnsense stuff, remove installation notes --- examples/sttest/installation-notes.txt | 137 ------------------ opnsense-config-xml/src/data/caddy.rs | 2 + opnsense-config-xml/src/data/haproxy.rs | 2 +- opnsense-config-xml/src/data/opnsense.rs | 4 +- opnsense-config/src/config/config.rs | 2 +- .../src/tests/data/config-full-ncd0.xml | 1 - .../src/tests/data/config-vm-test.xml | 21 +-- 7 files changed, 10 insertions(+), 159 deletions(-) delete mode 100644 examples/sttest/installation-notes.txt diff --git a/examples/sttest/installation-notes.txt b/examples/sttest/installation-notes.txt deleted file mode 100644 index 82b6e4e3..00000000 --- a/examples/sttest/installation-notes.txt +++ /dev/null @@ -1,137 +0,0 @@ -# Outside Dependency - -[] Get a RedHat PullSecret (free but require registering) - -# Hardware setup - -[] Set clock (watch out UTC vs Local...) -[] No SecureBoot -[] Empty disks -[] Boot order : disk, pxe (as long as when no OS found it falls back to pxe) - -# Opnsense manual stuff - -[] System -> Firmware -> Status : [Check for updates] -> Install all available updates (button down the page) - -[] System -> Settings -> Administration -> TCP port : 443 -> 8443 -[] System -> Settings -> Administration -> Secure Shell Server : [Check] Enable Secure Shell -[] System -> Settings -> Administration -> Root Login : [Check] Permit root user login -[] System -> Settings -> Administration -> Authentication Method : [Check] Permit password login - -[] System -> Settings -> General -> Hostname : fw0 -[] System -> Settings -> General -> Domain : sttest0.harmony.mcd - -[] System -> Services -> Unbound DNS -> General : [UNCHECK] Enable Unbound - -[] System -> Services -> Dnsmasq DNS & DHCP -> General -> Default -> Enable : [Check] -[] System -> Services -> Dnsmasq DNS & DHCP -> General -> DNS -> Listen port : leave blank (remove 0), it will default to 53 - -# Base setup - -[] Create a folder for your installation -[] Copy everything from `harmony/examples/sttest` in your new folder -[] Update `Cargo.toml` -> package name -[] Make sure symlink `data` points to harmony`s `data` folder -[] Update `env.sh` - -> HARMONY_SECRET_NAMESPACE : prefix given to the files containing the secrets in `$HOME/.local/share/harmony` - -> HARMONY_DATABASE_URL : `sqlite://` -[] Update `env.sh` -[] Create an ssh keypair, keep it in your project's root folder (never commit that) -[] Update `src/main.rs` : make sure `cluster's pubkey path` points to your public key - (I think we should change that to take it from the secret instead...? Unless a file is really required...? to check...) -[] Update `src/topology.rs` : replace `IPs`, `Names`, `Domain Name` (match opnsense config), Inventory's `Location` -[] Update `harmony/src/modules/okd/okd_nodes.rs` : impl OKDRoleProperties for WorkerRole : set `required_hosts` to the number of workers you will configure -[] Prepare some json to copy/paste later to feed the secrets (use proper values, these are examples): - opnsense creds: {"username":"root","password":"opnsense"} - ssh keypair: {"private":"-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----","public":"ssh-ed25519 ..."} - redhat pullsecret: {"pull_secret":"{\"auths\":{\"cloud.openshift.com\":{\"auth\":\"...",\"email\":\"...\"},\"quay.io\":{\"auth\":\"...",\"email\":\"..."},\"registry.connect.redhat.com\":{\"auth\":\"...",\"email\":\"..."},\"registry.redhat.io\":{\"auth\":\"...",\"email\":\"..."}}}"} -[] Create an sqlite database (you need sqlite3 on your machine) with two tables - ``` - $ sqlite3 - sqlite> CREATE TABLE IF NOT EXISTS physical_hosts ( - version_id TEXT PRIMARY KEY NOT NULL, - id TEXT NOT NULL, - data JSON NOT NULL); - - sqlite> CREATE INDEX IF NOT EXISTS idx_host_id_time - ON physical_hosts (id, version_id DESC); - CREATE TABLE IF NOT EXISTS host_role_mapping ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - host_id TEXT NOT NULL, - role TEXT NOT NULL - ); - ``` - -# Installation - -## pxe and bootstrap - -[] cd to folder -[] source env file : `. env.sh` -[] `cargo run` -[] feed the secrets when asked (opnsense and sshKeyPair for now) -[] create the hosts as asked on opnsense : Services -> Dnsmasq DNS & DHCP -> Hosts, make sure they dig properly -[] manual copy from the data folder when asked - ** ISSUE ** There is currently a public key in there which will overwrite your own key. We will remove it. - Until then, you can ctrl-c and restart `cargo run`, it will re-copy the right key -[] PXE boot the `bootstrap node`, it should boot the discovery agent image -[] The discovery process should kick in, select the bootstrap node -[] Feed the redhat pull-secret when asked -[] OKD installer will run, prepare all the files in `data/okd/installation_files_` -[] When asked for, do the manual copy of the generated files -[] When asked to reboot the bootstrap node, do it (not automated yet) and make sure it starts in PXE again. If you monitor the console, you should see iPXE finding the byMAC file and boot using the bootstrap ignition file -[] Harmony will then crash on a todo!, the bootstrap process should now be started - -[] edit your main.rs : comment the OKDIpxeScore block and define an empty vec instead -``` - /* - let mut scores: Vec>> = vec![Box::new(OKDIpxeScore { - kickstart_filename: "inventory.kickstart".to_string(), - harmony_inventory_agent: "harmony_inventory_agent".to_string(), - cluster_pubkey: FileContent { - path: FilePath::Relative("cluster_ssh_key.pub".to_string()), - content: ssh_key.public, - }, - })]; - */ - - let mut scores: Vec>> = vec![]; -``` - -## control planes - -[] edit `harmony/src/modules/okd/installation.rs` to comment the scores 01, 02, and `OKDSetupPersistNetworkBondScore` -[] PXE boot the 3 control planes. They should boot the discovery agent image -[] restart harmony : `cargo run` -[] the discovery should find your control planes. select them one by one - -> To check : the first time I made a mistake and selected the bootstrap node. I did ctrl-c and restarted. - Later on, when the dnsmasq have been updated, one of the CPs was wrong, using the mac of the bootstrap. - There may be an issue with the data in the sqllite db when this occurs -[] the byMAC files will be copied -[] when asked for, manually reboot the 3 control planes. They should reboot in pxe with their byMAC files and start the installation process - -> If you have a clock issue (timezone, bad date, whatever) they will loop on a certificate error -[] This will then end harmony in a panic on a todo! because its time to wait for the installation to complete - -## bootstrap cleanup - -[] When the installation is completed, remove the bootstrap node from Dnsmasq : Services ->Dnsmasq DNS & DHCP -> Hosts -[] If you want to recycle the bootstrap as a worker, ssh to it and clean the disk (sgdisk --zap-all, wipefs won't work) - -## workers - -[] pxe boot your workers (reboot the cleaned up bootstrap node), they should boot the inventory agent -[] edit `harmony/src/modules/okd/installation.rs` to comment the score 03 -[] restart harmony -[] select your workers from the discoverInventoryAgent -[] the byMAC files will be copied -[] when asked, reboot your workers. They should now boot on their byMAC configured images -[] harmony will then do its sanity check, installation report and end -[] monitor the cluster for csr `oc get csr` for the new worker nodes (you need to manually approve certs) - you should get two certs to approve for each worker node, in two batches. `oc adm certificate approve ` - - -# Things to know -- Folder where stuff will be saved on your machine (i.e.: local secrets) : `$HOME/.local/share/harmony` -- Folder where generated stuff related to your installation will be saved (including auth infos for the cluster) : `data/okd/installation_files_` -- When hosts are booted with the inventory agent image, you can ssh with `root@host` using the cluster privkey your defined -- When hosts are booted with an okd image, you can ssh with `core@host` using the cluster privkey your defined diff --git a/opnsense-config-xml/src/data/caddy.rs b/opnsense-config-xml/src/data/caddy.rs index 80088b9d..4c150fc2 100644 --- a/opnsense-config-xml/src/data/caddy.rs +++ b/opnsense-config-xml/src/data/caddy.rs @@ -8,6 +8,8 @@ pub struct Pischem { #[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)] pub struct Caddy { + #[yaserde(attribute = true)] + pub version: Option, pub general: CaddyGeneral, pub reverseproxy: MaybeString, } diff --git a/opnsense-config-xml/src/data/haproxy.rs b/opnsense-config-xml/src/data/haproxy.rs index 1114038b..1f96022a 100644 --- a/opnsense-config-xml/src/data/haproxy.rs +++ b/opnsense-config-xml/src/data/haproxy.rs @@ -598,7 +598,7 @@ pub struct HAProxyServer { pub ssl_client_certificate: MaybeString, #[yaserde(rename = "maxConnections")] pub max_connections: MaybeString, - pub weight: Option, + pub weight: Option, #[yaserde(rename = "checkInterval")] pub check_interval: MaybeString, #[yaserde(rename = "checkDownInterval")] diff --git a/opnsense-config-xml/src/data/opnsense.rs b/opnsense-config-xml/src/data/opnsense.rs index 9798d8f5..c1e2acc4 100644 --- a/opnsense-config-xml/src/data/opnsense.rs +++ b/opnsense-config-xml/src/data/opnsense.rs @@ -1256,7 +1256,7 @@ pub struct Host { pub ttl: Option, pub server: String, pub description: Option, - pub txtdata: MaybeString, + pub txtdata: Option, } impl Host { @@ -1272,7 +1272,7 @@ impl Host { ttl: Some(MaybeString::default()), mx: MaybeString::default(), description: None, - txtdata: MaybeString::default(), + txtdata: Some(MaybeString::default()), } } } diff --git a/opnsense-config/src/config/config.rs b/opnsense-config/src/config/config.rs index 1454292d..cbb39ac4 100644 --- a/opnsense-config/src/config/config.rs +++ b/opnsense-config/src/config/config.rs @@ -235,7 +235,7 @@ mod tests { async fn test_load_config_from_local_file() { for path in [ "src/tests/data/config-opnsense-25.1.xml", - // "src/tests/data/config-vm-test.xml", + "src/tests/data/config-vm-test.xml", "src/tests/data/config-structure.xml", "src/tests/data/config-full-1.xml", // "src/tests/data/config-full-ncd0.xml", diff --git a/opnsense-config/src/tests/data/config-full-ncd0.xml b/opnsense-config/src/tests/data/config-full-ncd0.xml index 6cb61861..b14d3b2f 100644 --- a/opnsense-config/src/tests/data/config-full-ncd0.xml +++ b/opnsense-config/src/tests/data/config-full-ncd0.xml @@ -271,7 +271,6 @@ en_US 1.1.1.1 - 8.8.8.8 none none none diff --git a/opnsense-config/src/tests/data/config-vm-test.xml b/opnsense-config/src/tests/data/config-vm-test.xml index 06429df6..ffa78ba1 100644 --- a/opnsense-config/src/tests/data/config-vm-test.xml +++ b/opnsense-config/src/tests/data/config-vm-test.xml @@ -28,28 +28,17 @@ default - - Source routing is another way for an attacker to try to reach non-routable addresses behind your box. - It can also be used to probe for information about your internal networks. These functions come enabled - as part of the standard FreeBSD core system. - + Source routing is another way for an attacker to try to reach non-routable addresses behind your box. It can also be used to probe for information about your internal networks. These functions come enabled as part of the standard FreeBSD core system. net.inet.ip.sourceroute default - - Source routing is another way for an attacker to try to reach non-routable addresses behind your box. - It can also be used to probe for information about your internal networks. These functions come enabled - as part of the standard FreeBSD core system. - + Source routing is another way for an attacker to try to reach non-routable addresses behind your box. It can also be used to probe for information about your internal networks. These functions come enabled as part of the standard FreeBSD core system. net.inet.ip.accept_sourceroute default - - This option turns off the logging of redirect packets because there is no limit and this could fill - up your logs consuming your whole hard drive. - + This option turns off the logging of redirect packets because there is no limit and this could fill up your logs consuming your whole hard drive. net.inet.icmp.log_redirect default @@ -179,9 +168,7 @@ default - Enable/disable sending of ICMP redirects in response to IP packets for which a better, - and for the sender directly reachable, route and next hop is known. - + Enable/disable sending of ICMP redirects in response to IP packets for which a better, and for the sender directly reachable, route and next hop is known. net.inet.ip.redirect default -- 2.39.5