feat(config): integrate etcd-based configuration management
- Add etcd-client dependency with TLS support - Implement EtcdConfig struct for reading config values with priority: etcd > env > default - Add ServiceRegistry for service discovery registration in etcd - Create from_etcd method in AppConfig for loading SMTP configuration - Update main.rs to use etcd-based config loading with fallback mechanism - Add etcd module with client connection and key-value operations - Modify Dockerfile to use cargo-chef for faster builds - Add docker-compose.yaml for emailks service deployment - Include AGENTS.md with development guidelines and best practices - Add build.sh script for podman-based container building - Update dependencies in Cargo.toml and Cargo.lock
This commit is contained in:
@@ -54,6 +54,43 @@ pub enum SmtpTls {
|
||||
}
|
||||
|
||||
impl AppConfig {
|
||||
pub fn from_etcd(
|
||||
host: String, port: u16, username: String, password: String,
|
||||
from_email: String, from_name: String, reply_to: String,
|
||||
tls: String, timeout_secs: u64, helo_name: String, allow_request_from: bool,
|
||||
queue_capacity: Option<usize>,
|
||||
listen_addr_str: &str,
|
||||
) -> Result<Self, ConfigError> {
|
||||
let tls = match tls.trim().to_ascii_lowercase().as_str() {
|
||||
"none" | "false" | "0" => SmtpTls::None,
|
||||
"starttls" | "start_tls" | "start-tls" => SmtpTls::StartTls,
|
||||
"tls" | "ssl" | "smtps" => SmtpTls::Tls,
|
||||
_ => SmtpTls::StartTls,
|
||||
};
|
||||
|
||||
validate_port("PORT", port)?;
|
||||
|
||||
Ok(Self {
|
||||
smtp: SmtpConfig {
|
||||
host,
|
||||
port,
|
||||
username: if username.is_empty() { None } else { Some(username) },
|
||||
password: if password.is_empty() { None } else { Some(password) },
|
||||
from_email: if from_email.is_empty() { None } else { Some(from_email) },
|
||||
from_name: if from_name.is_empty() { None } else { Some(from_name) },
|
||||
reply_to: if reply_to.is_empty() { None } else { Some(reply_to) },
|
||||
tls,
|
||||
timeout: std::time::Duration::from_secs(timeout_secs),
|
||||
helo_name: if helo_name.is_empty() { None } else { Some(helo_name) },
|
||||
allow_request_from,
|
||||
},
|
||||
queue_capacity,
|
||||
listen_addr: listen_addr_str
|
||||
.parse::<std::net::SocketAddr>()
|
||||
.map_err(|e: std::net::AddrParseError| ConfigError::InvalidEnv { name: "LISTEN_ADDR", reason: e.to_string() })?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_env() -> Result<Self, ConfigError> {
|
||||
let _ = dotenvy::dotenv();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user