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
143pub const DEFAULT_WG_PORT: u16 = 51420;
145
146fn default_wg_port() -> u16 {
147 DEFAULT_WG_PORT
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
152pub struct GlobalOverlayConfig {
153 #[serde(default = "default_overlay_cidr")]
155 pub overlay_cidr: String,
156
157 #[serde(default = "default_peer_discovery")]
159 pub peer_discovery_interval: Duration,
160}
161
162impl Default for GlobalOverlayConfig {
163 fn default() -> Self {
164 Self {
165 overlay_cidr: default_overlay_cidr(),
166 peer_discovery_interval: default_peer_discovery(),
167 }
168 }
169}
170
171fn default_overlay_cidr() -> String {
172 "10.0.0.0/8".to_string()
173}
174
175fn default_peer_discovery() -> Duration {
176 Duration::from_secs(30)
177}
178
179#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
181pub struct DnsConfig {
182 #[serde(default = "default_dns_addr")]
184 pub listen_addr: String,
185
186 #[serde(default = "default_global_tld")]
188 pub global_tld: String,
189
190 #[serde(default = "default_service_tld")]
192 pub service_tld: String,
193}
194
195impl Default for DnsConfig {
196 fn default() -> Self {
197 Self {
198 listen_addr: default_dns_addr(),
199 global_tld: default_global_tld(),
200 service_tld: default_service_tld(),
201 }
202 }
203}
204
205fn default_dns_addr() -> String {
206 "0.0.0.0:53".to_string()
207}
208
209fn default_global_tld() -> String {
210 "global".to_string()
211}
212
213fn default_service_tld() -> String {
214 "service".to_string()
215}
216
217#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
219pub struct MetricsConfig {
220 #[serde(default = "default_metrics_enabled")]
222 pub enabled: bool,
223
224 #[serde(default = "default_metrics_addr")]
226 pub listen_addr: String,
227
228 #[serde(default = "default_metrics_path")]
230 pub path: String,
231}
232
233impl Default for MetricsConfig {
234 fn default() -> Self {
235 Self {
236 enabled: default_metrics_enabled(),
237 listen_addr: default_metrics_addr(),
238 path: default_metrics_path(),
239 }
240 }
241}
242
243fn default_metrics_enabled() -> bool {
244 true
245}
246
247fn default_metrics_addr() -> String {
248 "0.0.0.0:9090".to_string()
249}
250
251fn default_metrics_path() -> String {
252 "/metrics".to_string()
253}
254
255#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
257pub struct LoggingConfig {
258 #[serde(default = "default_log_level")]
260 pub level: String,
261
262 #[serde(default = "default_log_format")]
264 pub format: String,
265
266 #[serde(default = "default_log_stdout")]
268 pub stdout: bool,
269
270 pub file: Option<PathBuf>,
272}
273
274impl Default for LoggingConfig {
275 fn default() -> Self {
276 Self {
277 level: default_log_level(),
278 format: default_log_format(),
279 stdout: default_log_stdout(),
280 file: None,
281 }
282 }
283}
284
285fn default_log_level() -> String {
286 "info".to_string()
287}
288
289fn default_log_format() -> String {
290 "json".to_string()
291}
292
293fn default_log_stdout() -> bool {
294 true
295}
296
297#[cfg(test)]
298mod tests {
299 use super::*;
300
301 #[test]
302 fn test_agent_config_default() {
303 let config = AgentConfig {
304 deployment_name: "test".to_string(),
305 node_id: "node-1".to_string(),
306 ..Default::default()
307 };
308 assert_eq!(config.deployment_name, "test");
309 assert_eq!(config.node_id, "node-1");
310 }
311}