//! Server deployment configuration. //! //! Reads from environment variables to select adapter (local/redis/nats) //! and WebTransport settings. use std::env; /// Adapter + message bus configuration for multi-node scale-out. #[derive(Debug, Clone)] pub struct DeployConfig { /// "local" | "redis" | "nats" pub adapter_mode: String, /// Redis cluster nodes, comma-separated host:port pairs. /// Example: "redis1:6379,redis2:6379,redis3:6379" pub redis_cluster_nodes: String, /// Redis password (optional). pub redis_password: String, /// NATS connection URL (used when adapter_mode = "nats"). pub nats_url: String, /// Unique server ID for this node. pub server_id: String, /// Enable WebTransport server. pub webtransport_enabled: bool, /// WebTransport listen port. pub webtransport_port: u16, /// TLS certificate path (required for WebTransport). pub cert_path: String, /// TLS key path (required for WebTransport). pub key_path: String, } impl DeployConfig { pub fn from_env() -> Self { let server_id = env::var("IMKS_SERVER_ID").unwrap_or_else(|_| hostname()); Self { adapter_mode: env::var("IMKS_ADAPTER").unwrap_or_else(|_| "local".into()), redis_cluster_nodes: env::var("IMKS_REDIS_CLUSTER_NODES") .unwrap_or_else(|_| "localhost:6379,localhost:6380,localhost:6381".into()), redis_password: env::var("IMKS_REDIS_PASSWORD").unwrap_or_default(), nats_url: env::var("IMKS_NATS_URL").unwrap_or_else(|_| "nats://localhost:4222".into()), server_id, webtransport_enabled: env::var("IMKS_WT_ENABLED") .map(|v| v == "true" || v == "1") .unwrap_or(false), webtransport_port: env::var("IMKS_WT_PORT") .ok() .and_then(|v| v.parse().ok()) .unwrap_or(3001), cert_path: env::var("IMKS_WT_CERT_PATH").unwrap_or_default(), key_path: env::var("IMKS_WT_KEY_PATH").unwrap_or_default(), } } /// Build a redis-cluster URL from cluster_nodes and optional password. /// Format: redis-cluster://[:password@]host1:port1,host2:port2,... pub fn redis_cluster_url(&self) -> String { let auth = if self.redis_password.is_empty() { String::new() } else { format!(":{}@", self.redis_password) }; format!("redis-cluster://{}{}", auth, self.redis_cluster_nodes) } } impl Default for DeployConfig { fn default() -> Self { Self::from_env() } } fn hostname() -> String { env::var("HOSTNAME") .or_else(|_| env::var("HOST")) .unwrap_or_else(|_| "imks-node-1".into()) }