1use serde::{Deserialize, Serialize};
8use uuid::Uuid;
9
10#[derive(Clone, Debug, Serialize, Deserialize)]
22#[serde(rename_all = "snake_case")]
23#[non_exhaustive]
24pub enum AdminEvent {
25 HostUpdated { id: Uuid },
27 HostCreated { id: Uuid },
29 HostDeleted { id: Uuid },
31 ServiceStatusChanged { id: Uuid, status: String },
33 SoftwareItemUpdated { id: Uuid },
35 SoftwareItemCreated { id: Uuid },
37 VersionCheckCompleted {
39 host_id: Uuid,
40 software_item_id: Uuid,
41 },
42 UpdateTriggered {
48 update_history_id: Uuid,
49 host_id: Uuid,
50 software_item_id: Uuid,
51 },
52 UpdateProtectionStarted {
57 update_history_id: Uuid,
58 host_id: Uuid,
59 software_item_id: Uuid,
60 },
61 UpdateStarted {
63 update_history_id: Uuid,
64 host_id: Uuid,
65 software_item_id: Uuid,
66 interactive: bool,
72 },
73 UpdateCompleted {
75 update_history_id: Uuid,
76 host_id: Uuid,
77 software_item_id: Uuid,
78 status: String,
79 },
80 DiscoveryCompleted { host_id: Uuid },
82 SystemServiceStatusChanged { id: Uuid, status: String },
84 SchedulerTaskCompleted { task_id: Uuid },
86 HostTagCreated { id: Uuid },
88 HostTagUpdated { id: Uuid },
90 HostTagDeleted { id: Uuid },
92 HostTagsChanged { host_id: Uuid },
94 GlobalGitHubProviderMisconfigured { problem: String },
96 DataReset,
98}
99
100impl AdminEvent {
101 pub fn event_name(&self) -> &'static str {
106 match self {
107 Self::HostUpdated { .. } => "host_updated",
108 Self::HostCreated { .. } => "host_created",
109 Self::HostDeleted { .. } => "host_deleted",
110 Self::ServiceStatusChanged { .. } => "service_status_changed",
111 Self::SoftwareItemUpdated { .. } => "software_item_updated",
112 Self::SoftwareItemCreated { .. } => "software_item_created",
113 Self::VersionCheckCompleted { .. } => "version_check_completed",
114 Self::UpdateTriggered { .. } => "update_triggered",
115 Self::UpdateProtectionStarted { .. } => "update_protection_started",
116 Self::UpdateStarted { .. } => "update_started",
117 Self::UpdateCompleted { .. } => "update_completed",
118 Self::DiscoveryCompleted { .. } => "discovery_completed",
119 Self::SystemServiceStatusChanged { .. } => "system_service_status_changed",
120 Self::SchedulerTaskCompleted { .. } => "scheduler_task_completed",
121 Self::HostTagCreated { .. } => "host_tag_created",
122 Self::HostTagUpdated { .. } => "host_tag_updated",
123 Self::HostTagDeleted { .. } => "host_tag_deleted",
124 Self::HostTagsChanged { .. } => "host_tags_changed",
125 Self::GlobalGitHubProviderMisconfigured { .. } => {
126 "global_github_provider_misconfigured"
127 }
128 Self::DataReset => "data_reset",
129 }
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 fn all_variants() -> Vec<AdminEvent> {
139 let id = Uuid::nil();
140 vec![
141 AdminEvent::HostUpdated { id },
142 AdminEvent::HostCreated { id },
143 AdminEvent::HostDeleted { id },
144 AdminEvent::ServiceStatusChanged {
145 id,
146 status: "approved".to_string(),
147 },
148 AdminEvent::SoftwareItemUpdated { id },
149 AdminEvent::SoftwareItemCreated { id },
150 AdminEvent::VersionCheckCompleted {
151 host_id: id,
152 software_item_id: id,
153 },
154 AdminEvent::UpdateTriggered {
155 update_history_id: id,
156 host_id: id,
157 software_item_id: id,
158 },
159 AdminEvent::UpdateProtectionStarted {
160 update_history_id: id,
161 host_id: id,
162 software_item_id: id,
163 },
164 AdminEvent::UpdateStarted {
165 update_history_id: id,
166 host_id: id,
167 software_item_id: id,
168 interactive: false,
169 },
170 AdminEvent::UpdateCompleted {
171 update_history_id: id,
172 host_id: id,
173 software_item_id: id,
174 status: "completed".to_string(),
175 },
176 AdminEvent::DiscoveryCompleted { host_id: id },
177 AdminEvent::SystemServiceStatusChanged {
178 id,
179 status: "approved".to_string(),
180 },
181 AdminEvent::SchedulerTaskCompleted { task_id: id },
182 AdminEvent::HostTagCreated { id },
183 AdminEvent::HostTagUpdated { id },
184 AdminEvent::HostTagDeleted { id },
185 AdminEvent::HostTagsChanged { host_id: id },
186 AdminEvent::GlobalGitHubProviderMisconfigured {
187 problem: "api_base_url requires auth_token".to_string(),
188 },
189 AdminEvent::DataReset,
190 ]
191 }
192
193 #[test]
194 fn serde_round_trip_all_variants() {
195 for event in all_variants() {
196 let json = serde_json::to_string(&event).unwrap();
197 let deserialized: AdminEvent = serde_json::from_str(&json).unwrap();
198 assert_eq!(event.event_name(), deserialized.event_name());
200 }
201 }
202
203 #[test]
204 fn event_name_returns_correct_strings() {
205 let id = Uuid::nil();
206 assert_eq!(AdminEvent::HostUpdated { id }.event_name(), "host_updated");
207 assert_eq!(AdminEvent::HostCreated { id }.event_name(), "host_created");
208 assert_eq!(AdminEvent::HostDeleted { id }.event_name(), "host_deleted");
209 assert_eq!(
210 AdminEvent::ServiceStatusChanged {
211 id,
212 status: String::new()
213 }
214 .event_name(),
215 "service_status_changed"
216 );
217 assert_eq!(
218 AdminEvent::SoftwareItemUpdated { id }.event_name(),
219 "software_item_updated"
220 );
221 assert_eq!(
222 AdminEvent::SoftwareItemCreated { id }.event_name(),
223 "software_item_created"
224 );
225 assert_eq!(
226 AdminEvent::VersionCheckCompleted {
227 host_id: id,
228 software_item_id: id,
229 }
230 .event_name(),
231 "version_check_completed"
232 );
233 assert_eq!(
234 AdminEvent::UpdateTriggered {
235 update_history_id: id,
236 host_id: id,
237 software_item_id: id,
238 }
239 .event_name(),
240 "update_triggered"
241 );
242 assert_eq!(
243 AdminEvent::UpdateStarted {
244 update_history_id: id,
245 host_id: id,
246 software_item_id: id,
247 interactive: false,
248 }
249 .event_name(),
250 "update_started"
251 );
252 assert_eq!(
253 AdminEvent::UpdateCompleted {
254 update_history_id: id,
255 host_id: id,
256 software_item_id: id,
257 status: String::new(),
258 }
259 .event_name(),
260 "update_completed"
261 );
262 assert_eq!(
263 AdminEvent::DiscoveryCompleted { host_id: id }.event_name(),
264 "discovery_completed"
265 );
266 assert_eq!(
267 AdminEvent::SystemServiceStatusChanged {
268 id,
269 status: String::new()
270 }
271 .event_name(),
272 "system_service_status_changed"
273 );
274 assert_eq!(
275 AdminEvent::SchedulerTaskCompleted { task_id: id }.event_name(),
276 "scheduler_task_completed"
277 );
278 assert_eq!(
279 AdminEvent::GlobalGitHubProviderMisconfigured {
280 problem: String::new(),
281 }
282 .event_name(),
283 "global_github_provider_misconfigured"
284 );
285 }
286
287 #[test]
288 fn event_name_count_matches_variant_count() {
289 assert_eq!(all_variants().len(), 20);
292 }
293
294 #[test]
295 fn serde_uses_snake_case_tag() {
296 let event = AdminEvent::HostUpdated { id: Uuid::nil() };
297 let json = serde_json::to_string(&event).unwrap();
298 assert!(json.contains("host_updated"), "json was: {json}");
300 }
301
302 #[test]
303 fn update_protection_started_event_name() {
304 let id = Uuid::nil();
305 let event = AdminEvent::UpdateProtectionStarted {
306 update_history_id: id,
307 host_id: id,
308 software_item_id: id,
309 };
310 assert_eq!(event.event_name(), "update_protection_started");
311 }
312}