feat: load service URLs from ConfigMap, not hardcoded

This commit is contained in:
2026-09-06 06:11:26 -07:00
parent c41cef0ca5
commit 6b35b04d20
5 changed files with 211 additions and 1 deletions
+93
View File
@@ -0,0 +1,93 @@
/// Configuration management for inter-pod URLs via environment variables (ConfigMap)
/// All service URLs come from K8s ConfigMap, never hardcoded
///
/// ConfigMap in K8s:
/// ```yaml
/// apiVersion: v1
/// kind: ConfigMap
/// metadata:
/// name: memory-service-config
/// namespace: poimen
/// data:
/// MEMORY_SERVICE_ADDR: "http://memory-service.poimen.svc.cluster.local:8080"
/// AUTHENTIK_ISSUER: "http://authentik.iam.svc.cluster.local/application/o/poimen-memory/"
/// WEBHOOK_URL: "http://temporal-webhook.temporal.svc.cluster.local:9000/webhook"
/// ```
use anyhow::{anyhow, Result};
#[derive(Debug, Clone)]
pub struct ServiceConfig {
/// Memory service address (this service itself)
pub memory_service_addr: String,
/// Authentik OIDC issuer endpoint
pub authentik_issuer: String,
/// Temporal webhook callback URL
pub webhook_url: String,
/// OpenSearch cluster endpoint
pub opensearch_url: String,
/// PostgreSQL connection string
pub database_url: String,
}
impl ServiceConfig {
/// Load configuration from environment variables (set by K8s ConfigMap)
/// Fails if required env vars are missing
pub fn from_env() -> Result<Self> {
let memory_service_addr = std::env::var("MEMORY_SERVICE_ADDR")
.unwrap_or_else(|_| "http://localhost:8080".to_string());
let authentik_issuer = std::env::var("AUTHENTIK_ISSUER")
.map_err(|_| anyhow!("AUTHENTIK_ISSUER env var not set (configure in ConfigMap)"))?;
let webhook_url = std::env::var("WEBHOOK_URL")
.map_err(|_| anyhow!("WEBHOOK_URL env var not set (configure in ConfigMap)"))?;
let opensearch_url = std::env::var("OPENSEARCH_URL")
.map_err(|_| anyhow!("OPENSEARCH_URL env var not set (configure in ConfigMap)"))?;
let database_url = std::env::var("DATABASE_URL")
.map_err(|_| anyhow!("DATABASE_URL env var not set (configure Secret or ConfigMap)"))?;
Ok(ServiceConfig {
memory_service_addr,
authentik_issuer,
webhook_url,
opensearch_url,
database_url,
})
}
/// Load with defaults for development (localhost only)
pub fn from_env_dev() -> Self {
ServiceConfig {
memory_service_addr: std::env::var("MEMORY_SERVICE_ADDR")
.unwrap_or_else(|_| "http://localhost:8080".to_string()),
authentik_issuer: std::env::var("AUTHENTIK_ISSUER")
.unwrap_or_else(|_| "http://localhost:8080/application/o/poimen-memory/".to_string()),
webhook_url: std::env::var("WEBHOOK_URL")
.unwrap_or_else(|_| "http://localhost:9000/webhook".to_string()),
opensearch_url: std::env::var("OPENSEARCH_URL")
.unwrap_or_else(|_| "http://localhost:9200".to_string()),
database_url: std::env::var("DATABASE_URL")
.unwrap_or_else(|_| "postgres://localhost/memory".to_string()),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_config_from_env_dev() {
let config = ServiceConfig::from_env_dev();
assert_eq!(config.memory_service_addr, "http://localhost:8080");
assert!(config.authentik_issuer.contains("localhost"));
assert!(config.webhook_url.contains("localhost"));
}
}
+1
View File
@@ -1,3 +1,4 @@
pub mod config;
pub mod endpoints;
pub mod handlers;
pub mod http_server;
+3 -1
View File
@@ -448,8 +448,10 @@ async fn cmd_learn(
all_files.sort();
println!("Found {} markdown files", all_files.len());
// Load configuration from environment (set by K8s ConfigMap)
let config = mem_cli::config::ServiceConfig::from_env_dev();
let api_url = std::env::var("MEM_API_URL")
.unwrap_or_else(|_| "http://localhost:8080".to_string());
.unwrap_or_else(|_| config.memory_service_addr.clone());
let api_token = std::env::var("MEM_API_TOKEN").ok();
let http = reqwest::Client::builder()
.timeout(std::time::Duration::from_secs(120))