Compare commits
3 commits
d26e67b940
...
10ea174e44
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10ea174e44 | ||
|
|
9c11152682 | ||
|
|
b153f222a5 |
10 changed files with 283 additions and 29 deletions
|
|
@ -6,6 +6,8 @@
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|
||||||
function cmd::activity::on_load() {
|
function cmd::activity::on_load() {
|
||||||
|
command::mixin json_output
|
||||||
|
|
||||||
load_module net
|
load_module net
|
||||||
|
|
||||||
flag::register --peer
|
flag::register --peer
|
||||||
|
|
@ -17,7 +19,7 @@ function cmd::activity::on_load() {
|
||||||
flag::register --drop
|
flag::register --drop
|
||||||
flag::register --external
|
flag::register --external
|
||||||
|
|
||||||
command::mixin json_output
|
flag::exclusive --accept --drop
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|
@ -201,15 +203,38 @@ function cmd::activity::run() {
|
||||||
local pp="${rest_key#*:}"
|
local pp="${rest_key#*:}"
|
||||||
local d_port="${pp%%:*}"
|
local d_port="${pp%%:*}"
|
||||||
local d_proto="${pp##*:}"
|
local d_proto="${pp##*:}"
|
||||||
local dest_display
|
local spec="${d_ip}:${d_port}:${d_proto}"
|
||||||
dest_display=$(resolve::dest "$d_ip" "$d_port" "$d_proto" 2>/dev/null \
|
local dest_display="${_DEST_RESOLVE_CACHE[$spec]:-${d_ip}:${d_port}/${d_proto}}"
|
||||||
|| echo "${d_ip}:${d_port}/${d_proto}")
|
|
||||||
ui::activity::accept_dest_row \
|
ui::activity::accept_dest_row \
|
||||||
"$dest_display" "$d_bytes_orig" "$d_bytes_reply" \
|
"$dest_display" "$d_bytes_orig" "$d_bytes_reply" \
|
||||||
"$d_count" "$drops_col" "$w_count"
|
"$d_count" "$drops_col" "$w_count"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare -gA _DEST_RESOLVE_CACHE=()
|
||||||
|
local -a _dest_specs=()
|
||||||
|
for _dk in "${!_ACCEPT_DEST[@]}"; do
|
||||||
|
# key format: peer:ip:port:proto — strip peer prefix
|
||||||
|
local _rest="${_dk#*:}"
|
||||||
|
local _dip="${_rest%%:*}"
|
||||||
|
local _pp="${_rest#*:}"
|
||||||
|
local _dport="${_pp%%:*}"
|
||||||
|
local _dproto="${_pp##*:}"
|
||||||
|
local _spec="${_dip}:${_dport}:${_dproto}"
|
||||||
|
# Deduplicate
|
||||||
|
local _found=false
|
||||||
|
for _s in "${_dest_specs[@]:-}"; do
|
||||||
|
[[ "$_s" == "$_spec" ]] && _found=true && break
|
||||||
|
done
|
||||||
|
$_found || _dest_specs+=("$_spec")
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ${#_dest_specs[@]} -gt 0 ]]; then
|
||||||
|
while IFS='|' read -r _spec _display; do
|
||||||
|
[[ -n "$_spec" ]] && _DEST_RESOLVE_CACHE["$_spec"]="$_display"
|
||||||
|
done < <(json::batch_resolve_dest "${_dest_specs[@]}" 2>/dev/null)
|
||||||
|
fi
|
||||||
|
|
||||||
local first_peer=true skip_peer=false current_name=""
|
local first_peer=true skip_peer=false current_name=""
|
||||||
local -a rendered_peers=()
|
local -a rendered_peers=()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|
||||||
function cmd::list::on_load() {
|
function cmd::list::on_load() {
|
||||||
|
command::mixin json_output
|
||||||
|
|
||||||
load_module identity
|
load_module identity
|
||||||
load_module ui
|
load_module ui
|
||||||
|
|
||||||
|
|
@ -19,7 +21,9 @@ function cmd::list::on_load() {
|
||||||
flag::register --allowed
|
flag::register --allowed
|
||||||
flag::register --detailed
|
flag::register --detailed
|
||||||
flag::register --name
|
flag::register --name
|
||||||
command::mixin json_output
|
|
||||||
|
# Mutually exclusive filter groups
|
||||||
|
flag::exclusive --online --offline --blocked --restricted --allowed
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ function cmd::logs::on_load() {
|
||||||
flag::register --ascending
|
flag::register --ascending
|
||||||
flag::register --descending
|
flag::register --descending
|
||||||
flag::register --resolved
|
flag::register --resolved
|
||||||
|
|
||||||
|
flag::exclusive --ascending --descending
|
||||||
}
|
}
|
||||||
|
|
||||||
function cmd::logs::help() {
|
function cmd::logs::help() {
|
||||||
|
|
@ -161,6 +163,11 @@ function cmd::logs::show() {
|
||||||
[[ -z "$filter_ip" ]] && log::error "Could not find IP for: $name" && return 1
|
[[ -z "$filter_ip" ]] && log::error "Could not find IP for: $name" && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if $fw_only && $wg_only; then
|
||||||
|
fw_only=false
|
||||||
|
wg_only=false
|
||||||
|
fi
|
||||||
|
|
||||||
if $follow; then
|
if $follow; then
|
||||||
cmd::logs::follow "$filter_ip" "$name" "$type" "$fw_only" "$wg_only"
|
cmd::logs::follow "$filter_ip" "$name" "$type" "$fw_only" "$wg_only"
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ declare -A _LOADED_COMMANDS=()
|
||||||
|
|
||||||
readonly _COMMAND_NAMESPACE="cmd"
|
readonly _COMMAND_NAMESPACE="cmd"
|
||||||
readonly _COMMAND_AUTO_LOAD_HOOK="on_load"
|
readonly _COMMAND_AUTO_LOAD_HOOK="on_load"
|
||||||
|
_CURRENT_LOADING_CMD=""
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# Helpers
|
# Helpers
|
||||||
|
|
@ -36,15 +37,59 @@ function command::exists() { command::has_function "$1" run; }
|
||||||
# Runner
|
# Runner
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|
||||||
|
# function command::run() {
|
||||||
|
# local cmd="$1"
|
||||||
|
# shift
|
||||||
|
|
||||||
|
# command::_reset_mixin_state # reset values only, keep _ACTIVE_MIXINS
|
||||||
|
|
||||||
|
# local -a args=("$@")
|
||||||
|
# command::_preprocess_flags args
|
||||||
|
|
||||||
|
# local fn
|
||||||
|
# fn=$(command::fn "$cmd" run)
|
||||||
|
# core::call_function "$fn" ${args[@]+"${args[@]}"}
|
||||||
|
# }
|
||||||
|
|
||||||
function command::run() {
|
function command::run() {
|
||||||
local cmd="$1"
|
local cmd="$1"
|
||||||
shift
|
shift
|
||||||
|
|
||||||
command::_reset_mixin_state # reset values only, keep _ACTIVE_MIXINS
|
command::_reset_mixin_state
|
||||||
|
|
||||||
local -a args=("$@")
|
# Build default args from config
|
||||||
|
local -a default_args=()
|
||||||
|
local defaults="${_COMMAND_DEFAULTS[$cmd]:-}"
|
||||||
|
if [[ -n "$defaults" ]]; then
|
||||||
|
read -ra default_args <<< "$defaults"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local -a user_args=("$@")
|
||||||
|
[[ $# -gt 0 ]] && user_args=("$@")
|
||||||
|
|
||||||
|
# Resolve exclusive group conflicts — user args override defaults
|
||||||
|
local groups="${_FLAG_EXCLUSIVE_GROUPS[$cmd]:-}"
|
||||||
|
if [[ -n "$groups" && ${#default_args[@]} -gt 0 && ${#user_args[@]} -gt 0 ]]; then
|
||||||
|
command::_resolve_conflicts default_args user_args "$groups"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local -a cleaned_defaults=()
|
||||||
|
for _d in "${default_args[@]:-}"; do
|
||||||
|
[[ -n "$_d" ]] && cleaned_defaults+=("$_d")
|
||||||
|
done
|
||||||
|
default_args=("${cleaned_defaults[@]:-}")
|
||||||
|
|
||||||
|
local -a args=()
|
||||||
|
for _d in "${default_args[@]:-}"; do
|
||||||
|
[[ -n "$_d" ]] && args+=("$_d")
|
||||||
|
done
|
||||||
|
for _u in "${user_args[@]:-}"; do
|
||||||
|
[[ -n "$_u" ]] && args+=("$_u")
|
||||||
|
done
|
||||||
|
|
||||||
|
# Preprocess mixin flags (--json, --no-color etc)
|
||||||
command::_preprocess_flags args
|
command::_preprocess_flags args
|
||||||
|
echo "DEBUG cmd=$cmd groups='$groups' defs='${default_args[*]}' user='${user_args[*]:-}'" >&2
|
||||||
local fn
|
local fn
|
||||||
fn=$(command::fn "$cmd" run)
|
fn=$(command::fn "$cmd" run)
|
||||||
core::call_function "$fn" ${args[@]+"${args[@]}"}
|
core::call_function "$fn" ${args[@]+"${args[@]}"}
|
||||||
|
|
@ -77,7 +122,9 @@ function load_command() {
|
||||||
source "$path"
|
source "$path"
|
||||||
_LOADED_COMMANDS["$name"]=1
|
_LOADED_COMMANDS["$name"]=1
|
||||||
|
|
||||||
|
_CURRENT_LOADING_CMD="$name"
|
||||||
core::call_if_exists "$(command::fn "$name" on_load)"
|
core::call_if_exists "$(command::fn "$name" on_load)"
|
||||||
|
_CURRENT_LOADING_CMD=""
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# core/command_mixins.sh
|
# core/command_mixins.sh
|
||||||
# Mixin infrastructure — loads mixin files and provides command::mixin
|
# Mixin infrastructure — loads mixin files and provides command::mixin / flag::exclusive
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# Active mixin tracking (per-process)
|
# Active mixin tracking (per-process)
|
||||||
|
|
@ -109,3 +109,87 @@ function command::_preprocess_flags() {
|
||||||
_args_ref=()
|
_args_ref=()
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# command::_resolve_conflicts <defaults_nameref> <user_nameref> <groups_string>
|
||||||
|
# Removes conflicting defaults when user provides a member of an exclusive group
|
||||||
|
function command::_resolve_conflicts() {
|
||||||
|
local -n _def_ref="$1"
|
||||||
|
local -n _usr_ref="$2"
|
||||||
|
local groups="$3"
|
||||||
|
|
||||||
|
[[ -z "$groups" ]] && return 0
|
||||||
|
[[ ${#_def_ref[@]} -eq 0 ]] && return 0
|
||||||
|
|
||||||
|
# Work on a copy — progressively filter across all groups
|
||||||
|
local -a working=("${_def_ref[@]}")
|
||||||
|
|
||||||
|
local group
|
||||||
|
while IFS= read -r group; do
|
||||||
|
[[ -z "$group" ]] && continue
|
||||||
|
|
||||||
|
local -a members=()
|
||||||
|
IFS=',' read -ra members <<< "$group"
|
||||||
|
|
||||||
|
# Find which member (if any) the user passed from this group
|
||||||
|
local user_member=""
|
||||||
|
local member user_arg
|
||||||
|
for member in "${members[@]}"; do
|
||||||
|
for user_arg in "${_usr_ref[@]:-}"; do
|
||||||
|
if [[ "$user_arg" == "$member" ]]; then
|
||||||
|
user_member="$member"
|
||||||
|
break 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
# No user member in this group — don't touch defaults
|
||||||
|
[[ -z "$user_member" ]] && continue
|
||||||
|
|
||||||
|
# User passed a member — remove all OTHER members from defaults
|
||||||
|
# (keep the same flag if it was already in defaults)
|
||||||
|
local -a new_working=()
|
||||||
|
local def_arg
|
||||||
|
for def_arg in "${working[@]:-}"; do
|
||||||
|
local is_other_member=false
|
||||||
|
for member in "${members[@]}"; do
|
||||||
|
# It's another member if it's in the group AND not the same as user's choice
|
||||||
|
if [[ "$def_arg" == "$member" && "$def_arg" != "$user_member" ]]; then
|
||||||
|
is_other_member=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
$is_other_member || new_working+=("$def_arg")
|
||||||
|
done
|
||||||
|
working=("${new_working[@]:-}")
|
||||||
|
done < <(echo "$groups" | tr '|' '\n')
|
||||||
|
|
||||||
|
# Write back
|
||||||
|
if [[ ${#working[@]} -gt 0 ]]; then
|
||||||
|
_def_ref=("${working[@]}")
|
||||||
|
else
|
||||||
|
_def_ref=()
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Flag Exclusive
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
declare -gA _FLAG_EXCLUSIVE_GROUPS=()
|
||||||
|
|
||||||
|
# flag::exclusive <flag1> <flag2> ...
|
||||||
|
# Called from on_load — registers mutually exclusive flags for current command
|
||||||
|
function flag::exclusive() {
|
||||||
|
local cmd="${_CURRENT_LOADING_CMD:-}"
|
||||||
|
[[ -z "$cmd" ]] && return 0
|
||||||
|
|
||||||
|
# Join flags with comma as one group
|
||||||
|
local group
|
||||||
|
group=$(IFS=','; echo "$*")
|
||||||
|
|
||||||
|
if [[ -n "${_FLAG_EXCLUSIVE_GROUPS[$cmd]:-}" ]]; then
|
||||||
|
_FLAG_EXCLUSIVE_GROUPS["$cmd"]+="${group}|"
|
||||||
|
else
|
||||||
|
_FLAG_EXCLUSIVE_GROUPS["$cmd"]="${group}|"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
@ -157,6 +157,7 @@ function json::endpoint_cache_get() { python3 "$JSON_HELPER" endpoint_cach
|
||||||
# Accept Events
|
# Accept Events
|
||||||
function json::accept_events() { python3 "$JSON_HELPER" accept_events "$@" </dev/null; }
|
function json::accept_events() { python3 "$JSON_HELPER" accept_events "$@" </dev/null; }
|
||||||
function json::accept_aggregate() { python3 "$JSON_HELPER" accept_aggregate "$@" </dev/null; }
|
function json::accept_aggregate() { python3 "$JSON_HELPER" accept_aggregate "$@" </dev/null; }
|
||||||
|
function json::batch_resolve_dest() { python3 "$JSON_HELPER" batch_resolve_dest "$(ctx::net)" "$(ctx::hosts)" "$@" </dev/null; }
|
||||||
|
|
||||||
function json::peer_transfer() {
|
function json::peer_transfer() {
|
||||||
ACTIVITY_TOTAL_LOW="$(config::activity_total_low)" \
|
ACTIVITY_TOTAL_LOW="$(config::activity_total_low)" \
|
||||||
|
|
|
||||||
|
|
@ -1607,6 +1607,23 @@ def config_load(file):
|
||||||
emit('ACTIVITY_CURRENT_LOW_BYTES', acur.get('low'))
|
emit('ACTIVITY_CURRENT_LOW_BYTES', acur.get('low'))
|
||||||
emit('ACTIVITY_CURRENT_MED_BYTES', acur.get('medium'))
|
emit('ACTIVITY_CURRENT_MED_BYTES', acur.get('medium'))
|
||||||
emit('ACTIVITY_CURRENT_HIGH_BYTES', acur.get('high'))
|
emit('ACTIVITY_CURRENT_HIGH_BYTES', acur.get('high'))
|
||||||
|
|
||||||
|
# Command defaults and aliases
|
||||||
|
# Output format:
|
||||||
|
# CMD_DEFAULT:activity=--exclude-service pihole:dns-udp --limit 50
|
||||||
|
# CMD_ALIAS:act=activity
|
||||||
|
# CMD_ALIAS:a=activity
|
||||||
|
cmds = d.get('commands', {})
|
||||||
|
for cmd_name, cmd_cfg in cmds.items():
|
||||||
|
if not isinstance(cmd_cfg, dict):
|
||||||
|
continue
|
||||||
|
defaults = cmd_cfg.get('defaults', [])
|
||||||
|
if defaults:
|
||||||
|
print(f"CMD_DEFAULT:{cmd_name}={' '.join(str(x) for x in defaults)}")
|
||||||
|
aliases = cmd_cfg.get('aliases', [])
|
||||||
|
for alias in aliases:
|
||||||
|
print(f"CMD_ALIAS:{alias}={cmd_name}")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error: {e}", file=sys.stderr)
|
print(f"Error: {e}", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
@ -1821,6 +1838,60 @@ def endpoint_cache_get(cache_file, peer):
|
||||||
except Exception:
|
except Exception:
|
||||||
print('')
|
print('')
|
||||||
|
|
||||||
|
def batch_resolve_dest(net_file, hosts_file, *dest_specs):
|
||||||
|
"""
|
||||||
|
Resolve multiple ip:port:proto specs at once.
|
||||||
|
Input: "ip:port:proto" strings
|
||||||
|
Output: "ip:port:proto|display_name" per line
|
||||||
|
Uses same logic as resolve::dest bash function.
|
||||||
|
"""
|
||||||
|
from lib.util import load_net_data, load_hosts_data, reverse_lookup, hosts_lookup
|
||||||
|
net_data = load_net_data(net_file)
|
||||||
|
hosts_data = load_hosts_data(hosts_file)
|
||||||
|
seen = set()
|
||||||
|
|
||||||
|
for spec in dest_specs:
|
||||||
|
if not spec or spec in seen:
|
||||||
|
continue
|
||||||
|
seen.add(spec)
|
||||||
|
|
||||||
|
parts = spec.split(':')
|
||||||
|
if len(parts) < 3:
|
||||||
|
print(f"{spec}|{spec}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
ip = parts[0]
|
||||||
|
port = parts[1]
|
||||||
|
proto = parts[2]
|
||||||
|
|
||||||
|
# Try service name first
|
||||||
|
svc = reverse_lookup(net_data, ip, port, proto)
|
||||||
|
if svc and svc != ip:
|
||||||
|
if port:
|
||||||
|
display = f"{svc}:{proto}-{port}" if False else f"{svc}"
|
||||||
|
# Use same format as resolve::dest: "svcname/proto" or "svcname:port"
|
||||||
|
display = svc
|
||||||
|
else:
|
||||||
|
display = svc
|
||||||
|
print(f"{spec}|{display}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Try host name
|
||||||
|
host = hosts_lookup(hosts_data, ip)
|
||||||
|
if host and host != ip:
|
||||||
|
if port:
|
||||||
|
print(f"{spec}|{host}:{port}/{proto}")
|
||||||
|
else:
|
||||||
|
print(f"{spec}|{host}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Raw fallback
|
||||||
|
if port:
|
||||||
|
print(f"{spec}|{ip}:{port}/{proto}")
|
||||||
|
else:
|
||||||
|
print(f"{spec}|{ip}")
|
||||||
|
|
||||||
|
|
||||||
# ======================================================
|
# ======================================================
|
||||||
|
|
||||||
def _net_read(file):
|
def _net_read(file):
|
||||||
|
|
@ -2238,6 +2309,7 @@ commands = {
|
||||||
args[3] if len(args) > 3 else '',
|
args[3] if len(args) > 3 else '',
|
||||||
args[4] if len(args) > 4 else '',
|
args[4] if len(args) > 4 else '',
|
||||||
args[5] if len(args) > 5 else '0'),
|
args[5] if len(args) > 5 else '0'),
|
||||||
|
'batch_resolve_dest': lambda args: batch_resolve_dest(args[0], args[1], *args[2:]),
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── Main ─────────────────────────────────────────────────────────────────────
|
# ── Main ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -22,6 +22,9 @@ declare -g _ACTIVITY_CURRENT_LOW_BYTES="${ACTIVITY_CURRENT_LOW_BYTES:-1000000}"
|
||||||
declare -g _ACTIVITY_CURRENT_MED_BYTES="${ACTIVITY_CURRENT_MED_BYTES:-10000000}"
|
declare -g _ACTIVITY_CURRENT_MED_BYTES="${ACTIVITY_CURRENT_MED_BYTES:-10000000}"
|
||||||
declare -g _ACTIVITY_CURRENT_HIGH_BYTES="${ACTIVITY_CURRENT_HIGH_BYTES:-100000000}"
|
declare -g _ACTIVITY_CURRENT_HIGH_BYTES="${ACTIVITY_CURRENT_HIGH_BYTES:-100000000}"
|
||||||
|
|
||||||
|
declare -gA _COMMAND_DEFAULTS=()
|
||||||
|
declare -gA _COMMAND_ALIASES=()
|
||||||
|
|
||||||
function config::_init_defaults() {
|
function config::_init_defaults() {
|
||||||
_WG_INTERFACE="wg0"
|
_WG_INTERFACE="wg0"
|
||||||
_WG_DNS="10.0.0.103"
|
_WG_DNS="10.0.0.103"
|
||||||
|
|
@ -89,6 +92,14 @@ function config::_load_json() {
|
||||||
ACTIVITY_CURRENT_LOW_BYTES) _ACTIVITY_CURRENT_LOW_BYTES="$value" ;;
|
ACTIVITY_CURRENT_LOW_BYTES) _ACTIVITY_CURRENT_LOW_BYTES="$value" ;;
|
||||||
ACTIVITY_CURRENT_MED_BYTES) _ACTIVITY_CURRENT_MED_BYTES="$value" ;;
|
ACTIVITY_CURRENT_MED_BYTES) _ACTIVITY_CURRENT_MED_BYTES="$value" ;;
|
||||||
ACTIVITY_CURRENT_HIGH_BYTES) _ACTIVITY_CURRENT_HIGH_BYTES="$value" ;;
|
ACTIVITY_CURRENT_HIGH_BYTES) _ACTIVITY_CURRENT_HIGH_BYTES="$value" ;;
|
||||||
|
CMD_DEFAULT:*)
|
||||||
|
local cmd_name="${key#CMD_DEFAULT:}"
|
||||||
|
_COMMAND_DEFAULTS["$cmd_name"]="$value"
|
||||||
|
;;
|
||||||
|
CMD_ALIAS:*)
|
||||||
|
local alias_name="${key#CMD_ALIAS:}"
|
||||||
|
_COMMAND_ALIASES["$alias_name"]="$value"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done < <(json::config_load "$file" 2>/dev/null)
|
done < <(json::config_load "$file" 2>/dev/null)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
7
wgctl
7
wgctl
|
|
@ -43,7 +43,6 @@ declare -A CMD_ALIASES=(
|
||||||
[del]=remove
|
[del]=remove
|
||||||
[delete]=remove
|
[delete]=remove
|
||||||
[mv]=rename
|
[mv]=rename
|
||||||
[ls]=list
|
|
||||||
[show]=list
|
[show]=list
|
||||||
[monitor]=watch
|
[monitor]=watch
|
||||||
[ban]=block
|
[ban]=block
|
||||||
|
|
@ -53,7 +52,6 @@ declare -A CMD_ALIASES=(
|
||||||
[down]=service
|
[down]=service
|
||||||
[reload]=service
|
[reload]=service
|
||||||
[stat]=service
|
[stat]=service
|
||||||
[log]=service
|
|
||||||
[start]=service
|
[start]=service
|
||||||
[stop]=service
|
[stop]=service
|
||||||
[restart]=service
|
[restart]=service
|
||||||
|
|
@ -78,6 +76,11 @@ function wgctl::dispatch() {
|
||||||
local cmd
|
local cmd
|
||||||
cmd="$(wgctl::resolve_alias "$raw_cmd")"
|
cmd="$(wgctl::resolve_alias "$raw_cmd")"
|
||||||
|
|
||||||
|
# Resolve config-defined aliases (from wgctl.json commands section)
|
||||||
|
if [[ -n "${_COMMAND_ALIASES[$cmd]:-}" ]]; then
|
||||||
|
cmd="${_COMMAND_ALIASES[$cmd]}"
|
||||||
|
fi
|
||||||
|
|
||||||
case "$cmd" in
|
case "$cmd" in
|
||||||
help) wgctl::help; return ;;
|
help) wgctl::help; return ;;
|
||||||
shell) : ;;
|
shell) : ;;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue