1use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5use std::time::Duration;
6
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
9pub struct AgentConfig {
10 pub deployment_name: String,
12
13 pub node_id: String,
15
16 #[serde(default)]
18 pub raft: RaftConfig,
19
20 #[serde(default)]
22 pub overlay: OverlayAgentConfig,
23
24 #[serde(default = "default_data_dir")]
26 pub data_dir: PathBuf,
27
28 #[serde(default)]
30 pub metrics: MetricsConfig,
31
32 #[serde(default)]
34 pub logging: LoggingConfig,
35
36 #[serde(default)]
38 pub auth: crate::auth::AuthConfig,
39}
40
41fn default_data_dir() -> PathBuf {
42 zlayer_paths::ZLayerDirs::default_data_dir()
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
47pub struct RaftConfig {
48 pub raft_addr: String,
50
51 pub advertise_addr: Option<String>,
53
54 #[serde(default = "default_snapshot_threshold")]
56 pub snapshot_threshold: u64,
57
58 #[serde(default = "default_snapshot_policy_count")]
60 pub snapshot_policy_count: u64,
61
62 #[serde(default = "default_election_timeout_min")]
64 pub election_timeout_min: u64,
65
66 #[serde(default = "default_election_timeout_max")]
68 pub election_timeout_max: u64,
69
70 #[serde(default = "default_heartbeat_interval")]
72 pub heartbeat_interval: u64,
73}
74
75impl Default for RaftConfig {
76 fn default() -> Self {
77 Self {
78 raft_addr: "0.0.0.0:27001".to_string(),
79 advertise_addr: None,
80 snapshot_threshold: default_snapshot_threshold(),
81 snapshot_policy_count: default_snapshot_policy_count(),
82 election_timeout_min: default_election_timeout_min(),
83 election_timeout_max: default_election_timeout_max(),
84 heartbeat_interval: default_heartbeat_interval(),
85 }
86 }
87}
88
89fn default_snapshot_threshold() -> u64 {
90 10000
91}
92
93fn default_snapshot_policy_count() -> u64 {
94 8000
95}
96
97fn default_election_timeout_min() -> u64 {
98 150
99}
100
101fn default_election_timeout_max() -> u64 {
102 300
103}
104
105fn default_heartbeat_interval() -> u64 {
106 50
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
111pub struct OverlayAgentConfig {
112 pub private_key: String,
114
115 pub public_key: Option<String>,
117
118 #[serde(default = "default_wg_port")]
120 pub wg_port: u16,
121
122 #[serde(default)]
124 pub global: GlobalOverlayConfig,
125
126 #[serde(default)]
128 pub dns: DnsConfig,
129}
130
131impl Default for OverlayAgentConfig {
132 fn default() -> Self {
133 Self {
134 private_key: String::new(),
135 public_key: None,
136 wg_port: default_wg_port(),
137 global: GlobalOverlayConfig::default(),
138 dns: DnsConfig::default(),
139 }
140 }
141}
142
143fn default_wg_port() -> u16 {
144 51820
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
149pub struct GlobalOverlayConfig {
150 #[serde(default = "default_overlay_cidr")]
152 pub overlay_cidr: String,
153
154 #[serde(default = "default_peer_discovery")]
156 pub peer_discovery_interval: Duration,
157}
158
159impl Default for GlobalOverlayConfig {
160 fn default() -> Self {
161 Self {
162 overlay_cidr: default_overlay_cidr(),
163 peer_discovery_interval: default_peer_discovery(),
164 }
165 }
166}
167
168fn default_overlay_cidr() -> String {
169 "10.0.0.0/8".to_string()
170}
171
172fn default_peer_discovery() -> Duration {
173 Duration::from_secs(30)
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
178pub struct DnsConfig {
179 #[serde(default = "default_dns_addr")]
181 pub listen_addr: String,
182
183 #[serde(default = "default_global_tld")]
185 pub global_tld: String,
186
187 #[serde(default = "default_service_tld")]
189 pub service_tld: String,
190}
191
192impl Default for DnsConfig {
193 fn default() -> Self {
194 Self {
195 listen_addr: default_dns_addr(),
196 global_tld: default_global_tld(),
197 service_tld: default_service_tld(),
198 }
199 }
200}
201
202fn default_dns_addr() -> String {
203 "0.0.0.0:53".to_string()
204}
205
206fn default_global_tld() -> String {
207 "global".to_string()
208}
209
210fn default_service_tld() -> String {
211 "service".to_string()
212}
213
214#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
216pub struct MetricsConfig {
217 #[serde(default = "default_metrics_enabled")]
219 pub enabled: bool,
220
221 #[serde(default = "default_metrics_addr")]
223 pub listen_addr: String,
224
225 #[serde(default = "default_metrics_path")]
227 pub path: String,
228}
229
230impl Default for MetricsConfig {
231 fn default() -> Self {
232 Self {
233 enabled: default_metrics_enabled(),
234 listen_addr: default_metrics_addr(),
235 path: default_metrics_path(),
236 }
237 }
238}
239
240fn default_metrics_enabled() -> bool {
241 true
242}
243
244fn default_metrics_addr() -> String {
245 "0.0.0.0:9090".to_string()
246}
247
248fn default_metrics_path() -> String {
249 "/metrics".to_string()
250}
251
252#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
254pub struct LoggingConfig {
255 #[serde(default = "default_log_level")]
257 pub level: String,
258
259 #[serde(default = "default_log_format")]
261 pub format: String,
262
263 #[serde(default = "default_log_stdout")]
265 pub stdout: bool,
266
267 pub file: Option<PathBuf>,
269}
270
271impl Default for LoggingConfig {
272 fn default() -> Self {
273 Self {
274 level: default_log_level(),
275 format: default_log_format(),
276 stdout: default_log_stdout(),
277 file: None,
278 }
279 }
280}
281
282fn default_log_level() -> String {
283 "info".to_string()
284}
285
286fn default_log_format() -> String {
287 "json".to_string()
288}
289
290fn default_log_stdout() -> bool {
291 true
292}
293
294#[cfg(test)]
295mod tests {
296 use super::*;
297
298 #[test]
299 fn test_agent_config_default() {
300 let config = AgentConfig {
301 deployment_name: "test".to_string(),
302 node_id: "node-1".to_string(),
303 ..Default::default()
304 };
305 assert_eq!(config.deployment_name, "test");
306 assert_eq!(config.node_id, "node-1");
307 }
308}