Export remote information behind optional flag

This commit is contained in:
Francesco Cogno 2019-07-31 15:24:52 +02:00
parent d60597be40
commit 5e0f111bd9
6 changed files with 37 additions and 17 deletions

2
Cargo.lock generated
View file

@ -514,7 +514,7 @@ dependencies = [
[[package]] [[package]]
name = "prometheus_wireguard_exporter" name = "prometheus_wireguard_exporter"
version = "3.0.0" version = "3.0.1"
dependencies = [ dependencies = [
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "prometheus_wireguard_exporter" name = "prometheus_wireguard_exporter"
version = "3.0.0" version = "3.0.1"
authors = ["Francesco Cogno <francesco.cogno@outlook.com>"] authors = ["Francesco Cogno <francesco.cogno@outlook.com>"]
description = "Prometheus WireGuard Exporter" description = "Prometheus WireGuard Exporter"
edition = "2018" edition = "2018"

View file

@ -49,7 +49,8 @@ Start the binary with `-h` to get the complete syntax. The parameters are:
| `-v` | no | <switch> | | Enable verbose mode. | `-v` | no | <switch> | | Enable verbose mode.
| `-p` | no | any valid port number | 9586 | Specify the service port. This is the port your Prometheus instance should point to. | `-p` | no | any valid port number | 9586 | Specify the service port. This is the port your Prometheus instance should point to.
| `-n` | no | path to the wireguard configuration file | | This flag adds the *friendly_name* attribute to the exported entries. See [Friendly names](#friendly-names) for more details. | `-n` | no | path to the wireguard configuration file | | This flag adds the *friendly_name* attribute to the exported entries. See [Friendly names](#friendly-names) for more details.
| `-s` | no | <switch> | off | Enabled the allowed ip + subnet split mode for the labels. | `-s` | no | <switch> | off | Enable the allowed ip + subnet split mode for the labels.
| `-r` | no | <switch> | off | Exports peer's remote ip and port as labels (if available).
Once started, the tool will listen on the specified port (or the default one, 9586, if not specified) and return a Prometheus valid response at the url `/metrics`. So to check if the tool is working properly simply browse the `http://localhost:9586/metrics` (or whichever port you choose). Once started, the tool will listen on the specified port (or the default one, 9586, if not specified) and return a Prometheus valid response at the url `/metrics`. So to check if the tool is working properly simply browse the `http://localhost:9586/metrics` (or whichever port you choose).

View file

@ -35,6 +35,7 @@ fn wg_with_text(
Ok(Response::new(Body::from(wg.render_with_names( Ok(Response::new(Body::from(wg.render_with_names(
Some(&pehm), Some(&pehm),
options.separate_allowed_ips, options.separate_allowed_ips,
options.export_remote_ip_and_port,
)))) ))))
} }
@ -71,9 +72,11 @@ fn perform_request(
done(WireGuard::try_from(&output_str as &str)) done(WireGuard::try_from(&output_str as &str))
.from_err() .from_err()
.and_then(move |wg| { .and_then(move |wg| {
ok(Response::new(Body::from( ok(Response::new(Body::from(wg.render_with_names(
wg.render_with_names(None, options.separate_allowed_ips), None,
))) options.separate_allowed_ips,
options.export_remote_ip_and_port,
))))
}) })
}, },
)) ))
@ -105,7 +108,13 @@ fn main() {
.help("separate allowed ips and ports") .help("separate allowed ips and ports")
.takes_value(false), .takes_value(false),
) )
.arg( .arg(
Arg::with_name("export_remote_ip_and_port")
.short("r")
.help("exports peer's remote ip and port as labels (if available)")
.takes_value(false),
)
.arg(
Arg::with_name("extract_names_config_file") Arg::with_name("extract_names_config_file")
.short("n") .short("n")
.help("If set, the exporter will look in the specified WireGuard config file for peer names (must be in [Peer] definition and be a comment)") .help("If set, the exporter will look in the specified WireGuard config file for peer names (must be in [Peer] definition and be a comment)")

View file

@ -3,6 +3,7 @@ pub(crate) struct Options {
pub verbose: bool, pub verbose: bool,
pub separate_allowed_ips: bool, pub separate_allowed_ips: bool,
pub extract_names_config_file: Option<String>, pub extract_names_config_file: Option<String>,
pub export_remote_ip_and_port: bool,
} }
impl Options { impl Options {
@ -12,12 +13,14 @@ impl Options {
verbose: matches.is_present("verbose"), verbose: matches.is_present("verbose"),
separate_allowed_ips: matches.is_present("separate_allowed_ips"), separate_allowed_ips: matches.is_present("separate_allowed_ips"),
extract_names_config_file: Some(e.to_owned()), extract_names_config_file: Some(e.to_owned()),
export_remote_ip_and_port: matches.is_present("export_remote_ip_and_port"),
} }
} else { } else {
Options { Options {
verbose: matches.is_present("verbose"), verbose: matches.is_present("verbose"),
separate_allowed_ips: matches.is_present("separate_allowed_ips"), separate_allowed_ips: matches.is_present("separate_allowed_ips"),
extract_names_config_file: None, extract_names_config_file: None,
export_remote_ip_and_port: matches.is_present("export_remote_ip_and_port"),
} }
} }
} }

View file

@ -119,6 +119,7 @@ impl WireGuard {
&self, &self,
pehm: Option<&PeerEntryHashMap>, pehm: Option<&PeerEntryHashMap>,
split_allowed_ips: bool, split_allowed_ips: bool,
export_remote_ip_and_port: bool,
) -> String { ) -> String {
// these are the exported counters // these are the exported counters
let pc_sent_bytes_total = PrometheusCounter::new( let pc_sent_bytes_total = PrometheusCounter::new(
@ -200,11 +201,13 @@ impl WireGuard {
} }
} }
if let Some(r_ip) = &ep.remote_ip { if export_remote_ip_and_port {
attributes.push(("remote_ip", &r_ip)); if let Some(r_ip) = &ep.remote_ip {
} attributes.push(("remote_ip", &r_ip));
if let Some(r_port) = &ep.remote_port { }
attributes_owned.push(("remote_port".to_string(), r_port.to_string())); if let Some(r_port) = &ep.remote_port {
attributes_owned.push(("remote_port".to_string(), r_port.to_string()));
}
} }
for (label, val) in &attributes_owned { for (label, val) in &attributes_owned {
@ -278,7 +281,7 @@ wg0\t928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=\t(none)\t5.90.62.106:21741\t10
#[test] #[test]
fn test_parse_and_serialize() { fn test_parse_and_serialize() {
let a = WireGuard::try_from(TEXT).unwrap(); let a = WireGuard::try_from(TEXT).unwrap();
let s = a.render_with_names(None, false); let s = a.render_with_names(None, false, true);
println!("{}", s); println!("{}", s);
} }
@ -304,7 +307,7 @@ wg0\t928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=\t(none)\t5.90.62.106:21741\t10
v.push(re); v.push(re);
wg.interfaces.insert("Pippo".to_owned(), v); wg.interfaces.insert("Pippo".to_owned(), v);
let prometheus = wg.render_with_names(None, false); let prometheus = wg.render_with_names(None, false, true);
assert_eq!(prometheus, REF); assert_eq!(prometheus, REF);
} }
@ -317,6 +320,8 @@ wg0\t928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=\t(none)\t5.90.62.106:21741\t10
const REF_SPLIT :&'static str = "# HELP wireguard_sent_bytes_total Bytes sent to the peer\n# TYPE wireguard_sent_bytes_total counter\nwireguard_sent_bytes_total{interface=\"Pippo\",public_key=\"test\",remote_ip=\"remote_ip\",allowed_ip_0=\"10.0.0.2\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",remote_port=\"100\"} 1000\nwireguard_sent_bytes_total{interface=\"Pippo\",public_key=\"second_test\",friendly_name=\"this is my friendly name\",remote_ip=\"remote_ip\",allowed_ip_0=\"10.0.0.4\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",allowed_ip_2=\"192.168.0.0\",allowed_subnet_2=\"16\",remote_port=\"100\"} 14\n# HELP wireguard_received_bytes_total Bytes received from the peer\n# TYPE wireguard_received_bytes_total counter\nwireguard_received_bytes_total{interface=\"Pippo\",public_key=\"test\",remote_ip=\"remote_ip\",allowed_ip_0=\"10.0.0.2\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",remote_port=\"100\"} 5000\nwireguard_received_bytes_total{interface=\"Pippo\",public_key=\"second_test\",friendly_name=\"this is my friendly name\",remote_ip=\"remote_ip\",allowed_ip_0=\"10.0.0.4\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",allowed_ip_2=\"192.168.0.0\",allowed_subnet_2=\"16\",remote_port=\"100\"} 1000000000\n# HELP wireguard_latest_handshake_seconds Seconds from the last handshake\n# TYPE wireguard_latest_handshake_seconds gauge\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"test\",remote_ip=\"remote_ip\",allowed_ip_0=\"10.0.0.2\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",remote_port=\"100\"} 500\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"second_test\",friendly_name=\"this is my friendly name\",remote_ip=\"remote_ip\",allowed_ip_0=\"10.0.0.4\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",allowed_ip_2=\"192.168.0.0\",allowed_subnet_2=\"16\",remote_port=\"100\"} 50\n"; const REF_SPLIT :&'static str = "# HELP wireguard_sent_bytes_total Bytes sent to the peer\n# TYPE wireguard_sent_bytes_total counter\nwireguard_sent_bytes_total{interface=\"Pippo\",public_key=\"test\",remote_ip=\"remote_ip\",allowed_ip_0=\"10.0.0.2\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",remote_port=\"100\"} 1000\nwireguard_sent_bytes_total{interface=\"Pippo\",public_key=\"second_test\",friendly_name=\"this is my friendly name\",remote_ip=\"remote_ip\",allowed_ip_0=\"10.0.0.4\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",allowed_ip_2=\"192.168.0.0\",allowed_subnet_2=\"16\",remote_port=\"100\"} 14\n# HELP wireguard_received_bytes_total Bytes received from the peer\n# TYPE wireguard_received_bytes_total counter\nwireguard_received_bytes_total{interface=\"Pippo\",public_key=\"test\",remote_ip=\"remote_ip\",allowed_ip_0=\"10.0.0.2\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",remote_port=\"100\"} 5000\nwireguard_received_bytes_total{interface=\"Pippo\",public_key=\"second_test\",friendly_name=\"this is my friendly name\",remote_ip=\"remote_ip\",allowed_ip_0=\"10.0.0.4\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",allowed_ip_2=\"192.168.0.0\",allowed_subnet_2=\"16\",remote_port=\"100\"} 1000000000\n# HELP wireguard_latest_handshake_seconds Seconds from the last handshake\n# TYPE wireguard_latest_handshake_seconds gauge\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"test\",remote_ip=\"remote_ip\",allowed_ip_0=\"10.0.0.2\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",remote_port=\"100\"} 500\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"second_test\",friendly_name=\"this is my friendly name\",remote_ip=\"remote_ip\",allowed_ip_0=\"10.0.0.4\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",allowed_ip_2=\"192.168.0.0\",allowed_subnet_2=\"16\",remote_port=\"100\"} 50\n";
const REF_SPLIT_NO_REMOTE :&'static str = "# HELP wireguard_sent_bytes_total Bytes sent to the peer\n# TYPE wireguard_sent_bytes_total counter\nwireguard_sent_bytes_total{interface=\"Pippo\",public_key=\"test\",allowed_ip_0=\"10.0.0.2\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\"} 1000\nwireguard_sent_bytes_total{interface=\"Pippo\",public_key=\"second_test\",friendly_name=\"this is my friendly name\",allowed_ip_0=\"10.0.0.4\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",allowed_ip_2=\"192.168.0.0\",allowed_subnet_2=\"16\"} 14\n# HELP wireguard_received_bytes_total Bytes received from the peer\n# TYPE wireguard_received_bytes_total counter\nwireguard_received_bytes_total{interface=\"Pippo\",public_key=\"test\",allowed_ip_0=\"10.0.0.2\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\"} 5000\nwireguard_received_bytes_total{interface=\"Pippo\",public_key=\"second_test\",friendly_name=\"this is my friendly name\",allowed_ip_0=\"10.0.0.4\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",allowed_ip_2=\"192.168.0.0\",allowed_subnet_2=\"16\"} 1000000000\n# HELP wireguard_latest_handshake_seconds Seconds from the last handshake\n# TYPE wireguard_latest_handshake_seconds gauge\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"test\",allowed_ip_0=\"10.0.0.2\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\"} 500\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"second_test\",friendly_name=\"this is my friendly name\",allowed_ip_0=\"10.0.0.4\",allowed_subnet_0=\"32\",allowed_ip_1=\"fd86:ea04:::4\",allowed_subnet_1=\"128\",allowed_ip_2=\"192.168.0.0\",allowed_subnet_2=\"16\"} 50\n";
let re1 = Endpoint::Remote(RemoteEndpoint { let re1 = Endpoint::Remote(RemoteEndpoint {
public_key: "test".to_owned(), public_key: "test".to_owned(),
remote_ip: Some("remote_ip".to_owned()), remote_ip: Some("remote_ip".to_owned()),
@ -355,11 +360,13 @@ wg0\t928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=\t(none)\t5.90.62.106:21741\t10
}; };
pehm.insert(pe.public_key, pe); pehm.insert(pe.public_key, pe);
let prometheus = wg.render_with_names(Some(&pehm), false); let prometheus = wg.render_with_names(Some(&pehm), false, true);
assert_eq!(prometheus, REF); assert_eq!(prometheus, REF);
let prometheus = wg.render_with_names(Some(&pehm), true); let prometheus = wg.render_with_names(Some(&pehm), true, true);
assert_eq!(prometheus, REF_SPLIT); assert_eq!(prometheus, REF_SPLIT);
}
let prometheus = wg.render_with_names(Some(&pehm), true, false);
assert_eq!(prometheus, REF_SPLIT_NO_REMOTE);
}
} }