postfix_log_parser/events/
trivial_rewrite.rs1use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
12pub struct TrivialRewriteEvent {
13 pub timestamp: DateTime<Utc>,
15
16 pub pid: Option<u32>,
19
20 pub event_type: TrivialRewriteEventType,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
25pub enum TrivialRewriteEventType {
26 ConfigOverrideWarning {
27 file_path: String,
28 line_number: u32,
29 parameter_name: String,
30 parameter_value: String,
31 },
32 DomainConfigWarning {
33 domain: String,
34 domain_list1: String, domain_list2: String, message: String,
37 },
38}
39
40impl TrivialRewriteEvent {
41 pub fn new(
42 timestamp: DateTime<Utc>,
43 pid: Option<u32>,
44 event_type: TrivialRewriteEventType,
45 ) -> Self {
46 Self {
47 timestamp,
48 pid,
49 event_type,
50 }
51 }
52
53 pub fn config_override_warning(
54 timestamp: DateTime<Utc>,
55 pid: Option<u32>,
56 file_path: String,
57 line_number: u32,
58 parameter_name: String,
59 parameter_value: String,
60 ) -> Self {
61 Self::new(
62 timestamp,
63 pid,
64 TrivialRewriteEventType::ConfigOverrideWarning {
65 file_path,
66 line_number,
67 parameter_name,
68 parameter_value,
69 },
70 )
71 }
72
73 pub fn domain_config_warning(
74 timestamp: DateTime<Utc>,
75 pid: Option<u32>,
76 domain: String,
77 domain_list1: String,
78 domain_list2: String,
79 message: String,
80 ) -> Self {
81 Self::new(
82 timestamp,
83 pid,
84 TrivialRewriteEventType::DomainConfigWarning {
85 domain,
86 domain_list1,
87 domain_list2,
88 message,
89 },
90 )
91 }
92
93 pub fn description(&self) -> String {
95 match &self.event_type {
96 TrivialRewriteEventType::ConfigOverrideWarning {
97 file_path,
98 line_number,
99 parameter_name,
100 parameter_value,
101 } => {
102 format!(
103 "Config override in {}:{} - parameter '{}' set to '{}'",
104 file_path, line_number, parameter_name, parameter_value
105 )
106 }
107 TrivialRewriteEventType::DomainConfigWarning {
108 domain,
109 domain_list1,
110 domain_list2,
111 message,
112 } => {
113 format!(
114 "Domain config warning for '{}': {} (conflicts between {} and {})",
115 domain, message, domain_list1, domain_list2
116 )
117 }
118 }
119 }
120
121 pub fn severity(&self) -> &'static str {
123 match &self.event_type {
124 TrivialRewriteEventType::ConfigOverrideWarning { .. } => "warning",
125 TrivialRewriteEventType::DomainConfigWarning { .. } => "warning",
126 }
127 }
128
129 pub fn parameter_name(&self) -> Option<&str> {
131 match &self.event_type {
132 TrivialRewriteEventType::ConfigOverrideWarning { parameter_name, .. } => {
133 Some(parameter_name)
134 }
135 TrivialRewriteEventType::DomainConfigWarning { .. } => None,
136 }
137 }
138
139 pub fn domain(&self) -> Option<&str> {
141 match &self.event_type {
142 TrivialRewriteEventType::ConfigOverrideWarning { .. } => None,
143 TrivialRewriteEventType::DomainConfigWarning { domain, .. } => Some(domain),
144 }
145 }
146}
147
148#[cfg(test)]
149mod tests {
150 use super::*;
151 use chrono::TimeZone;
152
153 #[test]
154 fn test_config_override_warning_event() {
155 let timestamp = Utc.with_ymd_and_hms(2024, 4, 8, 17, 54, 42).unwrap();
156 let event = TrivialRewriteEvent::config_override_warning(
157 timestamp,
158 Some(81),
159 "/etc/postfix/main.cf".to_string(),
160 820,
161 "smtpd_recipient_restrictions".to_string(),
162 "check_client_access pcre:/etc/postfix/filter_trusted,permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination,pcre:/etc/postfix/filter_default".to_string(),
163 );
164
165 assert_eq!(event.timestamp, timestamp);
166 assert_eq!(event.pid, Some(81));
167 assert_eq!(event.severity(), "warning");
168 assert_eq!(event.parameter_name(), Some("smtpd_recipient_restrictions"));
169 assert!(event.description().contains("Config override"));
170 assert!(event.description().contains("/etc/postfix/main.cf:820"));
171 }
172
173 #[test]
174 fn test_domain_config_warning_event() {
175 let timestamp = Utc.with_ymd_and_hms(2024, 4, 9, 14, 42, 34).unwrap();
176 let event = TrivialRewriteEvent::domain_config_warning(
177 timestamp,
178 Some(81),
179 "qq.com".to_string(),
180 "virtual_alias_domains".to_string(),
181 "relay_domains".to_string(),
182 "do not list domain qq.com in BOTH virtual_alias_domains and relay_domains".to_string(),
183 );
184
185 assert_eq!(event.timestamp, timestamp);
186 assert_eq!(event.pid, Some(81));
187 assert_eq!(event.severity(), "warning");
188 assert_eq!(event.domain(), Some("qq.com"));
189 assert!(event.description().contains("Domain config warning"));
190 assert!(event.description().contains("qq.com"));
191 assert!(event
192 .description()
193 .contains("virtual_alias_domains and relay_domains"));
194 }
195
196 #[test]
197 fn test_event_equality() {
198 let timestamp = Utc.with_ymd_and_hms(2024, 4, 8, 17, 54, 42).unwrap();
199
200 let event1 = TrivialRewriteEvent::config_override_warning(
201 timestamp,
202 Some(81),
203 "/etc/postfix/main.cf".to_string(),
204 820,
205 "smtpd_recipient_restrictions".to_string(),
206 "value1".to_string(),
207 );
208
209 let event2 = TrivialRewriteEvent::config_override_warning(
210 timestamp,
211 Some(81),
212 "/etc/postfix/main.cf".to_string(),
213 820,
214 "smtpd_recipient_restrictions".to_string(),
215 "value1".to_string(),
216 );
217
218 assert_eq!(event1, event2);
219 }
220}