feat: group purge-stale, peer endpoint history, resolve improvements
- group purge-stale: remove stale peers from group(s), --all, --dry-run
- daemon: update_peer_history() tracks all endpoints per peer
- daemon: endpoint_index.json for O(1) IP -> peer name lookup
- json_helper: peer_history_lookup() with index + scan fallback
- resolve::endpoint_parts: peer history as step 3 in resolution chain
- resolve::service_name: returns service name only, no raw fallback
- resolve::endpoint_parts: removed stale cache, always fresh
- watch: ui:⌚:wg_row/fw_row use shared primitives
- ui: ui::_render_endpoint_col, ui::_build_dest shared primitives
- shell: peer/hosts/identity/subnet/policy/activity in known commands
This commit is contained in:
parent
8b47e55b4a
commit
adab623f3f
1 changed files with 96 additions and 0 deletions
|
|
@ -13,6 +13,8 @@ function cmd::group::on_load() {
|
||||||
flag::register --new-name
|
flag::register --new-name
|
||||||
flag::register --main
|
flag::register --main
|
||||||
flag::register --force
|
flag::register --force
|
||||||
|
flag::register --all
|
||||||
|
flag::register --dry-run
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|
@ -37,6 +39,7 @@ Subcommands:
|
||||||
peer add Add a peer to a group
|
peer add Add a peer to a group
|
||||||
peer remove, peer rm Remove a peer from a group
|
peer remove, peer rm Remove a peer from a group
|
||||||
rm-peers Remove all peers in group from WireGuard
|
rm-peers Remove all peers in group from WireGuard
|
||||||
|
purge-stale Remove peers that no longer exist from group(s)
|
||||||
block Block all peers in group
|
block Block all peers in group
|
||||||
unblock Unblock all peers in group
|
unblock Unblock all peers in group
|
||||||
rule assign Assign a rule to all peers in group
|
rule assign Assign a rule to all peers in group
|
||||||
|
|
@ -53,6 +56,7 @@ Options:
|
||||||
--new-name <name> New group name (for rename)
|
--new-name <name> New group name (for rename)
|
||||||
--limit <n> Max log entries per peer (for logs)
|
--limit <n> Max log entries per peer (for logs)
|
||||||
--force Skip confirmation prompts
|
--force Skip confirmation prompts
|
||||||
|
--all Apply to all groups (for purge-stale)
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
wgctl group list
|
wgctl group list
|
||||||
|
|
@ -62,6 +66,9 @@ Examples:
|
||||||
wgctl group block --name family
|
wgctl group block --name family
|
||||||
wgctl group unblock --name family
|
wgctl group unblock --name family
|
||||||
wgctl group rule assign --name family --rule user
|
wgctl group rule assign --name family --rule user
|
||||||
|
wgctl group purge-stale --name family
|
||||||
|
wgctl group purge-stale --all
|
||||||
|
wgctl group purge-stale --all --force
|
||||||
wgctl group audit --name family
|
wgctl group audit --name family
|
||||||
wgctl group logs --name family --limit 20
|
wgctl group logs --name family --limit 20
|
||||||
wgctl group watch --name family
|
wgctl group watch --name family
|
||||||
|
|
@ -88,6 +95,7 @@ function cmd::group::run() {
|
||||||
block) cmd::group::block "$@" ;;
|
block) cmd::group::block "$@" ;;
|
||||||
unblock) cmd::group::unblock "$@" ;;
|
unblock) cmd::group::unblock "$@" ;;
|
||||||
rule) cmd::group::rule "$@" ;;
|
rule) cmd::group::rule "$@" ;;
|
||||||
|
purge-stale) cmd::group::purge_stale "$@" ;;
|
||||||
audit) cmd::group::audit "$@" ;;
|
audit) cmd::group::audit "$@" ;;
|
||||||
logs) cmd::group::logs "$@" ;;
|
logs) cmd::group::logs "$@" ;;
|
||||||
watch) cmd::group::watch "$@" ;;
|
watch) cmd::group::watch "$@" ;;
|
||||||
|
|
@ -813,3 +821,91 @@ function cmd::group::watch() {
|
||||||
load_command watch
|
load_command watch
|
||||||
cmd::watch::run --peers "$peer_filter"
|
cmd::watch::run --peers "$peer_filter"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Purge Stale
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
function cmd::group::purge_stale() {
|
||||||
|
local name="" force=false all=false
|
||||||
|
local dry_run=false
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--name) util::require_flag "--name" "${2:-}" || return 1; name="$2"; shift 2 ;;
|
||||||
|
--force) force=true; shift ;;
|
||||||
|
--all) all=true; shift ;;
|
||||||
|
--dry-run) dry_run=true; shift ;;
|
||||||
|
--help) cmd::group::help; return ;;
|
||||||
|
*) log::error "Unknown flag: $1"; return 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ -z "$name" && "$all" == "false" ]] && \
|
||||||
|
log::error "Specify --name <group> or --all" && return 1
|
||||||
|
|
||||||
|
# Build list of groups to process
|
||||||
|
local -a groups=()
|
||||||
|
if $all; then
|
||||||
|
while IFS= read -r group_file; do
|
||||||
|
groups+=("$(basename "$group_file" .group)")
|
||||||
|
done < <(find "$(ctx::groups)" -name "*.group" 2>/dev/null | sort)
|
||||||
|
else
|
||||||
|
group::require_exists "$name" || return 1
|
||||||
|
groups=("$name")
|
||||||
|
fi
|
||||||
|
|
||||||
|
local total_removed=0 total_groups=0
|
||||||
|
|
||||||
|
for group_name in "${groups[@]}"; do
|
||||||
|
[[ -z "$group_name" ]] && continue
|
||||||
|
|
||||||
|
# Find stale peers — in group but no .conf file
|
||||||
|
local -a stale=()
|
||||||
|
while IFS= read -r peer_name; do
|
||||||
|
[[ -z "$peer_name" ]] && continue
|
||||||
|
if [[ ! -f "$(ctx::clients)/${peer_name}.conf" ]]; then
|
||||||
|
stale+=("$peer_name")
|
||||||
|
fi
|
||||||
|
done < <(group::peers "$group_name" 2>/dev/null)
|
||||||
|
|
||||||
|
[[ ${#stale[@]} -eq 0 ]] && continue
|
||||||
|
|
||||||
|
(( total_groups++ )) || true
|
||||||
|
|
||||||
|
if ! $force; then
|
||||||
|
printf " Group '%s' has %d stale peer(s): %s\n" \
|
||||||
|
"$group_name" "${#stale[@]}" "${stale[*]}"
|
||||||
|
read -r -p " Remove them? [y/N] " confirm
|
||||||
|
case "$confirm" in
|
||||||
|
[yY]*) ;;
|
||||||
|
*) log::info "Skipped '${group_name}'"; continue ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
local group_file
|
||||||
|
group_file="$(group::path "$group_name")"
|
||||||
|
for peer_name in "${stale[@]}"; do
|
||||||
|
if $dry_run; then
|
||||||
|
printf " \033[2m[dry-run]\033[0m Would remove '%s' from group '%s'\n" \
|
||||||
|
"$peer_name" "$group_name"
|
||||||
|
else
|
||||||
|
json::remove "$group_file" "peers" "$peer_name" 2>/dev/null || true
|
||||||
|
log::debug "Removed stale peer '${peer_name}' from group '${group_name}'"
|
||||||
|
fi
|
||||||
|
(( total_removed++ )) || true
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
local action="Removed"
|
||||||
|
$dry_run && action="Would remove"
|
||||||
|
log::wg_success "${action} ${total_removed} stale peer(s)..."
|
||||||
|
|
||||||
|
if $all; then
|
||||||
|
if [[ "$total_removed" -eq 0 ]]; then
|
||||||
|
log::wg_warning "No stale peers found in any group"
|
||||||
|
else
|
||||||
|
log::wg_success "${action} ${total_removed} stale peer(s)..."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue