From b3a9c69cab4be8ab449e76c115bd15e96517485e Mon Sep 17 00:00:00 2001 From: Nuno Duque Nunes Date: Tue, 12 May 2026 01:21:25 +0000 Subject: [PATCH] refactor: block::run helpers, test --fn mode, param defaults --- commands/block.command.sh | 66 +++++++++++++++++++--------------- commands/test.command.sh | 72 +++++++++++++++++++++++++++++++++++--- daemon/endpoint_cache.json | 2 +- 3 files changed, 106 insertions(+), 34 deletions(-) diff --git a/commands/block.command.sh b/commands/block.command.sh index bee8cae..a89bb5f 100644 --- a/commands/block.command.sh +++ b/commands/block.command.sh @@ -109,12 +109,7 @@ function cmd::block::run() { public_key=$(keys::public "$name") || return 1 local endpoint - endpoint=$(monitor::endpoint_for_key "$public_key") - - # Fall back to cache if live endpoint not available - if [[ -z "$endpoint" || "$endpoint" == "(none)" ]]; then - endpoint=$(monitor::get_cached_endpoint "$name") - fi + endpoint=$(cmd::block::_get_endpoint "$name" "$public_key") local client_ip client_ip=$(cmd::block::get_client_ip "$name") || return 1 @@ -122,28 +117,7 @@ function cmd::block::run() { # $quiet || log::section "Blocking client: ${name} (${client_ip})" # No specific target — block everything - if [[ ${#ips[@]} -eq 0 && ${#subnets[@]} -eq 0 && ${#ports[@]} -eq 0 ]]; then - # Get real endpoint IP before removing peer from server - local public_key endpoint - public_key=$(keys::public "$name") || return 1 - endpoint=$(monitor::endpoint_for_key "$public_key") - - fw::block_all "$client_ip" "$name" - fw::save_block "$name" "$client_ip" - - # Watch real endpoint IP if available - if [[ -n "$endpoint" ]]; then - monitor::unwatch "$client_ip" # remove tunnel IP if added by block_all - monitor::watch "$endpoint" "$name" - fi - - # Remove peer from server to kill active connection - peers::remove_from_server "$name" - peers::reload - - $quiet || log::wg_success "${name} has been blocked." - return 0 - fi + cmd::block::_block_all "$name" "$client_ip" "$quiet" # Block specific IPs for ip in "${ips[@]}"; do @@ -171,3 +145,39 @@ function cmd::block::run() { log::debug "Block rules applied for: ${name}" } + +function cmd::block::_get_endpoint() { + local name="$1" public_key="$2" + local endpoint + endpoint=$(monitor::endpoint_for_key "$public_key") + if [[ -z "$endpoint" || "$endpoint" == "(none)" ]]; then + endpoint=$(monitor::get_cached_endpoint "$name") + fi + echo "$endpoint" +} + +function cmd::block::_block_all() { + local name="${1:-}" + local client_ip="${2:-}" + local quiet="${3:-false}" + + [[ -z "$name" ]] && log::error "name required" && return 1 + [[ -z "$client_ip" ]] && log::error "client_ip required" && return 1 + + local public_key endpoint + public_key=$(keys::public "$name") || return 1 + endpoint=$(cmd::block::_get_endpoint "$name" "$public_key") + + fw::block_all "$client_ip" "$name" + fw::save_block "$name" "$client_ip" + + if [[ -n "$endpoint" ]]; then + monitor::unwatch "$client_ip" + monitor::watch "$endpoint" "$name" + fi + + peers::remove_from_server "$name" + peers::reload + + $quiet || log::wg_success "${name} has been blocked." +} \ No newline at end of file diff --git a/commands/test.command.sh b/commands/test.command.sh index 7ef35a5..a9c2a85 100644 --- a/commands/test.command.sh +++ b/commands/test.command.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +WGCTL_BINARY="/usr/local/bin/wgctl" + # ============================================ # Lifecycle # ============================================ @@ -7,6 +9,8 @@ function cmd::test::on_load() { flag::register --destructive flag::register --section + flag::register --fn + flag::register --function } function cmd::test::help() { @@ -40,7 +44,7 @@ function cmd::test::run_cmd() { set +e # disable exit on error (return 1) - timeout 30 /usr/local/bin/wgctl "$@" > "$tmp" 2>&1 & + timeout 30 "$WGCTL_BINARY" "$@" > "$tmp" 2>&1 & local pid=$! wait $pid exit_code=$? @@ -80,7 +84,7 @@ function cmd::test::run_cmd_fails() { local tmp exit_code tmp=$(mktemp) - timeout 10 setsid /usr/local/bin/wgctl "$@" > "$tmp" 2>&1 + timeout 10 setsid "$WGCTL_BINARY" "$@" > "$tmp" 2>&1 exit_code=$? set -e # re-enable exit on error @@ -100,6 +104,30 @@ function cmd::test::run_cmd_fails() { test::pass "$desc" } +function cmd::test::run_function() { + local fn="$1" + + local namespace + namespace=$(echo "$fn" | cut -d':' -f3) + load_command "$namespace" 2>/dev/null || true + + test::reset + log::section "Function Test: ${fn}" + + case "$fn" in + cmd::block::run) cmd::test::fn_block ;; + cmd::unblock::run) cmd::test::fn_unblock ;; + cmd::remove::run) cmd::test::fn_remove ;; + cmd::rule::assign) cmd::test::fn_rule_assign ;; + *) + log::error "No function test defined for: ${fn}" + return 1 + ;; + esac + + test::summary +} + # ============================================ # Test sections # ============================================ @@ -180,8 +208,8 @@ function cmd::test::section_destructive() { test::section "Destructive (modifying state)" # Cleanup from any previous failed run - /usr/local/bin/wgctl remove --name phone-testunit --force > /dev/null 2>&1 || true - /usr/local/bin/wgctl group remove --name testgroup --force > /dev/null 2>&1 || true + "$WGCTL_BINARY" remove --name phone-testunit --force > /dev/null 2>&1 || true + "$WGCTL_BINARY" group remove --name testgroup --force > /dev/null 2>&1 || true # Add test peer cmd::test::run_cmd "add phone peer" "added successfully" \ @@ -218,19 +246,47 @@ function cmd::test::section_destructive() { remove --name phone-testunit --force } +# ============================================ +# Function Blocks +# ============================================ + +function cmd::test::fn_block() { + test::section "cmd::block::run" + + # Setup + "$WGCTL_BINARY" remove --name phone-testunit --force > /dev/null 2>&1 || true + "$WGCTL_BINARY" add --name testunit --type phone > /dev/null 2>&1 + + # Tests + cmd::test::run_cmd "block peer" "blocked" block --name phone-testunit + cmd::test::run_cmd "block already blocked" "already" block --name phone-testunit + + "$WGCTL_BINARY" unblock --name phone-testunit > /dev/null 2>&1 || true + cmd::test::run_cmd "block with --type" "blocked" block --name testunit --type phone + + cmd::test::run_cmd_fails "block nonexistent" block --name truly-nonexistent-xyz + + # Cleanup + "$WGCTL_BINARY" unblock --name phone-testunit > /dev/null 2>&1 || true + "$WGCTL_BINARY" remove --name phone-testunit --force > /dev/null 2>&1 || true +} + # ============================================ # Run # ============================================ function cmd::test::run() { local destructive=false section="" + local fn="" while [[ $# -gt 0 ]]; do case "$1" in --destructive) destructive=true; shift ;; --section) util::require_flag "--section" "${2:-}" || return 1 - section="$2"; shift 2 ;; + section="$2"; shift 2 + ;; + --fn|--function) fn="$2"; shift 2 ;; --verbose|-v) WGCTL_TEST_VERBOSE=true; shift ;; --help) cmd::test::help; return ;; *) @@ -240,6 +296,12 @@ function cmd::test::run() { esac done + # After flag parsing: + if [[ -n "$fn" ]]; then + cmd::test::run_function "$fn" + return + fi + test::reset log::section "wgctl Test Suite" diff --git a/daemon/endpoint_cache.json b/daemon/endpoint_cache.json index 5eeeb91..932add1 100644 --- a/daemon/endpoint_cache.json +++ b/daemon/endpoint_cache.json @@ -1,6 +1,6 @@ { "phone-fred": "94.63.0.129", - "phone-helena": "148.69.38.9", + "phone-helena": "148.69.39.194", "phone-nuno": "94.63.0.129", "tablet-nuno": "148.69.202.5", "guest-zephyr": "5.13.82.5",