use k8s_openapi::api::core::v1::ConfigMap; use kube::api::ObjectMeta; use kube::Resource; use crate::types::{Listener, SojuBouncer, SojuBouncerSpec}; pub fn build_configmap(bouncer: &SojuBouncer, db_uri: &str) -> ConfigMap { let name = bouncer.metadata.name.clone().unwrap(); let ns = bouncer.metadata.namespace.clone().unwrap(); let oref = bouncer.controller_owner_ref(&()).unwrap(); let config = generate_soju_config(&bouncer.spec, db_uri); ConfigMap { metadata: ObjectMeta { name: Some(format!("{name}-config")), namespace: Some(ns), owner_references: Some(vec![oref]), ..Default::default() }, data: Some([("config".to_string(), config)].into()), ..Default::default() } } fn generate_soju_config(spec: &SojuBouncerSpec, db_uri: &str) -> String { let mut lines = Vec::new(); lines.push(format!("hostname {}", spec.hostname)); if let Some(title) = &spec.title { lines.push(format!("title \"{title}\"")); } if spec.tls.is_some() { lines.push("tls /etc/soju/tls/tls.crt /etc/soju/tls/tls.key".to_string()); } for listener in &spec.listeners { lines.push(format!("listen {}", listener_uri(listener))); } lines.push(format!("db postgres \"{db_uri}\"")); lines.push("message-store db".to_string()); lines.push("auth internal".to_string()); lines.join("\n") } fn listener_uri(listener: &Listener) -> String { let addr = &listener.address; let host_port = if addr.starts_with(':') { format!("0.0.0.0{addr}") } else { addr.clone() }; if listener.tls { format!("ircs://{host_port}") } else { format!("irc+insecure://{host_port}") } } #[cfg(test)] mod tests { use super::*; use crate::testutil::test_bouncer; #[test] fn generates_soju_config_with_listeners() { let db_uri = "host=db.svc port=5432 user=test password=secret dbname=soju_test sslmode=disable"; let cm = build_configmap(&test_bouncer(), db_uri); let data = cm.data.unwrap(); let config = &data["config"]; assert!(config.contains("listen ircs://0.0.0.0:6697")); assert!(config.contains("listen irc+insecure://0.0.0.0:6667")); assert!(config.contains("hostname irc.example.com")); assert!(config.contains("title \"Test Bouncer\"")); assert!(config.contains("tls /etc/soju/tls/tls.crt /etc/soju/tls/tls.key")); assert!(config.contains("db postgres")); } #[test] fn configmap_has_owner_reference() { let cm = build_configmap(&test_bouncer(), "host=localhost dbname=test"); let orefs = cm.metadata.owner_references.unwrap(); assert_eq!(orefs.len(), 1); assert_eq!(orefs[0].name, "test-bouncer"); } #[test] fn configmap_named_correctly() { let cm = build_configmap(&test_bouncer(), "host=localhost dbname=test"); assert_eq!(cm.metadata.name.unwrap(), "test-bouncer-config"); } }