1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::path::Path;
6
7use super::auth::AuthConfig;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
12pub struct HttpValidationConfig {
13 pub mode: String,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize, Default)]
19#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
20pub struct HttpCorsConfig {
21 pub enabled: bool,
23 #[serde(default)]
25 pub allowed_origins: Vec<String>,
26 #[serde(default)]
28 pub allowed_methods: Vec<String>,
29 #[serde(default)]
31 pub allowed_headers: Vec<String>,
32 #[serde(default = "default_cors_allow_credentials")]
35 pub allow_credentials: bool,
36}
37
38fn default_cors_allow_credentials() -> bool {
39 false
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
44#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
45#[serde(default)]
46pub struct HttpConfig {
47 pub enabled: bool,
49 pub port: u16,
51 pub host: String,
53 pub openapi_spec: Option<String>,
55 pub cors: Option<HttpCorsConfig>,
57 pub request_timeout_secs: u64,
59 pub validation: Option<HttpValidationConfig>,
61 pub aggregate_validation_errors: bool,
63 pub validate_responses: bool,
65 pub response_template_expand: bool,
67 pub validation_status: Option<u16>,
69 pub validation_overrides: HashMap<String, String>,
71 pub skip_admin_validation: bool,
73 pub auth: Option<AuthConfig>,
75 #[serde(skip_serializing_if = "Option::is_none")]
77 pub tls: Option<HttpTlsConfig>,
78}
79
80impl Default for HttpConfig {
81 fn default() -> Self {
82 Self {
83 enabled: true,
84 port: 3000,
85 host: "0.0.0.0".to_string(),
86 openapi_spec: None,
87 cors: Some(HttpCorsConfig {
88 enabled: true,
89 allowed_origins: vec!["*".to_string()],
90 allowed_methods: vec![
91 "GET".to_string(),
92 "POST".to_string(),
93 "PUT".to_string(),
94 "DELETE".to_string(),
95 "PATCH".to_string(),
96 "OPTIONS".to_string(),
97 ],
98 allowed_headers: vec!["content-type".to_string(), "authorization".to_string()],
99 allow_credentials: false, }),
101 request_timeout_secs: 30,
102 validation: Some(HttpValidationConfig {
103 mode: "enforce".to_string(),
104 }),
105 aggregate_validation_errors: true,
106 validate_responses: false,
107 response_template_expand: false,
108 validation_status: None,
109 validation_overrides: HashMap::new(),
110 skip_admin_validation: true,
111 auth: None,
112 tls: None,
113 }
114 }
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize)]
119#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
120pub struct HttpTlsConfig {
121 pub enabled: bool,
123 pub cert_file: String,
125 pub key_file: String,
127 #[serde(skip_serializing_if = "Option::is_none")]
129 pub ca_file: Option<String>,
130 #[serde(default = "default_tls_min_version")]
132 pub min_version: String,
133 #[serde(default, skip_serializing_if = "Vec::is_empty")]
135 pub cipher_suites: Vec<String>,
136 #[serde(default)]
138 pub require_client_cert: bool,
139 #[serde(default = "default_mtls_mode")]
141 pub mtls_mode: String,
142}
143
144fn default_mtls_mode() -> String {
145 "off".to_string()
146}
147
148fn default_tls_min_version() -> String {
149 "1.2".to_string()
150}
151
152impl Default for HttpTlsConfig {
153 fn default() -> Self {
154 Self {
155 enabled: true,
156 cert_file: String::new(),
157 key_file: String::new(),
158 ca_file: None,
159 min_version: "1.2".to_string(),
160 cipher_suites: Vec::new(),
161 require_client_cert: false,
162 mtls_mode: "off".to_string(),
163 }
164 }
165}
166
167#[derive(Debug, Clone, Serialize, Deserialize)]
169#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
170#[serde(default)]
171pub struct WebSocketConfig {
172 pub enabled: bool,
174 pub port: u16,
176 pub host: String,
178 pub replay_file: Option<String>,
180 pub connection_timeout_secs: u64,
182}
183
184impl Default for WebSocketConfig {
185 fn default() -> Self {
186 Self {
187 enabled: true,
188 port: 3001,
189 host: "0.0.0.0".to_string(),
190 replay_file: None,
191 connection_timeout_secs: 300,
192 }
193 }
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
198#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
199#[serde(default)]
200pub struct GrpcConfig {
201 pub enabled: bool,
203 pub port: u16,
205 pub host: String,
207 pub proto_dir: Option<String>,
209 pub tls: Option<TlsConfig>,
211}
212
213impl Default for GrpcConfig {
214 fn default() -> Self {
215 Self {
216 enabled: true,
217 port: 50051,
218 host: "0.0.0.0".to_string(),
219 proto_dir: None,
220 tls: None,
221 }
222 }
223}
224
225#[derive(Debug, Clone, Serialize, Deserialize)]
227#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
228#[serde(default)]
229pub struct GraphQLConfig {
230 pub enabled: bool,
232 pub port: u16,
234 pub host: String,
236 pub schema_path: Option<String>,
238 pub handlers_dir: Option<String>,
240 pub playground_enabled: bool,
242 pub upstream_url: Option<String>,
244 pub introspection_enabled: bool,
246}
247
248impl Default for GraphQLConfig {
249 fn default() -> Self {
250 Self {
251 enabled: true,
252 port: 4000,
253 host: "0.0.0.0".to_string(),
254 schema_path: None,
255 handlers_dir: None,
256 playground_enabled: true,
257 upstream_url: None,
258 introspection_enabled: true,
259 }
260 }
261}
262
263#[derive(Debug, Clone, Serialize, Deserialize)]
265#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
266pub struct TlsConfig {
267 pub cert_path: String,
269 pub key_path: String,
271}
272
273#[derive(Debug, Clone, Serialize, Deserialize)]
275#[serde(default)]
276#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
277pub struct MqttConfig {
278 pub enabled: bool,
280 pub port: u16,
282 pub host: String,
284 pub max_connections: usize,
286 pub max_packet_size: usize,
288 pub keep_alive_secs: u16,
290 pub fixtures_dir: Option<std::path::PathBuf>,
292 pub enable_retained_messages: bool,
294 pub max_retained_messages: usize,
296}
297
298impl Default for MqttConfig {
299 fn default() -> Self {
300 Self {
301 enabled: false,
302 port: 1883,
303 host: "0.0.0.0".to_string(),
304 max_connections: 1000,
305 max_packet_size: 268435456, keep_alive_secs: 60,
307 fixtures_dir: None,
308 enable_retained_messages: true,
309 max_retained_messages: 10000,
310 }
311 }
312}
313
314#[derive(Debug, Clone, Serialize, Deserialize)]
316#[serde(default)]
317#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
318pub struct SmtpConfig {
319 pub enabled: bool,
321 pub port: u16,
323 pub host: String,
325 pub hostname: String,
327 pub fixtures_dir: Option<std::path::PathBuf>,
329 pub timeout_secs: u64,
331 pub max_connections: usize,
333 pub enable_mailbox: bool,
335 pub max_mailbox_messages: usize,
337 pub enable_starttls: bool,
339 pub tls_cert_path: Option<std::path::PathBuf>,
341 pub tls_key_path: Option<std::path::PathBuf>,
343}
344
345impl Default for SmtpConfig {
346 fn default() -> Self {
347 Self {
348 enabled: false,
349 port: 1025,
350 host: "0.0.0.0".to_string(),
351 hostname: "mockforge-smtp".to_string(),
352 fixtures_dir: Some(std::path::PathBuf::from("./fixtures/smtp")),
353 timeout_secs: 300,
354 max_connections: 10,
355 enable_mailbox: true,
356 max_mailbox_messages: 1000,
357 enable_starttls: false,
358 tls_cert_path: None,
359 tls_key_path: None,
360 }
361 }
362}
363
364#[derive(Debug, Clone, Serialize, Deserialize)]
366#[serde(default)]
367#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
368pub struct FtpConfig {
369 pub enabled: bool,
371 pub port: u16,
373 pub host: String,
375 pub passive_ports: (u16, u16),
377 pub max_connections: usize,
379 pub timeout_secs: u64,
381 pub allow_anonymous: bool,
383 pub fixtures_dir: Option<std::path::PathBuf>,
385 pub virtual_root: std::path::PathBuf,
387}
388
389impl Default for FtpConfig {
390 fn default() -> Self {
391 Self {
392 enabled: false,
393 port: 2121,
394 host: "0.0.0.0".to_string(),
395 passive_ports: (50000, 51000),
396 max_connections: 100,
397 timeout_secs: 300,
398 allow_anonymous: true,
399 fixtures_dir: None,
400 virtual_root: std::path::PathBuf::from("/mockforge"),
401 }
402 }
403}
404
405#[derive(Debug, Clone, Serialize, Deserialize)]
407#[serde(default)]
408#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
409pub struct KafkaConfig {
410 pub enabled: bool,
412 pub port: u16,
414 pub host: String,
416 pub broker_id: i32,
418 pub max_connections: usize,
420 pub log_retention_ms: i64,
422 pub log_segment_bytes: i64,
424 pub fixtures_dir: Option<std::path::PathBuf>,
426 pub auto_create_topics: bool,
428 pub default_partitions: i32,
430 pub default_replication_factor: i16,
432}
433
434impl Default for KafkaConfig {
435 fn default() -> Self {
436 Self {
437 enabled: false,
438 port: 9092, host: "0.0.0.0".to_string(),
440 broker_id: 1,
441 max_connections: 1000,
442 log_retention_ms: 604800000, log_segment_bytes: 1073741824, fixtures_dir: None,
445 auto_create_topics: true,
446 default_partitions: 3,
447 default_replication_factor: 1,
448 }
449 }
450}
451
452#[derive(Debug, Clone, Serialize, Deserialize)]
454#[serde(default)]
455#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
456pub struct AmqpConfig {
457 pub enabled: bool,
459 pub port: u16,
461 pub host: String,
463 pub max_connections: usize,
465 pub max_channels_per_connection: u16,
467 pub frame_max: u32,
469 pub heartbeat_interval: u16,
471 pub fixtures_dir: Option<std::path::PathBuf>,
473 pub virtual_hosts: Vec<String>,
475 pub tls_enabled: bool,
477 pub tls_port: u16,
479 pub tls_cert_path: Option<std::path::PathBuf>,
481 pub tls_key_path: Option<std::path::PathBuf>,
483 pub tls_ca_path: Option<std::path::PathBuf>,
485 pub tls_client_auth: bool,
487}
488
489impl Default for AmqpConfig {
490 fn default() -> Self {
491 Self {
492 enabled: false,
493 port: 5672, host: "0.0.0.0".to_string(),
495 max_connections: 1000,
496 max_channels_per_connection: 100,
497 frame_max: 131072, heartbeat_interval: 60,
499 fixtures_dir: None,
500 virtual_hosts: vec!["/".to_string()],
501 tls_enabled: false,
502 tls_port: 5671, tls_cert_path: None,
504 tls_key_path: None,
505 tls_ca_path: None,
506 tls_client_auth: false,
507 }
508 }
509}
510
511#[derive(Debug, Clone, Serialize, Deserialize)]
513#[serde(default)]
514#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
515pub struct TcpConfig {
516 pub enabled: bool,
518 pub port: u16,
520 pub host: String,
522 pub max_connections: usize,
524 pub timeout_secs: u64,
526 pub fixtures_dir: Option<std::path::PathBuf>,
528 pub echo_mode: bool,
530 pub enable_tls: bool,
532 pub tls_cert_path: Option<std::path::PathBuf>,
534 pub tls_key_path: Option<std::path::PathBuf>,
536}
537
538impl Default for TcpConfig {
539 fn default() -> Self {
540 Self {
541 enabled: false,
542 port: 9999,
543 host: "0.0.0.0".to_string(),
544 max_connections: 1000,
545 timeout_secs: 300,
546 fixtures_dir: Some(std::path::PathBuf::from("./fixtures/tcp")),
547 echo_mode: true,
548 enable_tls: false,
549 tls_cert_path: None,
550 tls_key_path: None,
551 }
552 }
553}
554
555#[derive(Debug, Clone, Serialize, Deserialize)]
557#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
558#[serde(default)]
559pub struct AdminConfig {
560 pub enabled: bool,
562 pub port: u16,
564 pub host: String,
566 pub auth_required: bool,
568 pub username: Option<String>,
570 pub password: Option<String>,
572 pub mount_path: Option<String>,
574 pub api_enabled: bool,
576 pub prometheus_url: String,
578}
579
580impl Default for AdminConfig {
581 fn default() -> Self {
582 let default_host = if std::env::var("DOCKER_CONTAINER").is_ok()
585 || std::env::var("container").is_ok()
586 || Path::new("/.dockerenv").exists()
587 {
588 "0.0.0.0".to_string()
589 } else {
590 "127.0.0.1".to_string()
591 };
592
593 Self {
594 enabled: false,
595 port: 9080,
596 host: default_host,
597 auth_required: false,
598 username: None,
599 password: None,
600 mount_path: None,
601 api_enabled: true,
602 prometheus_url: "http://localhost:9090".to_string(),
603 }
604 }
605}
606
607#[derive(Debug, Clone, Serialize, Deserialize)]
609#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
610pub struct ProtocolConfig {
611 pub enabled: bool,
613}
614
615#[derive(Debug, Clone, Serialize, Deserialize)]
617#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
618pub struct ProtocolsConfig {
619 pub http: ProtocolConfig,
621 pub graphql: ProtocolConfig,
623 pub grpc: ProtocolConfig,
625 pub websocket: ProtocolConfig,
627 pub smtp: ProtocolConfig,
629 pub mqtt: ProtocolConfig,
631 pub ftp: ProtocolConfig,
633 pub kafka: ProtocolConfig,
635 pub rabbitmq: ProtocolConfig,
637 pub amqp: ProtocolConfig,
639 pub tcp: ProtocolConfig,
641}
642
643impl Default for ProtocolsConfig {
644 fn default() -> Self {
645 Self {
646 http: ProtocolConfig { enabled: true },
647 graphql: ProtocolConfig { enabled: true },
648 grpc: ProtocolConfig { enabled: true },
649 websocket: ProtocolConfig { enabled: true },
650 smtp: ProtocolConfig { enabled: false },
651 mqtt: ProtocolConfig { enabled: true },
652 ftp: ProtocolConfig { enabled: false },
653 kafka: ProtocolConfig { enabled: false },
654 rabbitmq: ProtocolConfig { enabled: false },
655 amqp: ProtocolConfig { enabled: false },
656 tcp: ProtocolConfig { enabled: false },
657 }
658 }
659}