|
| 1 | +use chrono::NaiveDateTime; |
| 2 | + |
| 3 | +use crate::Message; |
| 4 | + |
| 5 | +pub struct ShowStatusMessage { |
| 6 | + /// Server version |
| 7 | + pub version_line: String, |
| 8 | + /// Router ID configured on this BIRD instance |
| 9 | + pub router_id: String, |
| 10 | + /// Current server time |
| 11 | + pub server_time: NaiveDateTime, |
| 12 | + /// Last reboot time |
| 13 | + pub last_reboot_on: NaiveDateTime, |
| 14 | + /// Last reconfiguration time |
| 15 | + pub last_reconfigured_on: NaiveDateTime, |
| 16 | + /// Status message |
| 17 | + pub status: String, |
| 18 | +} |
| 19 | + |
| 20 | +impl ShowStatusMessage { |
| 21 | + /// Parses `messages` to create a [ShowStatusMessage] object. Returns `None` if |
| 22 | + /// the parsing failed for any reason |
| 23 | + pub(crate) fn from_messages(messages: &Vec<Message>) -> Option<ShowStatusMessage> { |
| 24 | + let mut version_line: Option<String> = None; |
| 25 | + let mut router_id: Option<String> = None; |
| 26 | + let mut server_time: Option<NaiveDateTime> = None; |
| 27 | + let mut last_reboot_on: Option<NaiveDateTime> = None; |
| 28 | + let mut last_reconfigured_on: Option<NaiveDateTime> = None; |
| 29 | + let mut status: Option<String> = None; |
| 30 | + for msg in messages { |
| 31 | + match msg { |
| 32 | + Message::BirdVersion(v) => version_line = Some(v.clone()), |
| 33 | + Message::StatusReport(s) => status = Some(s.clone()), |
| 34 | + Message::Uptime(s) => { |
| 35 | + let tfmt = "%Y-%m-%d %H:%M:%S%.3f"; |
| 36 | + for line in s.lines() { |
| 37 | + if let Some(x) = line.strip_prefix("Router ID is ") { |
| 38 | + router_id = Some(String::from(x)); |
| 39 | + } else if let Some(x) = line.strip_prefix("Current server time is ") { |
| 40 | + if let Ok(dt) = NaiveDateTime::parse_from_str(x.trim(), tfmt) { |
| 41 | + server_time = Some(dt); |
| 42 | + } else { |
| 43 | + log::error!("failed to parse timestamp {}", x); |
| 44 | + return None; |
| 45 | + } |
| 46 | + } else if let Some(x) = line.strip_prefix("Last reboot on ") { |
| 47 | + if let Ok(dt) = NaiveDateTime::parse_from_str(x.trim(), tfmt) { |
| 48 | + last_reboot_on = Some(dt); |
| 49 | + } else { |
| 50 | + log::error!("failed to parse timestamp {}", x); |
| 51 | + return None; |
| 52 | + } |
| 53 | + } else if let Some(x) = line.strip_prefix("Last reconfiguration on ") { |
| 54 | + if let Ok(dt) = NaiveDateTime::parse_from_str(x.trim(), tfmt) { |
| 55 | + last_reconfigured_on = Some(dt); |
| 56 | + } else { |
| 57 | + log::error!("failed to parse timestamp {}", x); |
| 58 | + return None; |
| 59 | + } |
| 60 | + } |
| 61 | + } |
| 62 | + } |
| 63 | + _ => continue, |
| 64 | + } |
| 65 | + } |
| 66 | + if let Some(version_line) = version_line { |
| 67 | + if let Some(router_id) = router_id { |
| 68 | + if let Some(server_time) = server_time { |
| 69 | + if let Some(last_reboot_on) = last_reboot_on { |
| 70 | + if let Some(last_reconfigured_on) = last_reconfigured_on { |
| 71 | + if let Some(status) = status { |
| 72 | + return Some(ShowStatusMessage { |
| 73 | + version_line, |
| 74 | + router_id, |
| 75 | + server_time, |
| 76 | + last_reboot_on, |
| 77 | + last_reconfigured_on, |
| 78 | + status, |
| 79 | + }); |
| 80 | + } |
| 81 | + } |
| 82 | + } |
| 83 | + } |
| 84 | + } |
| 85 | + } |
| 86 | + None |
| 87 | + } |
| 88 | +} |
| 89 | + |
| 90 | +#[cfg(test)] |
| 91 | +mod tests { |
| 92 | + use super::*; |
| 93 | + |
| 94 | + #[test] |
| 95 | + fn test_parse_status() { |
| 96 | + let _ = env_logger::try_init(); |
| 97 | + let messages = vec![ |
| 98 | + Message::BirdVersion("BIRD 2.0.7".into()), |
| 99 | + Message::Uptime("Router ID is 172.29.0.12\nCurrent server time is 2022-05-08 10:14:23.381\nLast reboot on 2022-04-14 22:23:28.096\nLast reconfiguration on 2022-04-15 00:00:46.707".into()), |
| 100 | + Message::StatusReport("Daemon is up and running".into()), |
| 101 | + ]; |
| 102 | + if let Some(status) = ShowStatusMessage::from_messages(&messages) { |
| 103 | + assert_eq!(status.version_line, "BIRD 2.0.7"); |
| 104 | + assert_eq!(status.router_id, "172.29.0.12"); |
| 105 | + assert_eq!(status.server_time.to_string(), "2022-05-08 10:14:23.381"); |
| 106 | + assert_eq!(status.last_reboot_on.to_string(), "2022-04-14 22:23:28.096"); |
| 107 | + assert_eq!( |
| 108 | + status.last_reconfigured_on.to_string(), |
| 109 | + "2022-04-15 00:00:46.707", |
| 110 | + ); |
| 111 | + assert_eq!(status.status, "Daemon is up and running"); |
| 112 | + } else { |
| 113 | + panic!("failed to parse status"); |
| 114 | + } |
| 115 | + } |
| 116 | +} |
0 commit comments