Naposledy aktivní 1 month ago

Revize 0010a86ca419975455cb66f82ecd556ccc2b09f4

gistfile1.txt Raw
1#!/usr/bin/env bash
2
3# ============================================
4# Private helpers
5# ============================================
6
7function cmd::shell::_prompt() {
8 local user host dir
9 user=$(whoami)
10 host=$(hostname -s)
11 dir=$(basename "$PWD")
12 printf "\033[1;32m%s@%s\033[0m:\033[0;36m%s\033[0m \033[1;34mwgctl\033[0m> " \
13 "$user" "$host" "$dir"
14}
15
16function cmd::shell::_is_wgctl_command() {
17 local cmd="${1:-}"
18 local known=(
19 list add remove rm inspect block unblock
20 rule group audit logs watch fw config qr
21 rename keys ip net service shell help test
22 )
23 local c
24 for c in "${known[@]}"; do
25 [[ "$c" == "$cmd" ]] && return 0
26 done
27 return 1
28}
29
30function cmd::shell::_handle_builtin() {
31 local input="${1:-}"
32 local first="${input%% *}"
33
34 case "$first" in
35 cd)
36 local dir="${input#cd }"
37 [[ "$dir" == "$input" ]] && dir="$HOME"
38 cd "$dir" 2>/dev/null || log::error "cd: $dir: No such file or directory"
39 return 0
40 ;;
41 export|unset|source|.)
42 eval "$input"
43 return 0
44 ;;
45 esac
46 return 1
47}
48
49function cmd::shell::_execute() {
50 local input="${1:-}"
51 local first="${input%% *}"
52 local rest="${input#"$first"}"
53 rest="${rest# }"
54
55 cmd::shell::_handle_builtin "$input" && return 0
56
57 if cmd::shell::_is_wgctl_command "$first"; then
58 if [[ -n "$rest" ]]; then
59 wgctl::dispatch "$first" $rest || true
60 else
61 wgctl::dispatch "$first" || true
62 fi
63 return 0
64 fi
65
66 bash -c "$input" || true
67}
68
69function cmd::shell::_setup_history() {
70 HISTFILE="${HOME}/.wgctl_history"
71 HISTSIZE=1000
72 HISTFILESIZE=2000
73 history -r 2>/dev/null || true
74}
75
76function cmd::shell::_save_history() {
77 history -w 2>/dev/null || true
78}
79
80function cmd::shell::_banner() {
81 ui::section "wgctl shell"
82 printf "\n"
83 printf " Type wgctl commands directly (no 'wgctl' prefix).\n"
84 printf " Bash commands work too: ls, cat, systemctl, vim...\n\n"
85 printf " \033[1;37mCommon commands:\033[0m\n"
86 printf " list List all peers\n"
87 printf " list --blocked Show blocked peers\n"
88 printf " list --restricted Show restricted peers\n"
89 printf " list --rule user Filter by rule\n"
90 printf " inspect --name <peer> Full peer details\n"
91 printf " block --name <peer> Block a peer entirely\n"
92 printf " block --name <peer> --service proxmox Restrict service\n"
93 printf " unblock --name <peer> Restore full access\n"
94 printf " rule list Show firewall rules\n"
95 printf " rule list --tree Show with inheritance\n"
96 printf " rule show --name <rule> Rule details\n"
97 printf " net list Show network services\n"
98 printf " net list --detailed Show services with ports\n"
99 printf " group list Show groups\n"
100 printf " group block --name <group> Block all peers in group\n"
101 printf " logs --follow Live activity log\n"
102 printf " logs rotate Clean old log entries\n"
103 printf " watch Live WG + firewall monitor\n"
104 printf " fw list Show iptables rules\n"
105 printf " audit Verify firewall state\n"
106 printf " audit --fix Auto-repair firewall rules\n\n"
107 printf " \033[1mexit\033[0m or \033[1mquit\033[0m to leave · \033[1mhelp\033[0m for full command list\n\n"
108}
109
110# ============================================
111# Lifecycle
112# ============================================
113
114function cmd::shell::on_load() {
115 : # no flags needed
116}
117
118function cmd::shell::help() {
119 cat <<EOF
120Usage: wgctl shell
121
122Start an interactive wgctl shell.
123All wgctl commands work directly (no 'wgctl' prefix needed).
124Bash commands (ls, cat, systemctl, vim, etc.) also work.
125
126Shell builtins handled natively: cd, export, unset, source
127History saved to: ~/.wgctl_history
128
129Examples:
130 wgctl shell
131 wgctl> list --blocked
132 wgctl> inspect --name phone-nuno
133 wgctl> rule list --tree
134 wgctl> group block --name family
135 wgctl> logs --follow
136 wgctl> ls /etc/wireguard/.wgctl/rules/
137 wgctl> exit
138EOF
139}
140
141# ============================================
142# Tab completion
143# ============================================
144
145function cmd::shell::_setup_completion() {
146 local commands="list add remove rm inspect block unblock rule group audit logs watch fw config qr rename service shell help test"
147
148 function _wgctl_shell_complete() {
149 local cur="${COMP_WORDS[COMP_CWORD]}"
150 COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
151 }
152
153 bind 'set show-all-if-ambiguous on' 2>/dev/null || true
154 bind 'set completion-ignore-case on' 2>/dev/null || true
155}
156
157# ============================================
158# Run
159# ============================================
160
161function cmd::shell::run() {
162 cmd::shell::_banner
163 cmd::shell::_setup_history
164 cmd::shell::_setup_completion
165
166 while true; do
167 local input
168 IFS= read -r -e -p "$(cmd::shell::_prompt)" input || break
169
170 [[ -z "${input// }" ]] && continue
171
172 history -s "$input"
173
174 case "${input%% *}" in
175 exit|quit) break ;;
176 esac
177
178 cmd::shell::_execute "$input"
179 done
180
181 cmd::shell::_save_history
182 printf "\n Goodbye!\n\n"
183}