prometheus_wireguard_exporter/src/wireguard_config.rs

153 lines
3.8 KiB
Rust
Raw Normal View History

2019-05-17 10:17:06 +02:00
use crate::exporter_error::PeerEntryParseError;
2019-05-15 16:55:07 +02:00
use std::collections::HashMap;
2019-05-17 10:17:06 +02:00
use std::convert::TryFrom;
2019-05-15 16:55:07 +02:00
#[derive(Debug, Default, Clone)]
2019-05-16 20:45:04 +02:00
pub(crate) struct PeerEntry<'a> {
pub public_key: &'a str,
pub allowed_ips: &'a str,
pub name: Option<&'a str>,
2019-05-15 16:55:07 +02:00
}
2019-05-16 20:45:04 +02:00
#[inline]
2019-05-17 10:17:06 +02:00
fn after_char(s: &str, c_split: char) -> &str {
2019-05-16 20:45:04 +02:00
let mut p: usize = 0;
for c in s.chars().into_iter() {
2019-05-17 10:17:06 +02:00
if c == c_split {
2019-05-16 20:45:04 +02:00
return &s[p + 1..];
} else {
p += c.len_utf8();
}
}
s
}
2019-05-17 10:17:06 +02:00
fn parse_peer_entry<'a>(lines: &[&'a str]) -> Result<PeerEntry<'a>, PeerEntryParseError> {
2019-05-16 20:45:04 +02:00
let mut public_key = "";
let mut allowed_ips = "";
let mut name = None;
for line in lines {
if line.starts_with("PublicKey") {
2019-05-17 10:17:06 +02:00
public_key = after_char(line, '=').trim();
2019-05-16 20:45:04 +02:00
} else if line.starts_with("AllowedIPs") {
2019-05-17 10:17:06 +02:00
allowed_ips = after_char(line, '=').trim();
2019-05-16 20:45:04 +02:00
} else if line.starts_with("#") {
name = Some(line[1..].trim());
}
}
2019-05-17 10:17:06 +02:00
// Sanity checks
if public_key == "" {
let lines_owned: Vec<String> = lines.into_iter().map(|line| line.to_string()).collect();
Err(PeerEntryParseError::PublicKeyNotFound { lines: lines_owned })
} else if allowed_ips == "" {
let lines_owned: Vec<String> = lines.into_iter().map(|line| line.to_string()).collect();
Err(PeerEntryParseError::AllowedIPsEntryNotFound { lines: lines_owned })
} else {
Ok(PeerEntry {
public_key,
allowed_ips,
name, // name can be None
})
2019-05-16 20:45:04 +02:00
}
}
2019-05-17 10:17:06 +02:00
pub(crate) fn parse<'a>(
txt: &'a str,
) -> Result<HashMap<&'a str, PeerEntry<'a>>, PeerEntryParseError> {
2019-05-15 16:55:07 +02:00
let mut ht = HashMap::new();
2019-05-16 20:45:04 +02:00
let mut v_blocks = Vec::new();
let mut cur_block: Option<Vec<&str>> = 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);
}
2019-05-15 16:55:07 +02:00
}
}
2019-05-16 20:45:04 +02:00
}
2019-05-15 16:55:07 +02:00
2019-05-16 20:45:04 +02:00
if let Some(cur_block) = cur_block {
// we have a leftover block
v_blocks.push(cur_block);
}
println!("v_blocks == {:?}", v_blocks);
for block in &v_blocks {
2019-05-17 10:17:06 +02:00
let p = parse_peer_entry(block)?;
2019-05-16 20:45:04 +02:00
ht.insert(p.public_key, p);
}
println!("ht == {:?}", ht);
2019-05-15 16:55:07 +02:00
2019-05-17 10:17:06 +02:00
Ok(ht)
2019-05-15 16:55:07 +02:00
}
#[cfg(test)]
mod tests {
use super::*;
const TEXT: &'static str = "
ListenPort = 51820
PrivateKey = my_super_secret_private_key
# PreUp = iptables -t nat -A POSTROUTING -s 10.70.0.0/24 -o enp7s0 -j MASQUERADE
# PostDown = iptables -t nat -D POSTROUTING -s 10.70.0.0/24 -o enp7s0 -j MASQUERADE
[Peer]
2019-05-16 20:45:04 +02:00
# OnePlus 6T
2019-05-15 16:55:07 +02:00
PublicKey = 2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=
AllowedIPs = 10.70.0.2/32
[Peer]
2019-05-16 20:45:04 +02:00
# varch.local (laptop)
2019-05-15 16:55:07 +02:00
PublicKey = qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=
AllowedIPs = 10.70.0.3/32
[Peer]
2019-05-16 20:45:04 +02:00
# cantarch
2019-05-15 16:55:07 +02:00
PublicKey = L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=
AllowedIPs = 10.70.0.4/32
[Peer]
2019-05-16 20:45:04 +02:00
# frcognoarch
2019-05-15 16:55:07 +02:00
PublicKey = MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=
AllowedIPs = 10.70.0.50/32
[Peer]
2019-05-16 20:45:04 +02:00
# frcognowin10
2019-05-15 16:55:07 +02:00
PublicKey = lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=
AllowedIPs = 10.70.0.40/32
[Peer]
2019-05-16 20:45:04 +02:00
# OnePlus 5T
2019-05-15 16:55:07 +02:00
PublicKey = 928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=
AllowedIPs = 10.70.0.80/32
";
#[test]
fn test_parse() {
let a = parse(TEXT);
println!("{:?}", a);
}
#[test]
fn test_parse_and_serialize() {}
}