From 82188d14945f5f6da082233d0863afc6859caad9 Mon Sep 17 00:00:00 2001 From: Francesco Cogno Date: Mon, 20 May 2019 10:09:02 +0200 Subject: [PATCH] before live test --- src/main.rs | 8 ++-- src/wireguard.rs | 54 ++++++++++++++++++++++----- src/wireguard_config.rs | 81 ++++++++++++++++++++--------------------- 3 files changed, 87 insertions(+), 56 deletions(-) diff --git a/src/main.rs b/src/main.rs index 57b275a..e36a223 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,7 @@ use std::process::Command; use std::string::String; use wireguard::WireGuard; mod wireguard_config; -use wireguard_config::PeerEntryHashMap; +use wireguard_config::peer_entry_hashmap_try_from; fn check_compliance(req: &Request) -> Result<(), Response> { if req.uri() != "/metrics" { @@ -66,8 +66,8 @@ fn wg_with_text( wg_config_str: &str, wg_output: ::std::process::Output, ) -> Result, ExporterError> { - let pehm = PeerEntryHashMap::try_from(wg_config_str)?; - println!("pehm == {:?}", pehm); + let pehm = peer_entry_hashmap_try_from(wg_config_str)?; + trace!("pehm == {:?}", pehm); let wg_output_string = String::from_utf8(wg_output.stdout)?; let wg = WireGuard::try_from(&wg_output_string as &str)?; @@ -115,7 +115,7 @@ fn perform_request( fn main() { let matches = clap::App::new("prometheus_wireguard_exporter") - .version("0.1") + .version("1.2.0") .author("Francesco Cogno ") .arg( Arg::with_name("port") diff --git a/src/wireguard.rs b/src/wireguard.rs index 25505f1..2817b4f 100644 --- a/src/wireguard.rs +++ b/src/wireguard.rs @@ -1,5 +1,6 @@ use crate::exporter_error::ExporterError; use crate::render_to_prometheus::RenderToPrometheus; +use crate::wireguard_config::PeerEntryHashMap; use log::{debug, trace}; use std::collections::HashMap; use std::convert::TryFrom; @@ -124,20 +125,47 @@ impl TryFrom<&str> for WireGuard { } } -impl RenderToPrometheus for WireGuard { - fn render(&self) -> String { +impl WireGuard { + fn render_with_names(&self, pehm: Option<&PeerEntryHashMap>) -> String { let mut latest_handshakes = Vec::new(); let mut sent_bytes = Vec::new(); let mut received_bytes = Vec::new(); - for (interface, endpoints) in self.interfaces.iter() { - for endpoint in endpoints { - // only show remote endpoints - if let Endpoint::Remote(ep) = endpoint { - debug!("{:?}", ep); - sent_bytes.push(format!("wireguard_sent_bytes{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ep.sent_bytes)); - received_bytes.push(format!("wireguard_received_bytes{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ep.received_bytes)); - latest_handshakes.push(format!("wireguard_latest_handshake_seconds{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ::std::time::SystemTime::now().duration_since(ep.latest_handshake).unwrap().as_secs())); + if let Some(pehm) = pehm { + // here we try to add the "friendly" name looking in the hashmap + for (interface, endpoints) in self.interfaces.iter() { + for endpoint in endpoints { + // only show remote endpoints + if let Endpoint::Remote(ep) = endpoint { + debug!("{:?}", ep); + if let Some(ep_friendly_name) = pehm.get(&ep.public_key as &str) { + if let Some(ep_friendly_name) = ep_friendly_name.name { + sent_bytes.push(format!("wireguard_sent_bytes{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\", friendly_name=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ep_friendly_name, ep.sent_bytes)); + received_bytes.push(format!("wireguard_received_bytes{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\", friendly_name=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ep_friendly_name, ep.received_bytes)); + latest_handshakes.push(format!("wireguard_latest_handshake_seconds{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\", friendly_name=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ep_friendly_name, ::std::time::SystemTime::now().duration_since(ep.latest_handshake).unwrap().as_secs())); + } else { + sent_bytes.push(format!("wireguard_sent_bytes{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ep.sent_bytes)); + received_bytes.push(format!("wireguard_received_bytes{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ep.received_bytes)); + latest_handshakes.push(format!("wireguard_latest_handshake_seconds{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ::std::time::SystemTime::now().duration_since(ep.latest_handshake).unwrap().as_secs())); + } + } else { + sent_bytes.push(format!("wireguard_sent_bytes{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ep.sent_bytes)); + received_bytes.push(format!("wireguard_received_bytes{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ep.received_bytes)); + latest_handshakes.push(format!("wireguard_latest_handshake_seconds{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ::std::time::SystemTime::now().duration_since(ep.latest_handshake).unwrap().as_secs())); + } + } + } + } + } else { + for (interface, endpoints) in self.interfaces.iter() { + for endpoint in endpoints { + // only show remote endpoints + if let Endpoint::Remote(ep) = endpoint { + debug!("{:?}", ep); + sent_bytes.push(format!("wireguard_sent_bytes{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ep.sent_bytes)); + received_bytes.push(format!("wireguard_received_bytes{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ep.received_bytes)); + latest_handshakes.push(format!("wireguard_latest_handshake_seconds{{inteface=\"{}\", public_key=\"{}\", local_ip=\"{}\", local_subnet=\"{}\"}} {}\n", interface, ep.public_key, ep.local_ip, ep.local_subnet, ::std::time::SystemTime::now().duration_since(ep.latest_handshake).unwrap().as_secs())); + } } } } @@ -173,6 +201,12 @@ impl RenderToPrometheus for WireGuard { } } +impl RenderToPrometheus for WireGuard { + fn render(&self) -> String { + self.render_with_names(None) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/wireguard_config.rs b/src/wireguard_config.rs index ecc1a85..2af6701 100644 --- a/src/wireguard_config.rs +++ b/src/wireguard_config.rs @@ -63,56 +63,53 @@ impl<'a> TryFrom<&[&'a str]> for PeerEntry<'a> { } } -#[derive(Debug, Default, Clone)] -pub(crate) struct PeerEntryHashMap<'a>(HashMap<&'a str, PeerEntry<'a>>); +pub(crate) type PeerEntryHashMap<'a> = (HashMap<&'a str, PeerEntry<'a>>); -impl<'a> TryFrom<&'a str> for PeerEntryHashMap<'a> { - type Error = PeerEntryParseError; +pub(crate) fn peer_entry_hashmap_try_from<'a>( + txt: &'a str, +) -> Result { + let mut hm = HashMap::new(); - fn try_from(txt: &'a str) -> Result { - let mut hm = HashMap::new(); + let mut v_blocks = Vec::new(); + let mut cur_block: Option> = None; - let mut v_blocks = Vec::new(); - let mut cur_block: Option> = None; + for line in txt.lines().into_iter() { + if line.starts_with("[") { + if let Some(inner_cur_block) = cur_block { + // close the block + v_blocks.push(inner_cur_block); + cur_block = None; + } - for line in txt.lines().into_iter() { - if line.starts_with("[") { - if let Some(inner_cur_block) = cur_block { - // close the block - v_blocks.push(inner_cur_block); - cur_block = None; - } - - if line == "[Peer]" { - // start a new block - cur_block = Some(Vec::new()); - } - } 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 != "" { - inner_cur_block.push(line); - } + if line == "[Peer]" { + // start a new block + cur_block = Some(Vec::new()); + } + } 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 != "" { + inner_cur_block.push(line); } } } - - if let Some(cur_block) = cur_block { - // we have a leftover block - v_blocks.push(cur_block); - } - - debug!("v_blocks == {:?}", v_blocks); - - for block in &v_blocks { - let p: PeerEntry = PeerEntry::try_from(&block as &[&str])?; - hm.insert(p.public_key, p); - } - - debug!("hm == {:?}", hm); - - Ok(PeerEntryHashMap(hm)) } + + if let Some(cur_block) = cur_block { + // we have a leftover block + v_blocks.push(cur_block); + } + + debug!("v_blocks == {:?}", v_blocks); + + for block in &v_blocks { + let p: PeerEntry = PeerEntry::try_from(&block as &[&str])?; + hm.insert(p.public_key, p); + } + + debug!("hm == {:?}", hm); + + Ok(hm) } #[cfg(test)]