client: add uninstall command

pull/48/head
Jake McGinty 2021-04-09 22:37:33 +09:00
parent 5c444cc841
commit a44fe0d3ad
3 changed files with 65 additions and 13 deletions

View File

@ -5,7 +5,7 @@ use shared::{ensure_dirs_exist, Cidr, IoErrorContext, Peer, CLIENT_DATA_PATH};
use std::{ use std::{
fs::{File, OpenOptions}, fs::{File, OpenOptions},
io::{Read, Seek, SeekFrom, Write}, io::{Read, Seek, SeekFrom, Write},
path::Path, path::{Path, PathBuf},
}; };
use wgctrl::InterfaceName; use wgctrl::InterfaceName;
@ -33,7 +33,11 @@ impl DataStore {
.with_path(path)?; .with_path(path)?;
if shared::chmod(&file, 0o600)? { if shared::chmod(&file, 0o600)? {
println!("{} updated permissions for {} to 0600.", "[!]".yellow(), path.display()); println!(
"{} updated permissions for {} to 0600.",
"[!]".yellow(),
path.display()
);
} }
let mut json = String::new(); let mut json = String::new();
@ -46,14 +50,15 @@ impl DataStore {
Ok(Self { file, contents }) Ok(Self { file, contents })
} }
fn _open(interface: &InterfaceName, create: bool) -> Result<Self, Error> { pub fn get_path(interface: &InterfaceName) -> PathBuf {
ensure_dirs_exist(&[*CLIENT_DATA_PATH])?;
Self::open_with_path(
CLIENT_DATA_PATH CLIENT_DATA_PATH
.join(interface.to_string()) .join(interface.to_string())
.with_extension("json"), .with_extension("json")
create, }
)
fn _open(interface: &InterfaceName, create: bool) -> Result<Self, Error> {
ensure_dirs_exist(&[*CLIENT_DATA_PATH])?;
Self::open_with_path(Self::get_path(interface), create)
} }
pub fn open(interface: &InterfaceName) -> Result<Self, Error> { pub fn open(interface: &InterfaceName) -> Result<Self, Error> {

View File

@ -96,6 +96,9 @@ enum Command {
hosts: HostsOpt, hosts: HostsOpt,
}, },
/// Uninstall an innernet network.
Uninstall { interface: Interface },
/// Bring down the interface (equivalent to "wg-quick down [interface]") /// Bring down the interface (equivalent to "wg-quick down [interface]")
Down { interface: Interface }, Down { interface: Interface },
@ -416,6 +419,37 @@ fn fetch(
Ok(()) Ok(())
} }
fn uninstall(interface: &InterfaceName) -> Result<(), Error> {
let theme = ColorfulTheme::default();
if Confirm::with_theme(&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 = InterfaceConfig::get_path(interface);
let data = DataStore::get_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(())
}
fn add_cidr(interface: &InterfaceName) -> Result<(), Error> { fn add_cidr(interface: &InterfaceName) -> Result<(), Error> {
let InterfaceConfig { server, .. } = InterfaceConfig::from_interface(interface)?; let InterfaceConfig { server, .. } = InterfaceConfig::from_interface(interface)?;
println!("Fetching CIDRs"); println!("Fetching CIDRs");
@ -790,6 +824,7 @@ fn run(opt: Opt) -> Result<(), Error> {
hosts.into(), hosts.into(),
)?, )?,
Command::Down { interface } => wg::down(&interface)?, Command::Down { interface } => wg::down(&interface)?,
Command::Uninstall { interface } => uninstall(&interface)?,
Command::AddPeer { interface } => add_peer(&interface)?, Command::AddPeer { interface } => add_peer(&interface)?,
Command::AddCidr { interface } => add_cidr(&interface)?, Command::AddCidr { interface } => add_cidr(&interface)?,
Command::DisablePeer { interface } => enable_or_disable_peer(&interface, false)?, Command::DisablePeer { interface } => enable_or_disable_peer(&interface, false)?,

View File

@ -67,7 +67,11 @@ impl InterfaceConfig {
.with_path(path)?; .with_path(path)?;
if let Some(val) = mode { if let Some(val) = mode {
if crate::chmod(&target_file, 0o600)? { if crate::chmod(&target_file, 0o600)? {
println!("{} updated permissions for {} to 0600.", "[!]".yellow(), path.display()); println!(
"{} updated permissions for {} to 0600.",
"[!]".yellow(),
path.display()
);
} }
let metadata = target_file.metadata()?; let metadata = target_file.metadata()?;
let mut permissions = metadata.permissions(); let mut permissions = metadata.permissions();
@ -114,16 +118,24 @@ impl InterfaceConfig {
let path = Self::build_config_file_path(interface)?; let path = Self::build_config_file_path(interface)?;
let file = File::open(&path).with_path(&path)?; let file = File::open(&path).with_path(&path)?;
if crate::chmod(&file, 0o600)? { if crate::chmod(&file, 0o600)? {
println!("{} updated permissions for {} to 0600.", "[!]".yellow(), path.display()); println!(
"{} updated permissions for {} to 0600.",
"[!]".yellow(),
path.display()
);
} }
Self::from_file(path) Self::from_file(path)
} }
pub fn get_path(interface: &InterfaceName) -> PathBuf {
CLIENT_CONFIG_PATH
.join(interface.to_string())
.with_extension("conf")
}
fn build_config_file_path(interface: &InterfaceName) -> Result<PathBuf, Error> { fn build_config_file_path(interface: &InterfaceName) -> Result<PathBuf, Error> {
ensure_dirs_exist(&[*CLIENT_CONFIG_PATH])?; ensure_dirs_exist(&[*CLIENT_CONFIG_PATH])?;
Ok(CLIENT_CONFIG_PATH Ok(Self::get_path(interface))
.join(interface.to_string())
.with_extension("conf"))
} }
} }