use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct AgentConfig {
pub deployment_name: String,
pub node_id: String,
#[serde(default)]
pub raft: RaftConfig,
#[serde(default)]
pub overlay: OverlayAgentConfig,
#[serde(default = "default_data_dir")]
pub data_dir: PathBuf,
#[serde(default)]
pub metrics: MetricsConfig,
#[serde(default)]
pub logging: LoggingConfig,
#[serde(default)]
pub auth: crate::auth::AuthConfig,
}
fn default_data_dir() -> PathBuf {
zlayer_paths::ZLayerDirs::default_data_dir()
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RaftConfig {
pub raft_addr: String,
pub advertise_addr: Option<String>,
#[serde(default = "default_snapshot_threshold")]
pub snapshot_threshold: u64,
#[serde(default = "default_snapshot_policy_count")]
pub snapshot_policy_count: u64,
#[serde(default = "default_election_timeout_min")]
pub election_timeout_min: u64,
#[serde(default = "default_election_timeout_max")]
pub election_timeout_max: u64,
#[serde(default = "default_heartbeat_interval")]
pub heartbeat_interval: u64,
}
impl Default for RaftConfig {
fn default() -> Self {
Self {
raft_addr: "0.0.0.0:27001".to_string(),
advertise_addr: None,
snapshot_threshold: default_snapshot_threshold(),
snapshot_policy_count: default_snapshot_policy_count(),
election_timeout_min: default_election_timeout_min(),
election_timeout_max: default_election_timeout_max(),
heartbeat_interval: default_heartbeat_interval(),
}
}
}
fn default_snapshot_threshold() -> u64 {
10000
}
fn default_snapshot_policy_count() -> u64 {
8000
}
fn default_election_timeout_min() -> u64 {
150
}
fn default_election_timeout_max() -> u64 {
300
}
fn default_heartbeat_interval() -> u64 {
50
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct OverlayAgentConfig {
pub private_key: String,
pub public_key: Option<String>,
#[serde(default = "default_wg_port")]
pub wg_port: u16,
#[serde(default)]
pub global: GlobalOverlayConfig,
#[serde(default)]
pub dns: DnsConfig,
}
impl Default for OverlayAgentConfig {
fn default() -> Self {
Self {
private_key: String::new(),
public_key: None,
wg_port: default_wg_port(),
global: GlobalOverlayConfig::default(),
dns: DnsConfig::default(),
}
}
}
pub const DEFAULT_WG_PORT: u16 = 51420;
fn default_wg_port() -> u16 {
DEFAULT_WG_PORT
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct GlobalOverlayConfig {
#[serde(default = "default_overlay_cidr")]
pub overlay_cidr: String,
#[serde(default = "default_peer_discovery")]
pub peer_discovery_interval: Duration,
}
impl Default for GlobalOverlayConfig {
fn default() -> Self {
Self {
overlay_cidr: default_overlay_cidr(),
peer_discovery_interval: default_peer_discovery(),
}
}
}
fn default_overlay_cidr() -> String {
"10.0.0.0/8".to_string()
}
fn default_peer_discovery() -> Duration {
Duration::from_secs(30)
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DnsConfig {
#[serde(default = "default_dns_addr")]
pub listen_addr: String,
#[serde(default = "default_global_tld")]
pub global_tld: String,
#[serde(default = "default_service_tld")]
pub service_tld: String,
}
impl Default for DnsConfig {
fn default() -> Self {
Self {
listen_addr: default_dns_addr(),
global_tld: default_global_tld(),
service_tld: default_service_tld(),
}
}
}
fn default_dns_addr() -> String {
"0.0.0.0:53".to_string()
}
fn default_global_tld() -> String {
"global".to_string()
}
fn default_service_tld() -> String {
"service".to_string()
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct MetricsConfig {
#[serde(default = "default_metrics_enabled")]
pub enabled: bool,
#[serde(default = "default_metrics_addr")]
pub listen_addr: String,
#[serde(default = "default_metrics_path")]
pub path: String,
}
impl Default for MetricsConfig {
fn default() -> Self {
Self {
enabled: default_metrics_enabled(),
listen_addr: default_metrics_addr(),
path: default_metrics_path(),
}
}
}
fn default_metrics_enabled() -> bool {
true
}
fn default_metrics_addr() -> String {
"0.0.0.0:9090".to_string()
}
fn default_metrics_path() -> String {
"/metrics".to_string()
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct LoggingConfig {
#[serde(default = "default_log_level")]
pub level: String,
#[serde(default = "default_log_format")]
pub format: String,
#[serde(default = "default_log_stdout")]
pub stdout: bool,
pub file: Option<PathBuf>,
}
impl Default for LoggingConfig {
fn default() -> Self {
Self {
level: default_log_level(),
format: default_log_format(),
stdout: default_log_stdout(),
file: None,
}
}
}
fn default_log_level() -> String {
"info".to_string()
}
fn default_log_format() -> String {
"json".to_string()
}
fn default_log_stdout() -> bool {
true
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_agent_config_default() {
let config = AgentConfig {
deployment_name: "test".to_string(),
node_id: "node-1".to_string(),
..Default::default()
};
assert_eq!(config.deployment_name, "test");
assert_eq!(config.node_id, "node-1");
}
}