1use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5use std::time::Duration;
6use zlayer_types::overlay::OverlayMode;
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
10pub struct AgentConfig {
11 pub deployment_name: String,
13
14 pub node_id: String,
16
17 #[serde(default)]
19 pub raft: RaftConfig,
20
21 #[serde(default)]
23 pub overlay: OverlayAgentConfig,
24
25 #[serde(default = "default_data_dir")]
27 pub data_dir: PathBuf,
28
29 #[serde(default)]
31 pub metrics: MetricsConfig,
32
33 #[serde(default)]
35 pub logging: LoggingConfig,
36
37 #[serde(default)]
39 pub auth: crate::auth::AuthConfig,
40
41 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub overlay_default_mode: Option<OverlayMode>,
47}
48
49fn default_data_dir() -> PathBuf {
50 zlayer_paths::ZLayerDirs::default_data_dir()
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
55pub struct RaftConfig {
56 pub raft_addr: String,
58
59 pub advertise_addr: Option<String>,
61
62 #[serde(default = "default_snapshot_threshold")]
64 pub snapshot_threshold: u64,
65
66 #[serde(default = "default_snapshot_policy_count")]
68 pub snapshot_policy_count: u64,
69
70 #[serde(default = "default_election_timeout_min")]
72 pub election_timeout_min: u64,
73
74 #[serde(default = "default_election_timeout_max")]
76 pub election_timeout_max: u64,
77
78 #[serde(default = "default_heartbeat_interval")]
80 pub heartbeat_interval: u64,
81}
82
83impl Default for RaftConfig {
84 fn default() -> Self {
85 Self {
86 raft_addr: format!("0.0.0.0:{DEFAULT_RAFT_PORT}"),
87 advertise_addr: None,
88 snapshot_threshold: default_snapshot_threshold(),
89 snapshot_policy_count: default_snapshot_policy_count(),
90 election_timeout_min: default_election_timeout_min(),
91 election_timeout_max: default_election_timeout_max(),
92 heartbeat_interval: default_heartbeat_interval(),
93 }
94 }
95}
96
97fn default_snapshot_threshold() -> u64 {
98 10000
99}
100
101fn default_snapshot_policy_count() -> u64 {
102 8000
103}
104
105fn default_election_timeout_min() -> u64 {
106 150
107}
108
109fn default_election_timeout_max() -> u64 {
110 300
111}
112
113fn default_heartbeat_interval() -> u64 {
114 50
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
119pub struct OverlayAgentConfig {
120 pub private_key: String,
122
123 pub public_key: Option<String>,
125
126 #[serde(default = "default_wg_port")]
128 pub wg_port: u16,
129
130 #[serde(default)]
132 pub global: GlobalOverlayConfig,
133
134 #[serde(default)]
136 pub dns: DnsConfig,
137}
138
139impl Default for OverlayAgentConfig {
140 fn default() -> Self {
141 Self {
142 private_key: String::new(),
143 public_key: None,
144 wg_port: default_wg_port(),
145 global: GlobalOverlayConfig::default(),
146 dns: DnsConfig::default(),
147 }
148 }
149}
150
151pub const DEFAULT_WG_PORT: u16 = 51420;
153
154pub const DEFAULT_RAFT_PORT: u16 = 9000;
156
157fn default_wg_port() -> u16 {
158 DEFAULT_WG_PORT
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
163pub struct GlobalOverlayConfig {
164 #[serde(default = "default_overlay_cidr")]
166 pub overlay_cidr: String,
167
168 #[serde(default = "default_peer_discovery")]
170 pub peer_discovery_interval: Duration,
171}
172
173impl Default for GlobalOverlayConfig {
174 fn default() -> Self {
175 Self {
176 overlay_cidr: default_overlay_cidr(),
177 peer_discovery_interval: default_peer_discovery(),
178 }
179 }
180}
181
182fn default_overlay_cidr() -> String {
183 "10.0.0.0/8".to_string()
184}
185
186fn default_peer_discovery() -> Duration {
187 Duration::from_secs(30)
188}
189
190#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
192pub struct DnsConfig {
193 #[serde(default = "default_dns_addr")]
195 pub listen_addr: String,
196
197 #[serde(default = "default_global_tld")]
199 pub global_tld: String,
200
201 #[serde(default = "default_service_tld")]
203 pub service_tld: String,
204}
205
206impl Default for DnsConfig {
207 fn default() -> Self {
208 Self {
209 listen_addr: default_dns_addr(),
210 global_tld: default_global_tld(),
211 service_tld: default_service_tld(),
212 }
213 }
214}
215
216fn default_dns_addr() -> String {
217 "0.0.0.0:53".to_string()
218}
219
220fn default_global_tld() -> String {
221 "global".to_string()
222}
223
224fn default_service_tld() -> String {
225 "service".to_string()
226}
227
228#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
230pub struct MetricsConfig {
231 #[serde(default = "default_metrics_enabled")]
233 pub enabled: bool,
234
235 #[serde(default = "default_metrics_addr")]
237 pub listen_addr: String,
238
239 #[serde(default = "default_metrics_path")]
241 pub path: String,
242}
243
244impl Default for MetricsConfig {
245 fn default() -> Self {
246 Self {
247 enabled: default_metrics_enabled(),
248 listen_addr: default_metrics_addr(),
249 path: default_metrics_path(),
250 }
251 }
252}
253
254fn default_metrics_enabled() -> bool {
255 true
256}
257
258fn default_metrics_addr() -> String {
259 "0.0.0.0:9090".to_string()
260}
261
262fn default_metrics_path() -> String {
263 "/metrics".to_string()
264}
265
266#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
268pub struct LoggingConfig {
269 #[serde(default = "default_log_level")]
271 pub level: String,
272
273 #[serde(default = "default_log_format")]
275 pub format: String,
276
277 #[serde(default = "default_log_stdout")]
279 pub stdout: bool,
280
281 pub file: Option<PathBuf>,
283}
284
285impl Default for LoggingConfig {
286 fn default() -> Self {
287 Self {
288 level: default_log_level(),
289 format: default_log_format(),
290 stdout: default_log_stdout(),
291 file: None,
292 }
293 }
294}
295
296fn default_log_level() -> String {
297 "info".to_string()
298}
299
300fn default_log_format() -> String {
301 "json".to_string()
302}
303
304fn default_log_stdout() -> bool {
305 true
306}
307
308#[cfg(test)]
309mod tests {
310 use super::*;
311
312 #[test]
313 fn test_agent_config_default() {
314 let config = AgentConfig {
315 deployment_name: "test".to_string(),
316 node_id: "node-1".to_string(),
317 ..Default::default()
318 };
319 assert_eq!(config.deployment_name, "test");
320 assert_eq!(config.node_id, "node-1");
321 }
322}