From 9f0eb7f0502f071102d8c22c494ea068d075c80e Mon Sep 17 00:00:00 2001 From: Francesco Cogno Date: Sun, 20 Nov 2022 16:13:06 +0100 Subject: [PATCH] Issue/100 (#101) * Updating clap * completed clap ugprade * Upgraded other deps * removed unused use * fixed tests * exported delay * fixed multiple params * added actual calculation --- Cargo.lock | 200 ++++++++++++++++++++++++++--------------------- Cargo.toml | 28 +++---- README.md | 8 +- src/main.rs | 47 +++++------ src/options.rs | 52 ++++-------- src/wireguard.rs | 122 ++++++++++++++++++++++++----- 6 files changed, 270 insertions(+), 187 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77da81e..fac6c6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.56" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" [[package]] name = "arrayref" @@ -118,25 +118,32 @@ dependencies = [ "atty", "bitflags", "strsim 0.8.0", - "textwrap 0.11.0", + "textwrap", "unicode-width", "vec_map", ] [[package]] name = "clap" -version = "3.1.6" +version = "4.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c93436c21e4698bacadf42917db28b23017027a4deccb35dbe47a7e7840123" +checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e" dependencies = [ "atty", "bitflags", - "indexmap", - "lazy_static", - "os_str_bytes", + "clap_lex", + "once_cell", "strsim 0.10.0", "termcolor", - "textwrap 0.15.0", +] + +[[package]] +name = "clap_lex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +dependencies = [ + "os_str_bytes", ] [[package]] @@ -215,9 +222,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" dependencies = [ "atty", "humantime 2.1.0", @@ -289,12 +296,6 @@ dependencies = [ "wasi 0.9.0+wasi-snapshot-preview1", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - [[package]] name = "hermit-abi" version = "0.1.19" @@ -306,9 +307,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", @@ -328,9 +329,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -355,9 +356,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.17" +version = "0.14.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043f0e083e9901b6cc658a77d1eb86f4fc650bbb977a4337dd63192826aa85dd" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" dependencies = [ "bytes", "futures-channel", @@ -393,16 +394,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "indexmap" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "itoa" version = "1.0.1" @@ -426,15 +417,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.119" +version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" [[package]] name = "log" -version = "0.4.14" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] @@ -447,34 +438,14 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "mio" -version = "0.8.1" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba42135c6a5917b9db9cd7b293e5409e1c6b041e6f9825e92e55a894c63b6f8" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", - "miow", - "ntapi", "wasi 0.11.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "ntapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", + "windows-sys", ] [[package]] @@ -556,9 +527,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.10.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "openssl-probe" @@ -571,9 +542,6 @@ name = "os_str_bytes" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr", -] [[package]] name = "pin-project-lite" @@ -616,12 +584,12 @@ dependencies = [ [[package]] name = "prometheus_wireguard_exporter" -version = "3.6.3" +version = "3.6.4" dependencies = [ "anyhow", - "clap 3.1.6", + "clap 4.0.26", "clippy", - "env_logger 0.9.0", + "env_logger 0.9.3", "http", "hyper", "log", @@ -667,9 +635,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.5" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -678,9 +646,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "ring" @@ -785,15 +753,15 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.136" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "8e8b3801309262e8184d9687fb697586833e939767aea0dda89f5a8e650e8bd7" dependencies = [ "itoa", "ryu", @@ -808,9 +776,9 @@ checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", @@ -874,26 +842,20 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", @@ -902,10 +864,11 @@ dependencies = [ [[package]] name = "tokio" -version = "1.17.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" +checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" dependencies = [ + "autocfg", "libc", "mio", "pin-project-lite", @@ -1118,3 +1081,60 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" diff --git a/Cargo.toml b/Cargo.toml index d423c8f..0ecde34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "prometheus_wireguard_exporter" -version = "3.6.3" +version = "3.6.4" authors = ["Francesco Cogno "] description = "Prometheus WireGuard Exporter" edition = "2018" @@ -19,18 +19,18 @@ default = [] leaky_log = [] [dependencies] -log = "0.4.14" -env_logger = "0.9.0" -clap = { version = "3.1.0", features = ["cargo", "env"] } -serde_json = "1.0" -serde = "1.0" -thiserror = "1.0" -anyhow = "1.0" -hyper = { version = "0.14", features = ["stream"] } -http = "0.2" -tokio = { version = "1.0", features = ["macros", "rt"] } -prometheus_exporter_base = { version = "1.3", features = ["hyper_server"] } -regex = "1.5.4" +log = "0.4.17" +env_logger = "0.9.3" +clap = { version = "4.0.26", features = ["cargo", "env"] } +serde_json = "1.0.88" +serde = "1.0.147" +thiserror = "1.0.37" +anyhow = "1.0.66" +hyper = { version = "0.14.23", features = ["stream"] } +http = "0.2.8" +tokio = { version = "1.22.0", features = ["macros", "rt"] } +prometheus_exporter_base = { version = "1.3.0", features = ["hyper_server"] } +regex = "1.7.0" [dev-dependencies] -clippy = "0.0" +clippy = "0.0.302" diff --git a/README.md b/README.md index f62a149..4277a87 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ [![Crate](https://img.shields.io/crates/v/prometheus_wireguard_exporter.svg)](https://crates.io/crates/prometheus_wireguard_exporter) [![cratedown](https://img.shields.io/crates/d/prometheus_wireguard_exporter.svg)](https://crates.io/crates/prometheus_wireguard_exporter) [![cratelastdown](https://img.shields.io/crates/dv/prometheus_wireguard_exporter.svg)](https://crates.io/crates/prometheus_wireguard_exporter) -[![release](https://img.shields.io/github/release/MindFlavor/prometheus_wireguard_exporter.svg)](https://github.com/MindFlavor/prometheus_wireguard_exporter/tree/3.6.3) -[![tag](https://img.shields.io/github/tag/mindflavor/prometheus_wireguard_exporter.svg)](https://github.com/MindFlavor/prometheus_wireguard_exporter/tree/3.6.3) +[![release](https://img.shields.io/github/release/MindFlavor/prometheus_wireguard_exporter.svg)](https://github.com/MindFlavor/prometheus_wireguard_exporter/tree/3.6.4) +[![tag](https://img.shields.io/github/tag/mindflavor/prometheus_wireguard_exporter.svg)](https://github.com/MindFlavor/prometheus_wireguard_exporter/tree/3.6.4) [![Rust build](https://github.com/mindflavor/prometheus_wireguard_exporter/workflows/Rust/badge.svg)](https://github.com/mindflavor/prometheus_wireguard_exporter/actions?query=workflow%3ARust) -[![commitssince](https://img.shields.io/github/commits-since/mindflavor/prometheus_wireguard_exporter/3.6.3)](https://img.shields.io/github/commits-since/mindflavor/prometheus_wireguard_exporter/3.6.3) +[![commitssince](https://img.shields.io/github/commits-since/mindflavor/prometheus_wireguard_exporter/3.6.4)](https://img.shields.io/github/commits-since/mindflavor/prometheus_wireguard_exporter/3.6.4) [![Docker build](https://github.com/MindFlavor/prometheus_wireguard_exporter/actions/workflows/docker.yml/badge.svg)](https://github.com/qdm12/godevcontainer/actions/workflows/docker.yml) @@ -22,6 +22,7 @@ A Prometheus exporter for [WireGuard](https://www.wireguard.com), written in Rus ## Changelog +* From release [3.6.4](https://github.com/MindFlavor/prometheus_wireguard_exporter/releases/tag/3.6.4) the exporter optionally calculates the delta, in seconds, since the last handshake. The metric is `wireguard_latest_handshake_delay_seconds`. Thanks to [mmahacek](https://github.com/mmahacek) for the [idea](https://github.com/MindFlavor/prometheus_wireguard_exporter/issues/100). * From release [3.6.3](https://github.com/MindFlavor/prometheus_wireguard_exporter/releases/tag/3.6.3) the exporter automatically parses the systemd-networkd's peer syntax too (`[WireGuardPeer]` rather than `[Peer]`). Thanks to [mbonino](https://github.com/mbonino) for the PR (see https://github.com/MindFlavor/prometheus_wireguard_exporter/pull/92). * From release [3.6.1](https://github.com/MindFlavor/prometheus_wireguard_exporter/releases/tag/3.6.1) the exporter correctly escapes the double quotes in `friendly_name`. Thanks to [Steven Wood](https://github.com/stvnw) for finding the bug in #82. * **BREAKING** From version `3.6.0` the exporter takes fallback configuration values from the environment variables. Thanks to [j_r0dd](https://github.com/jr0dd) for the idea. This changes how the exporter evaluates the command line parameters: make sure to consult the documentation on how to convert your command line to the new format. Basically every switch (for example verbose `-v`) not expect values, either `true` or `false`. This is necessary because there is no way to discriminate between an empty environment variable and one that has not been set. @@ -125,6 +126,7 @@ prometheus_wireguard_exporter -a true -v true <...> | `-s` | `PROMETHEUS_WIREGUARD_EXPORTER_SEPARATE_ALLOWED_IPS_ENABLED` | No | `true` or `false` | `false` | No | Enable the allowed ip + subnet split mode for the labels. | `-r` | `PROMETHEUS_WIREGUARD_EXPORTER_EXPORT_REMOTE_IP_AND_PORT_ENABLED` | No | `true` or `false` | `false` | No | Exports peer's remote ip and port as labels (if available). | `-i` | `PROMETHEUS_WIREGUARD_EXPORTER_INTERFACES` | No | Your interface name(s) | `all` | Yes | Specifies the interface(s) passed to the `wg show dump` parameter. Multiple parameters are allowed. +| `-d` | `EXPORT_LATEST_HANDSHAKE_DELAY` | No | `true` or `false` | `false` | No | Adds the `wireguard_latest_handshake_delay_seconds` metric that automatically calculates the seconds passed since the last handshake. Keep in mind that command line values take precedence over environment variables. diff --git a/src/main.rs b/src/main.rs index df92d44..5d7c8a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,5 @@ use anyhow::Context; -//extern crate serde_json; -use clap::{crate_authors, crate_name, crate_version, Arg}; +use clap::{crate_authors, crate_name, crate_version, value_parser, Arg}; use hyper::{Body, Request}; use log::{debug, info, trace}; use std::env; @@ -105,11 +104,7 @@ async fn perform_request( } if let Some(wg_accumulator) = wg_accumulator { - Ok(wg_accumulator.render_with_names( - peer_entry_hashmap.as_ref(), - options.separate_allowed_ips, - options.export_remote_ip_and_port, - )) + Ok(wg_accumulator.render_with_names(peer_entry_hashmap.as_ref(), &options)) } else { panic!(); } @@ -125,74 +120,81 @@ async fn main() -> Result<(), Box> { .short('l') .long("address") .env("PROMETHEUS_WIREGUARD_EXPORTER_ADDRESS") + .value_parser(value_parser!(IpAddr)) .help("exporter address") .default_value("0.0.0.0") - .takes_value(true), ) .arg( Arg::new("port") .short('p') .long("port") .env("PROMETHEUS_WIREGUARD_EXPORTER_PORT") + .value_parser(value_parser!(u16)) .help("exporter port") .default_value("9586") - .takes_value(true), ) .arg( Arg::new("verbose") .short('v') .long("verbose") .env("PROMETHEUS_WIREGUARD_EXPORTER_VERBOSE_ENABLED") + .value_parser(value_parser!(bool)) .help("verbose logging") .default_value("false") - .takes_value(true), ) .arg( Arg::new("prepend_sudo") .short('a') .long("prepend_sudo") .env("PROMETHEUS_WIREGUARD_EXPORTER_PREPEND_SUDO_ENABLED") + .value_parser(value_parser!(bool)) .help("Prepend sudo to the wg show commands") .default_value("false") - .takes_value(true), ) .arg( Arg::new("separate_allowed_ips") .short('s') .long("separate_allowed_ips") .env("PROMETHEUS_WIREGUARD_EXPORTER_SEPARATE_ALLOWED_IPS_ENABLED") + .value_parser(value_parser!(bool)) .help("separate allowed ips and ports") .default_value("false") - .takes_value(true), ) .arg( Arg::new("export_remote_ip_and_port") .short('r') .long("export_remote_ip_and_port") .env("PROMETHEUS_WIREGUARD_EXPORTER_EXPORT_REMOTE_IP_AND_PORT_ENABLED") + .value_parser(value_parser!(bool)) .help("exports peer's remote ip and port as labels (if available)") .default_value("false") - .takes_value(true), ) .arg( Arg::new("extract_names_config_files") .short('n') .long("extract_names_config_files") + .num_args(0..) .env("PROMETHEUS_WIREGUARD_EXPORTER_CONFIG_FILE_NAMES") .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). Multiple files are supported.") - .multiple_values(true) - .use_value_delimiter(true) - .takes_value(true)) + .use_value_delimiter(false)) .arg( Arg::new("interfaces") .short('i') .long("interfaces") + .num_args(0..) .env("PROMETHEUS_WIREGUARD_EXPORTER_INTERFACES") .help("If set specifies the interface passed to the wg show command. It is relative to the same position config_file. In not specified, all will be passed.") - .multiple_values(true) - .use_value_delimiter(true) - .takes_value(true)) - .get_matches(); + .use_value_delimiter(false)) + .arg( + Arg::new("export_latest_handshake_delay") + .short('d') + .long("export_latest_handshake_delay") + .env("EXPORT_LATEST_HANDSHAKE_DELAY") + .value_parser(value_parser!(bool)) + .help("exports runtime calculated latest handshake delay") + .default_value("false") + ) + .get_matches(); let options = Options::from_claps(&matches); @@ -216,9 +218,8 @@ async fn main() -> Result<(), Box> { ); info!("using options: {:?}", options); - let bind = matches.value_of("port").unwrap(); - let bind = bind.parse::().expect("port must be a valid number"); - let ip = matches.value_of("addr").unwrap().parse::().unwrap(); + let bind: u16 = *matches.get_one("port").unwrap(); + let ip: IpAddr = *matches.get_one("addr").unwrap(); let addr = (ip, bind).into(); info!("starting exporter on http://{}/metrics", addr); diff --git a/src/options.rs b/src/options.rs index 9097c54..4ef5e20 100644 --- a/src/options.rs +++ b/src/options.rs @@ -1,3 +1,5 @@ +use clap::parser::ValuesRef; + #[derive(Debug, Clone)] pub(crate) struct Options { pub verbose: bool, @@ -6,49 +8,27 @@ pub(crate) struct Options { pub extract_names_config_files: Option>, pub interfaces: Option>, pub export_remote_ip_and_port: bool, + pub export_latest_handshake_delay: bool, } impl Options { pub fn from_claps(matches: &clap::ArgMatches) -> Options { let options = Options { - verbose: matches - .value_of("verbose") - .map(|e| { - e.to_lowercase() - .parse() - .expect("cannot parse verbose as a bool") - }) - .unwrap_or_default(), - prepend_sudo: matches - .value_of("prepend_sudo") - .map(|e| { - e.to_lowercase() - .parse() - .expect("cannot parse prepend_sudo as a bool") - }) - .unwrap_or_default(), - separate_allowed_ips: matches - .value_of("separate_allowed_ips") - .map(|e| { - e.to_lowercase() - .parse() - .expect("cannot parse separate_allowed_ips as a bool") - }) - .unwrap_or_default(), + verbose: *matches.get_one("verbose").unwrap_or(&false), + prepend_sudo: *matches.get_one("prepend_sudo").unwrap_or(&false), + separate_allowed_ips: *matches.get_one("separate_allowed_ips").unwrap_or(&false), extract_names_config_files: matches - .values_of("extract_names_config_files") - .map(|e| e.into_iter().map(|e| e.to_owned()).collect()), + .get_many("extract_names_config_files") + .map(|e: ValuesRef<'_, String>| e.into_iter().map(|a| a.to_owned()).collect()), interfaces: matches - .values_of("interfaces") - .map(|e| e.into_iter().map(|a| a.to_owned()).collect()), - export_remote_ip_and_port: matches - .value_of("export_remote_ip_and_port") - .map(|e| { - e.to_lowercase() - .parse() - .expect("cannot parse export_remote_ip_and_port as a bool") - }) - .unwrap_or_default(), + .get_many("interfaces") + .map(|e: ValuesRef<'_, String>| e.into_iter().map(|a| a.to_string()).collect()), + export_remote_ip_and_port: *matches + .get_one("export_remote_ip_and_port") + .unwrap_or(&false), + export_latest_handshake_delay: *matches + .get_one("export_latest_handshake_delay") + .unwrap_or(&false), }; options diff --git a/src/wireguard.rs b/src/wireguard.rs index 788b063..e2090ee 100644 --- a/src/wireguard.rs +++ b/src/wireguard.rs @@ -1,4 +1,5 @@ use crate::exporter_error::ExporterError; +use crate::options::Options; use crate::wireguard_config::PeerEntryHashMap; use crate::FriendlyDescription; use log::{debug, trace}; @@ -8,6 +9,7 @@ use std::collections::HashMap; use std::convert::TryFrom; use std::fmt::Debug; use std::net::SocketAddr; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; const EMPTY: &str = "(none)"; @@ -165,10 +167,12 @@ impl WireGuard { pub(crate) fn render_with_names( &self, pehm: Option<&PeerEntryHashMap>, - split_allowed_ips: bool, - export_remote_ip_and_port: bool, + options: &Options, ) -> String { - debug!("WireGuard::render_with_names(self == {:?}, pehm == {:?}, split_allowed_ips == {:?}, export_remote_ip_and_port == {:?} called", self, pehm, split_allowed_ips,export_remote_ip_and_port); + debug!( + "WireGuard::render_with_names(self == {:?}, pehm == {:?}, options == {:?} called", + self, pehm, options + ); // these are the exported counters let mut pc_sent_bytes_total = PrometheusMetric::build() @@ -184,8 +188,19 @@ impl WireGuard { let mut pc_latest_handshake = PrometheusMetric::build() .with_name("wireguard_latest_handshake_seconds") .with_metric_type(MetricType::Gauge) - .with_help("Seconds from the last handshake") + .with_help("UNIX timestamp seconds of the last handshake") .build(); + let mut pc_latest_handshake_delay = if options.export_latest_handshake_delay { + Some( + PrometheusMetric::build() + .with_name("wireguard_latest_handshake_delay_seconds") + .with_metric_type(MetricType::Gauge) + .with_help("Seconds from the last handshake") + .build(), + ) + } else { + None + }; // Here we make sure we process the interfaces in the // lexicographical order. @@ -214,7 +229,7 @@ impl WireGuard { let mut attributes: Vec<(&str, &str)> = vec![("interface", interface), ("public_key", &ep.public_key)]; - if split_allowed_ips { + if options.separate_allowed_ips { let v_ip_and_subnet: Vec<(&str, &str)> = ep .allowed_ips .split(',') @@ -286,7 +301,7 @@ impl WireGuard { } } - if export_remote_ip_and_port { + if options.export_remote_ip_and_port { if let Some(r_ip) = &ep.remote_ip { attributes.push(("remote_ip", r_ip)); } @@ -304,6 +319,18 @@ impl WireGuard { instance = instance.with_label(h, v); } + pc_latest_handshake_delay + .as_mut() + .map(|pc_latest_handshake_delay| { + let earlier = UNIX_EPOCH + Duration::from_secs(ep.latest_handshake); + let delta = SystemTime::now() + .duration_since(earlier) + .expect("time went backwards"); + pc_latest_handshake_delay.render_and_append_instance( + &instance.clone().with_value(delta.as_secs() as u128), + ) + }); + pc_sent_bytes_total .render_and_append_instance(&instance.clone().with_value(ep.sent_bytes)) .render(); @@ -320,10 +347,15 @@ impl WireGuard { } format!( - "{}\n{}\n{}", + "{}\n{}\n{}{}", pc_sent_bytes_total.render(), pc_received_bytes_total.render(), - pc_latest_handshake.render() + pc_latest_handshake.render(), + pc_latest_handshake_delay.map_or_else( + // this row adds pc_latest_handshake_delay only if configured + || "".to_owned(), + |pc_latest_handshake_delay| format!("\n{}", pc_latest_handshake_delay.render()) + ) ) } } @@ -397,7 +429,17 @@ wg0\tsUsR6xufQQ8Tf0FuyY9tfEeYdhVMeFelr4ZMUrj+B0E=\t(none)\t10.211.123.128:51820\ let pe = PeerEntryHashMap::new(); - let s = a.render_with_names(Some(&pe), true, true); + let options = Options { + verbose: true, + prepend_sudo: true, + separate_allowed_ips: true, + extract_names_config_files: None, + interfaces: None, + export_remote_ip_and_port: true, + export_latest_handshake_delay: true, + }; + + let s = a.render_with_names(Some(&pe), &options); println!("{}", s); let s_ok = "# HELP wireguard_sent_bytes_total Bytes sent to the peer @@ -440,7 +482,7 @@ wireguard_received_bytes_total{interface=\"wg0\",public_key=\"yjeBkrZqUThSSHySFz wireguard_received_bytes_total{interface=\"wg0\",public_key=\"HtOSi37ALMnSkeAFqeWYZqlBnZqAJERhb5o/i3ZPEFI=\",remote_ip=\"10.211.123.127\",allowed_ip_0=\"10.90.0.17\",allowed_subnet_0=\"32\",remote_port=\"51820\"} 62592693520 wireguard_received_bytes_total{interface=\"wg0\",public_key=\"sUsR6xufQQ8Tf0FuyY9tfEeYdhVMeFelr4ZMUrj+B0E=\",remote_ip=\"10.211.123.128\",allowed_ip_0=\"10.90.0.18\",allowed_subnet_0=\"32\",remote_port=\"51820\"} 75066288152 -# HELP wireguard_latest_handshake_seconds Seconds from the last handshake +# HELP wireguard_latest_handshake_seconds UNIX timestamp seconds of the last handshake # TYPE wireguard_latest_handshake_seconds gauge wireguard_latest_handshake_seconds{interface=\"wg0\",public_key=\"923V/iAdcz8BcqB0Xo6pDJzARGBJCQ6fWe+peixQyB4=\",remote_ip=\"10.211.123.112\",allowed_ip_0=\"10.90.0.10\",allowed_subnet_0=\"32\",allowed_ip_1=\"10.0.1.0\",allowed_subnet_1=\"24\",remote_port=\"51820\"} 0 wireguard_latest_handshake_seconds{interface=\"wg0\",public_key=\"9M1fhLa9sIlT39z+SI/0a5H3mNSHYmM+NGA6sirD2nU=\",remote_ip=\"10.211.123.113\",allowed_ip_0=\"10.90.0.3\",allowed_subnet_0=\"32\",allowed_ip_1=\"10.198.171.0\",allowed_subnet_1=\"24\",remote_port=\"51820\"} 0 @@ -487,13 +529,24 @@ wireguard_latest_handshake_seconds{interface=\"wg0\",public_key=\"sUsR6xufQQ8Tf0 #[test] fn test_parse_and_serialize() { let a = WireGuard::try_from(TEXT).unwrap(); - let s = a.render_with_names(None, false, true); + + let options = Options { + verbose: true, + prepend_sudo: true, + separate_allowed_ips: false, + extract_names_config_files: None, + interfaces: None, + export_remote_ip_and_port: true, + export_latest_handshake_delay: true, + }; + + let s = a.render_with_names(None, &options); println!("{}", s); } #[test] fn test_render_to_prometheus_simple() { - const REF : &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_ips=\"to_change\",remote_ip=\"remote_ip\",remote_port=\"100\"} 1000\n\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_ips=\"to_change\",remote_ip=\"remote_ip\",remote_port=\"100\"} 5000\n\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_ips=\"to_change\",remote_ip=\"remote_ip\",remote_port=\"100\"} 500\n"; + const REF : &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_ips=\"to_change\",remote_ip=\"remote_ip\",remote_port=\"100\"} 1000\n\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_ips=\"to_change\",remote_ip=\"remote_ip\",remote_port=\"100\"} 5000\n\n# HELP wireguard_latest_handshake_seconds UNIX timestamp seconds of the last handshake\n# TYPE wireguard_latest_handshake_seconds gauge\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"test\",allowed_ips=\"to_change\",remote_ip=\"remote_ip\",remote_port=\"100\"} 500\n"; let re = Endpoint::Remote(RemoteEndpoint { public_key: "test".to_owned(), @@ -513,7 +566,17 @@ wireguard_latest_handshake_seconds{interface=\"wg0\",public_key=\"sUsR6xufQQ8Tf0 v.push(re); wg.interfaces.insert("Pippo".to_owned(), v); - let prometheus = wg.render_with_names(None, false, true); + let options = Options { + verbose: true, + prepend_sudo: true, + separate_allowed_ips: false, + extract_names_config_files: None, + interfaces: None, + export_remote_ip_and_port: true, + export_latest_handshake_delay: true, + }; + + let prometheus = wg.render_with_names(None, &options); assert_eq!(prometheus, REF); } @@ -522,13 +585,13 @@ wireguard_latest_handshake_seconds{interface=\"wg0\",public_key=\"sUsR6xufQQ8Tf0 fn test_render_to_prometheus_complex() { use crate::wireguard_config::PeerEntry; - const REF :&'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_ips=\"10.0.0.2/32,fd86:ea04:::4/128\",remote_ip=\"remote_ip\",remote_port=\"100\"} 1000\nwireguard_sent_bytes_total{interface=\"Pippo\",public_key=\"second_test\",allowed_ips=\"10.0.0.4/32,fd86:ea04:::4/128,192.168.0.0/16\",friendly_name=\"this is my friendly name\",remote_ip=\"remote_ip\",remote_port=\"100\"} 14\n\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_ips=\"10.0.0.2/32,fd86:ea04:::4/128\",remote_ip=\"remote_ip\",remote_port=\"100\"} 5000\nwireguard_received_bytes_total{interface=\"Pippo\",public_key=\"second_test\",allowed_ips=\"10.0.0.4/32,fd86:ea04:::4/128,192.168.0.0/16\",friendly_name=\"this is my friendly name\",remote_ip=\"remote_ip\",remote_port=\"100\"} 1000000000\n\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_ips=\"10.0.0.2/32,fd86:ea04:::4/128\",remote_ip=\"remote_ip\",remote_port=\"100\"} 500\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"second_test\",allowed_ips=\"10.0.0.4/32,fd86:ea04:::4/128,192.168.0.0/16\",friendly_name=\"this is my friendly name\",remote_ip=\"remote_ip\",remote_port=\"100\"} 50\n"; + const REF :&'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_ips=\"10.0.0.2/32,fd86:ea04:::4/128\",remote_ip=\"remote_ip\",remote_port=\"100\"} 1000\nwireguard_sent_bytes_total{interface=\"Pippo\",public_key=\"second_test\",allowed_ips=\"10.0.0.4/32,fd86:ea04:::4/128,192.168.0.0/16\",friendly_name=\"this is my friendly name\",remote_ip=\"remote_ip\",remote_port=\"100\"} 14\n\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_ips=\"10.0.0.2/32,fd86:ea04:::4/128\",remote_ip=\"remote_ip\",remote_port=\"100\"} 5000\nwireguard_received_bytes_total{interface=\"Pippo\",public_key=\"second_test\",allowed_ips=\"10.0.0.4/32,fd86:ea04:::4/128,192.168.0.0/16\",friendly_name=\"this is my friendly name\",remote_ip=\"remote_ip\",remote_port=\"100\"} 1000000000\n\n# HELP wireguard_latest_handshake_seconds UNIX timestamp seconds of the last handshake\n# TYPE wireguard_latest_handshake_seconds gauge\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"test\",allowed_ips=\"10.0.0.2/32,fd86:ea04:::4/128\",remote_ip=\"remote_ip\",remote_port=\"100\"} 500\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"second_test\",allowed_ips=\"10.0.0.4/32,fd86:ea04:::4/128,192.168.0.0/16\",friendly_name=\"this is my friendly name\",remote_ip=\"remote_ip\",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\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\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\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\n# HELP wireguard_latest_handshake_seconds UNIX timestamp seconds of 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\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\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"; + 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\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\n# HELP wireguard_latest_handshake_seconds UNIX timestamp seconds of 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"; - const REF_JSON :&'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_ips=\"10.0.0.2/32,fd86:ea04:::4/128\",remote_ip=\"remote_ip\",remote_port=\"100\"} 1000\nwireguard_sent_bytes_total{interface=\"Pippo\",public_key=\"second_test\",allowed_ips=\"10.0.0.4/32,fd86:ea04:::4/128,192.168.0.0/16\",remote_ip=\"remote_ip\",auth_date=\"1614869789\",first_name=\"Coordinator\",id=\"482217555\",last_name=\"DrProxy.me\",username=\"DrProxyMeCoordinator\",remote_port=\"100\"} 14\n\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_ips=\"10.0.0.2/32,fd86:ea04:::4/128\",remote_ip=\"remote_ip\",remote_port=\"100\"} 5000\nwireguard_received_bytes_total{interface=\"Pippo\",public_key=\"second_test\",allowed_ips=\"10.0.0.4/32,fd86:ea04:::4/128,192.168.0.0/16\",remote_ip=\"remote_ip\",auth_date=\"1614869789\",first_name=\"Coordinator\",id=\"482217555\",last_name=\"DrProxy.me\",username=\"DrProxyMeCoordinator\",remote_port=\"100\"} 1000000000\n\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_ips=\"10.0.0.2/32,fd86:ea04:::4/128\",remote_ip=\"remote_ip\",remote_port=\"100\"} 500\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"second_test\",allowed_ips=\"10.0.0.4/32,fd86:ea04:::4/128,192.168.0.0/16\",remote_ip=\"remote_ip\",auth_date=\"1614869789\",first_name=\"Coordinator\",id=\"482217555\",last_name=\"DrProxy.me\",username=\"DrProxyMeCoordinator\",remote_port=\"100\"} 50\n"; + const REF_JSON :&'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_ips=\"10.0.0.2/32,fd86:ea04:::4/128\",remote_ip=\"remote_ip\",remote_port=\"100\"} 1000\nwireguard_sent_bytes_total{interface=\"Pippo\",public_key=\"second_test\",allowed_ips=\"10.0.0.4/32,fd86:ea04:::4/128,192.168.0.0/16\",remote_ip=\"remote_ip\",auth_date=\"1614869789\",first_name=\"Coordinator\",id=\"482217555\",last_name=\"DrProxy.me\",username=\"DrProxyMeCoordinator\",remote_port=\"100\"} 14\n\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_ips=\"10.0.0.2/32,fd86:ea04:::4/128\",remote_ip=\"remote_ip\",remote_port=\"100\"} 5000\nwireguard_received_bytes_total{interface=\"Pippo\",public_key=\"second_test\",allowed_ips=\"10.0.0.4/32,fd86:ea04:::4/128,192.168.0.0/16\",remote_ip=\"remote_ip\",auth_date=\"1614869789\",first_name=\"Coordinator\",id=\"482217555\",last_name=\"DrProxy.me\",username=\"DrProxyMeCoordinator\",remote_port=\"100\"} 1000000000\n\n# HELP wireguard_latest_handshake_seconds UNIX timestamp seconds of the last handshake\n# TYPE wireguard_latest_handshake_seconds gauge\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"test\",allowed_ips=\"10.0.0.2/32,fd86:ea04:::4/128\",remote_ip=\"remote_ip\",remote_port=\"100\"} 500\nwireguard_latest_handshake_seconds{interface=\"Pippo\",public_key=\"second_test\",allowed_ips=\"10.0.0.4/32,fd86:ea04:::4/128,192.168.0.0/16\",remote_ip=\"remote_ip\",auth_date=\"1614869789\",first_name=\"Coordinator\",id=\"482217555\",last_name=\"DrProxy.me\",username=\"DrProxyMeCoordinator\",remote_port=\"100\"} 50\n"; let re1 = Endpoint::Remote(RemoteEndpoint { public_key: "test".to_owned(), @@ -570,13 +633,27 @@ wireguard_latest_handshake_seconds{interface=\"wg0\",public_key=\"sUsR6xufQQ8Tf0 }; pehm.insert(pe.public_key, pe.clone()); - let prometheus = wg.render_with_names(Some(&pehm), false, true); + let mut options = Options { + verbose: true, + prepend_sudo: true, + separate_allowed_ips: false, + extract_names_config_files: None, + interfaces: None, + export_remote_ip_and_port: true, + export_latest_handshake_delay: true, + }; + + let prometheus = wg.render_with_names(Some(&pehm), &options); assert_eq!(prometheus, REF); - let prometheus = wg.render_with_names(Some(&pehm), true, true); + options.separate_allowed_ips = true; + + let prometheus = wg.render_with_names(Some(&pehm), &options); assert_eq!(prometheus, REF_SPLIT); - let prometheus = wg.render_with_names(Some(&pehm), true, false); + options.export_remote_ip_and_port = false; + + let prometheus = wg.render_with_names(Some(&pehm), &options); assert_eq!(prometheus, REF_SPLIT_NO_REMOTE); // second test @@ -604,7 +681,10 @@ wireguard_latest_handshake_seconds{interface=\"wg0\",public_key=\"sUsR6xufQQ8Tf0 }; pehm.insert(pe.public_key, pe.clone()); - let prometheus = wg.render_with_names(Some(&pehm), false, true); + options.separate_allowed_ips = false; + options.export_remote_ip_and_port = true; + + let prometheus = wg.render_with_names(Some(&pehm), &options); assert_eq!(prometheus, REF_JSON); } }