From c0140aa3ace8e9d87f118c56d242a2afbea36d33 Mon Sep 17 00:00:00 2001 From: Simon Garrelou Date: Fri, 2 Jun 2023 21:23:29 +0200 Subject: Put each function into its own file --- src/add.rs | 33 ++++++++++++ src/config.rs | 16 ++++++ src/configuration.rs | 31 ----------- src/list.rs | 14 +++++ src/main.rs | 143 ++++++++++++--------------------------------------- src/rm.rs | 36 +++++++++++++ src/wgcmd.rs | 25 +++++++++ 7 files changed, 157 insertions(+), 141 deletions(-) create mode 100644 src/add.rs create mode 100644 src/config.rs delete mode 100644 src/configuration.rs create mode 100644 src/list.rs create mode 100644 src/rm.rs create mode 100644 src/wgcmd.rs diff --git a/src/add.rs b/src/add.rs new file mode 100644 index 0000000..8ccf53b --- /dev/null +++ b/src/add.rs @@ -0,0 +1,33 @@ +use std::{net::Ipv4Addr, str::FromStr, fs::File}; +use std::io::Write; +use anyhow::{anyhow, Result}; +use crate::wg::{config::WireguardConfig, peer::Peer}; + +pub fn run(wg_conf: &mut WireguardConfig, wg_conf_path: String, peer_name: &String, ip: Option<&String>) -> Result<()> { + let ip = match ip { + Some(s) => { + Ipv4Addr::from_str(s.as_str())? + }, + None => { + match wg_conf.next_free_ip() { + Ok(i) => i, + Err(e) => { + return Err(e); + } + } + } + }; + + match wg_conf.get_peer(peer_name.as_str()) { + Some(_) => { return Err(anyhow!("There is already a peer named {}", peer_name)); }, + None => {} + } + + let p = Peer::new(peer_name.clone(), ip)?; + wg_conf.peers.push(p); + + let mut f = File::create(wg_conf_path)?; + write!(f, "{}", wg_conf.gen_config()?)?; + + Ok(()) +} \ No newline at end of file diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..5ae4e1e --- /dev/null +++ b/src/config.rs @@ -0,0 +1,16 @@ +use crate::wg::config::WireguardConfig; +use crate::Configuration; +use anyhow::{anyhow, Result}; + +pub fn run(wg_conf: &WireguardConfig, conf: &Configuration, peer_name: String, is_full: bool) -> Result<()> { + let peer = match wg_conf.get_peer(peer_name.as_str()) { + Some(p) => p, + None => { + return Err(anyhow!("No such peer: {}", peer_name)); + } + }; + + println!("{}", peer.gen_config(wg_conf, conf.dns.clone(), conf.endpoint.clone(), conf.port, is_full)?); + + Ok(()) +} \ No newline at end of file diff --git a/src/configuration.rs b/src/configuration.rs deleted file mode 100644 index 839db24..0000000 --- a/src/configuration.rs +++ /dev/null @@ -1,31 +0,0 @@ -use serde::Deserialize; -use anyhow::{Result, anyhow, Context}; -use std::fs::read_to_string; - -#[derive(Deserialize)] -pub struct Configuration { - pub endpoint: String, - pub wgconf: String, - pub port: Option, - pub dns: Option, -} - -pub fn find_configuration_file(argument: Option<&String>) -> Result { - match argument { - Some(p) => { - if let Ok(t) = read_to_string(p) { - let c: Configuration = toml::from_str(&t).context("parsing configuration file")?; - return Ok(c) - } - }, - None => { - // Try /etc/wgmgr.toml - if let Ok(t) = read_to_string("/etc/wgmgr.toml") { - let c: Configuration = toml::from_str(&t).context("parsing /etc/wgmgr.toml")?; - return Ok(c) - } - }, - }; - - Err(anyhow!("Could not find a valid configuration file for wgmgr.")) -} diff --git a/src/list.rs b/src/list.rs new file mode 100644 index 0000000..3baba8f --- /dev/null +++ b/src/list.rs @@ -0,0 +1,14 @@ +use crate::wg::config::WireguardConfig; + +pub fn run(wg_conf: &WireguardConfig) { + let mut max_length = 0; + for p in wg_conf.peers.iter() { + if p.name.len() > max_length { + max_length = p.name.len(); + } + } + + for p in wg_conf.peers.iter() { + println!("{:max_length$} | {}", p.name, p.ip); + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 3f82d43..17b920d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,17 @@ -use std::fs::File; -use std::net::Ipv4Addr; -use std::str::FromStr; use std::{env, process::exit}; -use std::io::Write; -use std::process::Command as processCommand; + use anyhow::{Result, anyhow, Context}; use clap::{arg, command, Command}; -use wg::config::WireguardConfig; +use serde::Deserialize; +use std::fs::read_to_string; mod wg; -mod configuration; +mod list; +mod rm; +mod add; +mod wgcmd; +mod config; fn main() { let matches = command!() @@ -80,7 +81,7 @@ fn main() { // Find the configuration file for wgmgr - let wgmgr_conf = match configuration::find_configuration_file(matches.get_one::("config")) { + let wgmgr_conf = match find_configuration_file(matches.get_one::("config")) { Ok(c) => c, Err(e) => { eprintln!("Could not find wgmgr configuration file. Place it at /etc/wgmgr.toml or use the --config flag."); @@ -102,7 +103,7 @@ fn main() { match matches.subcommand() { Some(("ls", _)) => { - do_list(&wg_conf); + list::run(&wg_conf); } Some(("config", args)) => { @@ -122,7 +123,7 @@ fn main() { None => false }; - if let Err(e) = do_config(&wg_conf, &wgmgr_conf, peer_name.to_string(), is_full) { + if let Err(e) = config::run(&wg_conf, &wgmgr_conf, peer_name.to_string(), is_full) { eprintln!("Error generating configuration for {}: {:?}", peer_name.to_string(), e); exit(1); } @@ -133,7 +134,7 @@ fn main() { Some(("add", args)) => { let new_name = args.get_one::("NAME").unwrap().to_string(); - if let Err(e) = do_add(&mut wg_conf, wgmgr_conf.wgconf, &new_name, args.get_one::("ip")) { + if let Err(e) = add::run(&mut wg_conf, wgmgr_conf.wgconf, &new_name, args.get_one::("ip")) { eprintln!("Error adding peer: {:?}", e); exit(1); } @@ -144,7 +145,7 @@ fn main() { Some(("rm", args)) => { let rm_name = args.get_one::("NAME").unwrap().to_string(); - if let Err(e) = do_rm(&mut wg_conf, wgmgr_conf.wgconf, &rm_name) { + if let Err(e) = rm::run(&mut wg_conf, wgmgr_conf.wgconf, &rm_name) { eprintln!("Error removing peer: {:?}", e); exit(1); } @@ -153,7 +154,7 @@ fn main() { }, Some(("wg", _)) => { - if let Err(e) = do_wg(&wg_conf) { + if let Err(e) = wgcmd::run(&wg_conf) { eprintln!("{:?}", e); exit(1); } @@ -166,109 +167,31 @@ fn main() { } -fn do_list(wg_conf: &wg::config::WireguardConfig) { - let mut max_length = 0; - for p in wg_conf.peers.iter() { - if p.name.len() > max_length { - max_length = p.name.len(); - } - } - - for p in wg_conf.peers.iter() { - println!("{:max_length$} | {}", p.name, p.ip); - } +#[derive(Deserialize)] +pub struct Configuration { + pub endpoint: String, + pub wgconf: String, + pub port: Option, + pub dns: Option, } -fn do_config(wg_conf: &wg::config::WireguardConfig, conf: &configuration::Configuration, peer_name: String, is_full: bool) -> Result<()> { - let peer = match wg_conf.get_peer(peer_name.as_str()) { - Some(p) => p, - None => { - return Err(anyhow!("No such peer: {}", peer_name)); - } - }; - - println!("{}", peer.gen_config(wg_conf, conf.dns.clone(), conf.endpoint.clone(), conf.port, is_full)?); - - Ok(()) -} - -fn do_add(wg_conf: &mut WireguardConfig, wg_conf_path: String, peer_name: &String, ip: Option<&String>) -> Result<()> { - let ip = match ip { - Some(s) => { - Ipv4Addr::from_str(s.as_str())? +pub fn find_configuration_file(argument: Option<&String>) -> Result { + match argument { + Some(p) => { + if let Ok(t) = read_to_string(p) { + let c: Configuration = toml::from_str(&t).context("parsing configuration file")?; + return Ok(c) + } }, None => { - match wg_conf.next_free_ip() { - Ok(i) => i, - Err(e) => { - return Err(e); - } + // Try /etc/wgmgr.toml + if let Ok(t) = read_to_string("/etc/wgmgr.toml") { + let c: Configuration = toml::from_str(&t).context("parsing /etc/wgmgr.toml")?; + return Ok(c) } - } + }, }; - match wg_conf.get_peer(peer_name.as_str()) { - Some(_) => { return Err(anyhow!("There is already a peer named {}", peer_name)); }, - None => {} - } - - let p = wg::peer::Peer::new(peer_name.clone(), ip)?; - wg_conf.peers.push(p); - - let mut f = File::create(wg_conf_path)?; - write!(f, "{}", wg_conf.gen_config()?)?; - - Ok(()) + Err(anyhow!("Could not find a valid configuration file for wgmgr.")) } -fn do_rm(wg_conf: &mut WireguardConfig, wg_conf_path: String, peer_name: &String) -> Result<()> { - let mut del_index = 0; - let mut found = false; - let mut pk_path = String::new(); - - for (i, peer) in wg_conf.peers.iter().enumerate() { - if &peer.name == peer_name { - del_index = i; - found = true; - pk_path = peer.private_key_path().context("could not get private key path")?; - break; - } - } - - if !found { - return Err(anyhow!("No such peer: {}", peer_name)); - } - - wg_conf.peers.remove(del_index); - - let mut f = File::create(wg_conf_path.clone()).context(format!("error opening configuration file: {}", wg_conf_path))?; - let data = wg_conf.gen_config().context("error generating configuration")?; - - f.write_all(data.as_bytes()).context(format!("error writing to file: {}", wg_conf_path))?; - - std::fs::remove_file(pk_path).context(format!("could not remove file: {}", wg_conf_path))?; - - Ok(()) -} - -fn do_wg(wg_conf: &WireguardConfig) -> Result<()> { - let wg = processCommand::new("wg") - .env("WG_COLOR_MODE", "always") - .output() - .context("could not run 'wg', is it installed?")?; - - if !wg.status.success() { - let err = String::from_utf8(wg.stderr)?; - return Err(anyhow!("error running 'wg': {}", err)); - } - - let mut out = String::from_utf8(wg.stdout).context("error parsing stdout")?; - - for peer in wg_conf.peers.iter() { - out = out.replace(peer.public_key.as_str(), peer.name.as_str()); - } - - println!("{}", out); - - Ok(()) -} diff --git a/src/rm.rs b/src/rm.rs new file mode 100644 index 0000000..61880d2 --- /dev/null +++ b/src/rm.rs @@ -0,0 +1,36 @@ +use std::{fs::File, io::Write}; + +use anyhow::{anyhow, Result, Context}; + +use crate::wg::config::WireguardConfig; + +pub fn run(wg_conf: &mut WireguardConfig, wg_conf_path: String, peer_name: &String) -> Result<()> { + let mut del_index = 0; + let mut found = false; + let mut pk_path = String::new(); + + for (i, peer) in wg_conf.peers.iter().enumerate() { + if &peer.name == peer_name { + del_index = i; + found = true; + pk_path = peer.private_key_path().context("could not get private key path")?; + break; + } + } + + if !found { + return Err(anyhow!("No such peer: {}", peer_name)); + } + + wg_conf.peers.remove(del_index); + + let mut f = File::create(wg_conf_path.clone()).context(format!("error opening configuration file: {}", wg_conf_path))?; + let data = wg_conf.gen_config().context("error generating configuration")?; + + f.write_all(data.as_bytes()).context(format!("error writing to file: {}", wg_conf_path))?; + + std::fs::remove_file(pk_path).context(format!("could not remove file: {}", wg_conf_path))?; + + Ok(()) +} + diff --git a/src/wgcmd.rs b/src/wgcmd.rs new file mode 100644 index 0000000..32a23a6 --- /dev/null +++ b/src/wgcmd.rs @@ -0,0 +1,25 @@ +use crate::wg::config::WireguardConfig; +use std::process::Command; +use anyhow::{anyhow, Result, Context}; + +pub fn run(wg_conf: &WireguardConfig) -> Result<()> { + let wg = Command::new("wg") + .env("WG_COLOR_MODE", "always") + .output() + .context("could not run 'wg', is it installed?")?; + + if !wg.status.success() { + let err = String::from_utf8(wg.stderr)?; + return Err(anyhow!("error running 'wg': {}", err)); + } + + let mut out = String::from_utf8(wg.stdout).context("error parsing stdout")?; + + for peer in wg_conf.peers.iter() { + out = out.replace(peer.public_key.as_str(), peer.name.as_str()); + } + + println!("{}", out); + + Ok(()) +} -- cgit v1.2.3