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")]
45 pub overlay_default_mode: Option<OverlayMode>,
46}
47
48fn default_data_dir() -> PathBuf {
49 zlayer_paths::ZLayerDirs::default_data_dir()
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
54pub struct RaftConfig {
55 pub raft_addr: String,
57
58 pub advertise_addr: Option<String>,
60
61 #[serde(default = "default_snapshot_threshold")]
63 pub snapshot_threshold: u64,
64
65 #[serde(default = "default_snapshot_policy_count")]
67 pub snapshot_policy_count: u64,
68
69 #[serde(default = "default_election_timeout_min")]
71 pub election_timeout_min: u64,
72
73 #[serde(default = "default_election_timeout_max")]
75 pub election_timeout_max: u64,
76
77 #[serde(default = "default_heartbeat_interval")]
79 pub heartbeat_interval: u64,
80}
81
82impl Default for RaftConfig {
83 fn default() -> Self {
84 Self {
85 raft_addr: "0.0.0.0:27001".to_string(),
86 advertise_addr: None,
87 snapshot_threshold: default_snapshot_threshold(),
88 snapshot_policy_count: default_snapshot_policy_count(),
89 election_timeout_min: default_election_timeout_min(),
90 election_timeout_max: default_election_timeout_max(),
91 heartbeat_interval: default_heartbeat_interval(),
92 }
93 }
94}
95
96fn default_snapshot_threshold() -> u64 {
97 10000
98}
99
100fn default_snapshot_policy_count() -> u64 {
101 8000
102}
103
104fn default_election_timeout_min() -> u64 {
105 150
106}
107
108fn default_election_timeout_max() -> u64 {
109 300
110}
111
112fn default_heartbeat_interval() -> u64 {
113 50
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
118pub struct OverlayAgentConfig {
119 pub private_key: String,
121
122 pub public_key: Option<String>,
124
125 #[serde(default = "default_wg_port")]
127 pub wg_port: u16,
128
129 #[serde(default)]
131 pub global: GlobalOverlayConfig,
132
133 #[serde(default)]
135 pub dns: DnsConfig,
136}
137
138impl Default for OverlayAgentConfig {
139 fn default() -> Self {
140 Self {
141 private_key: String::new(),
142 public_key: None,
143 wg_port: default_wg_port(),
144 global: GlobalOverlayConfig::default(),
145 dns: DnsConfig::default(),
146 }
147 }
148}
149
150pub const DEFAULT_WG_PORT: u16 = 51420;
152
153fn default_wg_port() -> u16 {
154 DEFAULT_WG_PORT
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
159pub struct GlobalOverlayConfig {
160 #[serde(default = "default_overlay_cidr")]
162 pub overlay_cidr: String,
163
164 #[serde(default = "default_peer_discovery")]
166 pub peer_discovery_interval: Duration,
167}
168
169impl Default for GlobalOverlayConfig {
170 fn default() -> Self {
171 Self {
172 overlay_cidr: default_overlay_cidr(),
173 peer_discovery_interval: default_peer_discovery(),
174 }
175 }
176}
177
178fn default_overlay_cidr() -> String {
179 "10.0.0.0/8".to_string()
180}
181
182fn default_peer_discovery() -> Duration {
183 Duration::from_secs(30)
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
188pub struct DnsConfig {
189 #[serde(default = "default_dns_addr")]
191 pub listen_addr: String,
192
193 #[serde(default = "default_global_tld")]
195 pub global_tld: String,
196
197 #[serde(default = "default_service_tld")]
199 pub service_tld: String,
200}
201
202impl Default for DnsConfig {
203 fn default() -> Self {
204 Self {
205 listen_addr: default_dns_addr(),
206 global_tld: default_global_tld(),
207 service_tld: default_service_tld(),
208 }
209 }
210}
211
212fn default_dns_addr() -> String {
213 "0.0.0.0:53".to_string()
214}
215
216fn default_global_tld() -> String {
217 "global".to_string()
218}
219
220fn default_service_tld() -> String {
221 "service".to_string()
222}
223
224#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
226pub struct MetricsConfig {
227 #[serde(default = "default_metrics_enabled")]
229 pub enabled: bool,
230
231 #[serde(default = "default_metrics_addr")]
233 pub listen_addr: String,
234
235 #[serde(default = "default_metrics_path")]
237 pub path: String,
238}
239
240impl Default for MetricsConfig {
241 fn default() -> Self {
242 Self {
243 enabled: default_metrics_enabled(),
244 listen_addr: default_metrics_addr(),
245 path: default_metrics_path(),
246 }
247 }
248}
249
250fn default_metrics_enabled() -> bool {
251 true
252}
253
254fn default_metrics_addr() -> String {
255 "0.0.0.0:9090".to_string()
256}
257
258fn default_metrics_path() -> String {
259 "/metrics".to_string()
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
264pub struct LoggingConfig {
265 #[serde(default = "default_log_level")]
267 pub level: String,
268
269 #[serde(default = "default_log_format")]
271 pub format: String,
272
273 #[serde(default = "default_log_stdout")]
275 pub stdout: bool,
276
277 pub file: Option<PathBuf>,
279}
280
281impl Default for LoggingConfig {
282 fn default() -> Self {
283 Self {
284 level: default_log_level(),
285 format: default_log_format(),
286 stdout: default_log_stdout(),
287 file: None,
288 }
289 }
290}
291
292fn default_log_level() -> String {
293 "info".to_string()
294}
295
296fn default_log_format() -> String {
297 "json".to_string()
298}
299
300fn default_log_stdout() -> bool {
301 true
302}
303
304#[cfg(test)]
305mod tests {
306 use super::*;
307
308 #[test]
309 fn test_agent_config_default() {
310 let config = AgentConfig {
311 deployment_name: "test".to_string(),
312 node_id: "node-1".to_string(),
313 ..Default::default()
314 };
315 assert_eq!(config.deployment_name, "test");
316 assert_eq!(config.node_id, "node-1");
317 }
318}