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 pub advertised_host: Option<String>,
440 pub advertised_port: Option<u16>,
444}
445
446impl Default for KafkaConfig {
447 fn default() -> Self {
448 Self {
449 enabled: false,
450 port: 9092, host: "0.0.0.0".to_string(),
452 broker_id: 1,
453 max_connections: 1000,
454 log_retention_ms: 604800000, log_segment_bytes: 1073741824, fixtures_dir: None,
457 auto_create_topics: true,
458 default_partitions: 3,
459 default_replication_factor: 1,
460 advertised_host: None,
461 advertised_port: None,
462 }
463 }
464}
465
466#[derive(Debug, Clone, Serialize, Deserialize)]
468#[serde(default)]
469#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
470pub struct AmqpConfig {
471 pub enabled: bool,
473 pub port: u16,
475 pub host: String,
477 pub max_connections: usize,
479 pub max_channels_per_connection: u16,
481 pub frame_max: u32,
483 pub heartbeat_interval: u16,
485 pub fixtures_dir: Option<std::path::PathBuf>,
487 pub virtual_hosts: Vec<String>,
489 pub tls_enabled: bool,
491 pub tls_port: u16,
493 pub tls_cert_path: Option<std::path::PathBuf>,
495 pub tls_key_path: Option<std::path::PathBuf>,
497 pub tls_ca_path: Option<std::path::PathBuf>,
499 pub tls_client_auth: bool,
501}
502
503impl Default for AmqpConfig {
504 fn default() -> Self {
505 Self {
506 enabled: false,
507 port: 5672, host: "0.0.0.0".to_string(),
509 max_connections: 1000,
510 max_channels_per_connection: 100,
511 frame_max: 131072, heartbeat_interval: 60,
513 fixtures_dir: None,
514 virtual_hosts: vec!["/".to_string()],
515 tls_enabled: false,
516 tls_port: 5671, tls_cert_path: None,
518 tls_key_path: None,
519 tls_ca_path: None,
520 tls_client_auth: false,
521 }
522 }
523}
524
525#[derive(Debug, Clone, Serialize, Deserialize)]
527#[serde(default)]
528#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
529pub struct TcpConfig {
530 pub enabled: bool,
532 pub port: u16,
534 pub host: String,
536 pub max_connections: usize,
538 pub timeout_secs: u64,
540 pub fixtures_dir: Option<std::path::PathBuf>,
542 pub echo_mode: bool,
544 pub enable_tls: bool,
546 pub tls_cert_path: Option<std::path::PathBuf>,
548 pub tls_key_path: Option<std::path::PathBuf>,
550}
551
552impl Default for TcpConfig {
553 fn default() -> Self {
554 Self {
555 enabled: false,
556 port: 9999,
557 host: "0.0.0.0".to_string(),
558 max_connections: 1000,
559 timeout_secs: 300,
560 fixtures_dir: Some(std::path::PathBuf::from("./fixtures/tcp")),
561 echo_mode: true,
562 enable_tls: false,
563 tls_cert_path: None,
564 tls_key_path: None,
565 }
566 }
567}
568
569#[derive(Debug, Clone, Serialize, Deserialize)]
571#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
572#[serde(default)]
573pub struct AdminConfig {
574 pub enabled: bool,
576 pub port: u16,
578 pub host: String,
580 pub auth_required: bool,
582 pub username: Option<String>,
584 pub password: Option<String>,
586 pub mount_path: Option<String>,
588 pub api_enabled: bool,
590 pub prometheus_url: String,
592}
593
594impl Default for AdminConfig {
595 fn default() -> Self {
596 let default_host = if std::env::var("DOCKER_CONTAINER").is_ok()
599 || std::env::var("container").is_ok()
600 || Path::new("/.dockerenv").exists()
601 {
602 "0.0.0.0".to_string()
603 } else {
604 "127.0.0.1".to_string()
605 };
606
607 Self {
608 enabled: false,
609 port: 9080,
610 host: default_host,
611 auth_required: false,
612 username: None,
613 password: None,
614 mount_path: None,
615 api_enabled: true,
616 prometheus_url: "http://localhost:9090".to_string(),
617 }
618 }
619}
620
621#[derive(Debug, Clone, Serialize, Deserialize)]
623#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
624pub struct ProtocolConfig {
625 pub enabled: bool,
627}
628
629#[derive(Debug, Clone, Serialize, Deserialize)]
631#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
632pub struct ProtocolsConfig {
633 pub http: ProtocolConfig,
635 pub graphql: ProtocolConfig,
637 pub grpc: ProtocolConfig,
639 pub websocket: ProtocolConfig,
641 pub smtp: ProtocolConfig,
643 pub mqtt: ProtocolConfig,
645 pub ftp: ProtocolConfig,
647 pub kafka: ProtocolConfig,
649 pub rabbitmq: ProtocolConfig,
651 pub amqp: ProtocolConfig,
653 pub tcp: ProtocolConfig,
655}
656
657impl Default for ProtocolsConfig {
658 fn default() -> Self {
659 Self {
660 http: ProtocolConfig { enabled: true },
661 graphql: ProtocolConfig { enabled: true },
662 grpc: ProtocolConfig { enabled: true },
663 websocket: ProtocolConfig { enabled: true },
664 smtp: ProtocolConfig { enabled: false },
665 mqtt: ProtocolConfig { enabled: true },
666 ftp: ProtocolConfig { enabled: false },
667 kafka: ProtocolConfig { enabled: false },
668 rabbitmq: ProtocolConfig { enabled: false },
669 amqp: ProtocolConfig { enabled: false },
670 tcp: ProtocolConfig { enabled: false },
671 }
672 }
673}