use anyhow::Result;
use clap::Args;
use crate::config::{load_config, Role};
use crate::ufw::rules::UfwManager;
#[derive(Args)]
pub struct RemovePortArgs {
pub id: String,
#[arg(long)]
pub no_ufw: bool,
}
pub fn execute(args: &RemovePortArgs) -> Result<()> {
let mut config = load_config()?;
let port_to_remove = config.ports().iter().find(|p| p.id == args.id).cloned();
let initial_len = config.ports().len();
config.ports_mut().retain(|p| p.id != args.id);
if config.ports().len() == initial_len {
return Err(anyhow::anyhow!("Port mapping '{}' not found", args.id));
}
config.save()?;
if config.role() == Role::Server && !args.no_ufw {
if let Some(port) = &port_to_remove {
let ufw = UfwManager::new();
if ufw.is_active() {
match ufw.deny_port(port.remote_port, &port.protocol) {
Ok(()) => {
println!("\x1b[1;32m✓ UFW rule removed: {} {}\x1b[0m", port.remote_port, port.protocol);
}
Err(e) => {
println!("\x1b[1;33m⚠ Failed to remove UFW rule: {}\x1b[0m", e);
}
}
}
}
}
println!("\n\x1b[1;32m✓ Port mapping '{}' removed\x1b[0m\n", args.id);
Ok(())
}