server: add uninstall command

pull/48/head
Jake McGinty 2021-04-09 22:42:29 +09:00
parent a44fe0d3ad
commit c370c25924
3 changed files with 42 additions and 4 deletions

View File

@ -420,8 +420,7 @@ fn fetch(
}
fn uninstall(interface: &InterfaceName) -> Result<(), Error> {
let theme = ColorfulTheme::default();
if Confirm::with_theme(&theme)
if Confirm::with_theme(&*prompts::THEME)
.with_prompt(&format!(
"Permanently delete network \"{}\"?",
interface.as_str_lossy().yellow()

View File

@ -1,4 +1,5 @@
use colored::*;
use dialoguer::Confirm;
use error::handle_rejection;
use hyper::{server::conn::AddrStream, Body, Request};
use indoc::printdoc;
@ -52,6 +53,9 @@ enum Command {
#[structopt(alias = "init")]
New,
/// Permanently uninstall a created network, rendering it unusable. Use with care.
Uninstall { interface: Interface },
/// Serve the coordinating server for an existing network.
Serve { interface: Interface },
@ -125,7 +129,11 @@ impl ConfigFile {
let path = path.as_ref();
let file = File::open(path).with_path(path)?;
if shared::chmod(&file, 0o600)? {
println!("{} updated permissions for {} to 0600.", "[!]".yellow(), path.display());
println!(
"{} updated permissions for {} to 0600.",
"[!]".yellow(),
path.display()
);
}
Ok(toml::from_slice(&std::fs::read(&path).with_path(path)?)?)
}
@ -191,6 +199,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("{}: {}.", "creation failed".red(), e);
}
},
Command::Uninstall { interface } => uninstall(&interface, &conf)?,
Command::Serve { interface } => serve(&interface, &conf).await?,
Command::AddPeer { interface } => add_peer(&interface, &conf)?,
Command::AddCidr { interface } => add_cidr(&interface, &conf)?,
@ -337,6 +346,36 @@ async fn serve(interface: &InterfaceName, conf: &ServerConfig) -> Result<(), Err
Ok(())
}
fn uninstall(interface: &InterfaceName, conf: &ServerConfig) -> Result<(), Error> {
if Confirm::with_theme(&*prompts::THEME)
.with_prompt(&format!(
"Permanently delete network \"{}\"?",
interface.as_str_lossy().yellow()
))
.default(false)
.interact()?
{
println!("{} bringing down interface (if up).", "[*]".dimmed());
wg::down(interface).ok();
let config = conf.config_path(interface);
let data = conf.database_path(interface);
std::fs::remove_file(&config)
.with_path(&config)
.map_err(|e| println!("[!] {}", e.to_string().yellow()))
.ok();
std::fs::remove_file(&data)
.with_path(&data)
.map_err(|e| println!("[!] {}", e.to_string().yellow()))
.ok();
println!(
"{} network {} is uninstalled.",
"[*]".dimmed(),
interface.as_str_lossy().yellow()
);
}
Ok(())
}
/// This function differs per OS, because different operating systems have
/// opposing characteristics when binding to a specific IP address.
/// On Linux, binding to a specific local IP address does *not* bind it to

View File

@ -12,7 +12,7 @@ use std::net::{IpAddr, SocketAddr};
use wgctrl::{InterfaceName, KeyPair};
lazy_static! {
static ref THEME: ColorfulTheme = ColorfulTheme::default();
pub static ref THEME: ColorfulTheme = ColorfulTheme::default();
/// Regex to match the requirements of hostname(7), needed to have peers also be reachable hostnames.
/// Note that the full length also must be maximum 63 characters, which this regex does not check.