From 4584bd6e50dfdc817a86e86d2cc8148e316fd5a7 Mon Sep 17 00:00:00 2001 From: Francesco Cogno Date: Sun, 10 Jan 2021 11:03:48 +0100 Subject: [PATCH] Bugfix: comments no longer remove friendly names --- Cargo.toml | 2 +- example.json | 4 ---- src/wireguard_config.rs | 47 ++++++++++++++++++++++++++++------------- 3 files changed, 33 insertions(+), 20 deletions(-) delete mode 100644 example.json diff --git a/Cargo.toml b/Cargo.toml index b1ea5f0..03f1367 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "prometheus_wireguard_exporter" -version = "3.4.1" +version = "3.4.2" authors = ["Francesco Cogno "] description = "Prometheus WireGuard Exporter" edition = "2018" diff --git a/example.json b/example.json deleted file mode 100644 index 66bd6ba..0000000 --- a/example.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - { "path": "/home/mindflavor", "recursive": true }, - { "path": "/home/mindflavor/.cargo", "recursive": false } -] diff --git a/src/wireguard_config.rs b/src/wireguard_config.rs index 97014eb..a7763b0 100644 --- a/src/wireguard_config.rs +++ b/src/wireguard_config.rs @@ -10,7 +10,6 @@ pub(crate) struct PeerEntry<'a> { pub name: Option<&'a str>, } -#[inline] fn after_char(s: &str, c_split: char) -> &str { let mut p: usize = 0; for c in s.chars().into_iter() { @@ -23,6 +22,16 @@ fn after_char(s: &str, c_split: char) -> &str { s } +fn after_char_strip_comment(s: &str, c_split: char) -> &str { + let s = after_char(s, c_split); + + if let Some(idx) = s.find('#') { + &s[..idx].trim() + } else { + s + } +} + fn from_pound_line_to_key_value(line: &str) -> Option<(&str, &str)> { // since the pound sign is 1 byte the below slice will work let line = &line[1..]; @@ -42,7 +51,7 @@ impl<'a> TryFrom<&[&'a str]> for PeerEntry<'a> { type Error = PeerEntryParseError; fn try_from(lines: &[&'a str]) -> Result, Self::Error> { - debug!("PeerEntry::TryFrom called with lines == {:?}", lines); + debug!("PeerEntry::TryFrom called with lines == {:#?}", lines); let mut public_key = ""; let mut allowed_ips = ""; @@ -52,12 +61,17 @@ impl<'a> TryFrom<&[&'a str]> for PeerEntry<'a> { let line_lowercase = line.to_lowercase(); if line_lowercase.starts_with("publickey") { - public_key = after_char(line, '=').trim(); + public_key = after_char_strip_comment(line, '=').trim(); + debug!("public_key == {}", public_key); } else if line_lowercase.starts_with("allowedips") { - allowed_ips = after_char(line, '=').trim(); + allowed_ips = after_char_strip_comment(line, '=').trim(); + debug!("allowed_ips == {}", allowed_ips); } else if line.trim().starts_with('#') { if let Some((key, value)) = from_pound_line_to_key_value(line) { - // if it's a supported key, let' map it + // if it's a supported key, let' map it. + // we support one key now but this way + // we can support more in the future + #[allow(clippy::single_match)] match key { "friendly_name" => { name = Some(value); @@ -71,12 +85,12 @@ impl<'a> TryFrom<&[&'a str]> for PeerEntry<'a> { // Sanity checks // If there are more than one PublicKey or AllowedIPs we won't catch it. But // WireGuard won't be working either so we can live with this simplification. - if public_key == "" { + if public_key.is_empty() { // we return a owned String for ergonomics. This will allocate but it's ok since it's not supposed // to happen :) let lines_owned: Vec = lines.iter().map(|line| (*line).to_string()).collect(); Err(PeerEntryParseError::PublicKeyNotFound { lines: lines_owned }) - } else if allowed_ips == "" { + } else if allowed_ips.is_empty() { let lines_owned: Vec = lines.iter().map(|line| (*line).to_string()).collect(); Err(PeerEntryParseError::AllowedIPsEntryNotFound { lines: lines_owned }) } else { @@ -96,6 +110,7 @@ pub(crate) type PeerEntryHashMap<'a> = HashMap<&'a str, PeerEntry<'a>>; pub(crate) fn peer_entry_hashmap_try_from( txt: &str, ) -> Result { + debug!("txt == {}", txt); let mut hm = HashMap::new(); let mut v_blocks = Vec::new(); @@ -116,7 +131,7 @@ pub(crate) fn peer_entry_hashmap_try_from( } else { // push the line if we are in a block (only if not empty) if let Some(inner_cur_block) = &mut cur_block { - if line != "" { + if !line.is_empty() { inner_cur_block.push(line); } } @@ -158,7 +173,7 @@ PrivateKey = my_super_secret_private_key # This is a comment # This is a comment PublicKey = 2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk= -AllowedIPs = 10.70.0.2/32 +AllowedIPs = 10.70.0.2/32 # this is a comment in AllowedIPs line [Peer] # friendly_name=varch.local (laptop) @@ -179,7 +194,7 @@ AllowedIPs = 10.70.0.50/32 # This is a comment # friendly_name = frcognowin10 # This is something -PublicKey = lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc= +PublicKey = lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc= # other comment AllowedIPs = 10.70.0.40/32 [Peer] @@ -218,7 +233,7 @@ PrivateKey = my_super_secret_private_key [Peer] # friendly_name=OnePlus 6T PublicKey = 2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk= -AllowedIPs = 10.70.0.2/32 +AllowedIPs = 10.70.0.2/32 # this is a comment [Peer] # friendly_name=varch.local (laptop) @@ -265,13 +280,15 @@ PublicKey = L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008= #[test] fn test_parse_friendly_name() { let a: PeerEntryHashMap = peer_entry_hashmap_try_from(TEXT).unwrap(); + + let entry = a.get("lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc="); + let entry = entry.expect("this should have been Some (frcognowin10)!"); + assert_eq!(Some("frcognowin10"), entry.name); + let entry = a.get("2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk="); let entry = entry.expect("this should have been Some!"); assert_eq!(Some("OnePlus 6T"), entry.name); - - let entry = a.get("lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc="); - let entry = entry.expect("this should have been Some!"); - assert_eq!(Some("frcognowin10"), entry.name); + assert_eq!(entry.allowed_ips, "10.70.0.2/32"); let entry = a.get("928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk="); let entry = entry.expect("this should have been Some!");