From 470d5f5814406a0ccbfa977374c02957b34b11ff Mon Sep 17 00:00:00 2001 From: lemonsh Date: Sun, 14 May 2023 00:06:55 +0200 Subject: [PATCH] add pfw show command --- connectbox-shell/Cargo.toml | 3 ++- connectbox-shell/src/cli.rs | 10 ++++++- connectbox-shell/src/commands/mod.rs | 1 + connectbox-shell/src/commands/pfw.rs | 39 ++++++++++++++++++++++++++++ connectbox-shell/src/main.rs | 23 +++++++++------- 5 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 connectbox-shell/src/commands/mod.rs create mode 100644 connectbox-shell/src/commands/pfw.rs diff --git a/connectbox-shell/Cargo.toml b/connectbox-shell/Cargo.toml index 3d8f81e..4015d41 100644 --- a/connectbox-shell/Cargo.toml +++ b/connectbox-shell/Cargo.toml @@ -15,4 +15,5 @@ clap = { version = "4.2", default-features = false, features = ["suggestions", " dirs = "5.0" connectbox = { path = "../connectbox" } color-print = "0.3" -anstream = "0.3" \ No newline at end of file +ascii_table = { version = "4.0", features = ["auto_table_width"] } +once_cell = "1.17" diff --git a/connectbox-shell/src/cli.rs b/connectbox-shell/src/cli.rs index c9572c3..6c01418 100644 --- a/connectbox-shell/src/cli.rs +++ b/connectbox-shell/src/cli.rs @@ -19,7 +19,15 @@ pub(crate) struct Args { pub(crate) enum ShellCommand { Exit, #[command(name = "pfw")] - PortForwards, + PortForwards { + #[command(subcommand)] + cmd: PortForwardsCommand + } +} + +#[derive(Parser, Debug)] +pub(crate) enum PortForwardsCommand { + Show } pub(crate) fn shell_cmd() -> Command { diff --git a/connectbox-shell/src/commands/mod.rs b/connectbox-shell/src/commands/mod.rs new file mode 100644 index 0000000..172b7dc --- /dev/null +++ b/connectbox-shell/src/commands/mod.rs @@ -0,0 +1 @@ +pub mod pfw; \ No newline at end of file diff --git a/connectbox-shell/src/commands/pfw.rs b/connectbox-shell/src/commands/pfw.rs new file mode 100644 index 0000000..6ec1de7 --- /dev/null +++ b/connectbox-shell/src/commands/pfw.rs @@ -0,0 +1,39 @@ +use std::{vec, fmt::Display}; + +use ascii_table::{AsciiTable, Align::Right}; +use color_eyre::Result; +use color_print::cprintln; +use once_cell::sync::OnceCell; + +use crate::{cli::PortForwardsCommand, AppState}; + +static PORT_FORWARDING_TABLE: OnceCell = OnceCell::new(); + +fn init_port_forwarding_table() -> AsciiTable { + let mut t = AsciiTable::default(); + t.column(0).set_header("ID").set_align(Right); + t.column(1).set_header("Local IP"); + t.column(2).set_header("Start port"); + t.column(3).set_header("End port"); + t.column(4).set_header("In. start port"); + t.column(5).set_header("In. end port"); + t.column(6).set_header("Protocol"); + t.column(7).set_header("Enabled"); + t +} + +pub(crate) async fn run(cmd: PortForwardsCommand, state: &AppState) -> Result<()> { + match cmd { + PortForwardsCommand::Show => { + cprintln!("Retrieving the port forwarding table..."); + let port_forwards = state.connect_box.port_forwards().await?; + let table_entries = port_forwards.entries.iter().map(|e| { + let v: Vec<&dyn Display> = vec![&e.id, &e.local_ip, &e.start_port, &e.end_port, &e.start_port_in, &e.end_port_in, &e.protocol, &e.enable]; + v + }); + let rendered_table = PORT_FORWARDING_TABLE.get_or_init(init_port_forwarding_table).format(table_entries); + cprintln!("LAN IP: {}\nSubnet mask: {}\n{rendered_table}", port_forwards.lan_ip, port_forwards.subnet_mask); + }, + } + Ok(()) +} \ No newline at end of file diff --git a/connectbox-shell/src/main.rs b/connectbox-shell/src/main.rs index b263cff..b1548dc 100644 --- a/connectbox-shell/src/main.rs +++ b/connectbox-shell/src/main.rs @@ -1,5 +1,4 @@ -use anstream::println; -use color_print::cstr; +use color_print::{cstr, cprintln}; use clap::{FromArgMatches, Parser}; use cli::Args; @@ -11,6 +10,11 @@ use crate::{cli::ShellCommand, utils::QuotableArgs}; mod cli; mod utils; +mod commands; + +pub(crate) struct AppState { + connect_box: ConnectBox +} #[tokio::main(flavor = "current_thread")] async fn main() -> Result<()> { @@ -33,12 +37,13 @@ async fn main() -> Result<()> { .join(".connectbox-shell-history"); let _err = rl.load_history(&history_path); - println!(cstr!("Logging in...")); - let connectbox = ConnectBox::new(args.address, password, true)?; - connectbox.login().await?; + cprintln!("Logging in..."); + let connect_box = ConnectBox::new(args.address, password, true)?; + connect_box.login().await?; + let state = AppState { connect_box }; loop { - match rl.readline(cstr!(" > ")) { + match rl.readline(cstr!("\n > ")) { Ok(line) => { if line.chars().all(char::is_whitespace) { continue; @@ -52,10 +57,10 @@ async fn main() -> Result<()> { }; match cmd { ShellCommand::Exit => break, - ShellCommand::PortForwards => todo!(), + ShellCommand::PortForwards { cmd } => commands::pfw::run(cmd, &state).await?, } } - Err(ReadlineError::Interrupted) | Err(ReadlineError::Eof) => break, + Err(ReadlineError::Interrupted | ReadlineError::Eof) => break, Err(err) => { println!("{err:?}"); break; @@ -63,7 +68,7 @@ async fn main() -> Result<()> { } } println!("Logging out..."); - connectbox.logout().await?; + state.connect_box.logout().await?; rl.save_history(&history_path)?; Ok(())