Commit 1e73e6e8 authored by Vitaly Lipatov's avatar Vitaly Lipatov

router: add web UI for managing bypass/direct route lists

Python web API (route-web-api.py) on port 80 for adding domains to egw bypass or dgw direct lists. Runs as unprivileged routeweb user, list files are picked up by route-update.sh via symlinks. Features: - Add/remove/move domains between bypass and direct lists - Auto-remove from other list when adding (mutual exclusion) - "No rule" button to remove from input field - Active routes section showing all applied rules from route-update - Last update timestamp from all-routes.json mtime route-update.sh: generate_web_json() exports all list entries as JSON for the web UI after each run. Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent f0223740
...@@ -833,6 +833,64 @@ EOF ...@@ -833,6 +833,64 @@ EOF
birdc configure >/dev/null 2>&1 && log "BIRD reconfigured" || log "WARNING: birdc configure failed" birdc configure >/dev/null 2>&1 && log "BIRD reconfigured" || log "WARNING: birdc configure failed"
} }
# --- Generate JSON with all active list entries for web UI ---
WEB_JSON="/home/routeweb/route-web-api/all-routes.json"
generate_web_json()
{
[ -d "$(dirname "$WEB_JSON")" ] || return 0
local tmp=$(mktemp "$WEB_JSON.XXXXXX" 2>/dev/null) || return 0
local first_group=true
echo '{' > "$tmp"
for routes_dir in "$ROUTES_DIR" ; do
[ -d "$routes_dir" ] || continue
for group_dir in "$routes_dir"/*/ ; do
[ -d "$group_dir" ] || continue
local group=$(basename "$group_dir")
local first_list=true
local has_lists=false
for listfile in "$group_dir"/*.list ; do
[ -f "$listfile" ] || continue
local fname=$(basename "$listfile")
local lname="${fname%.list}"
# Read entries (follow symlinks), skip empty
local entries=$(grep -v '^#' "$listfile" 2>/dev/null | grep -v '^$' | sort)
[ -z "$entries" ] && continue
if ! $has_lists ; then
$first_group || echo ',' >> "$tmp"
first_group=false
printf '"%s":{' "$group" >> "$tmp"
has_lists=true
fi
$first_list || echo ',' >> "$tmp"
first_list=false
# Format entries as JSON array
local json_entries=$(echo "$entries" | awk '
BEGIN { printf "[" }
NR > 1 { printf "," }
{ gsub(/"/, "\\\""); printf "\"%s\"", $0 }
END { printf "]" }
')
printf '"%s":%s' "$lname" "$json_entries" >> "$tmp"
done
$has_lists && echo '}' >> "$tmp"
done
done
echo '}' >> "$tmp"
chmod 644 "$tmp"
mv "$tmp" "$WEB_JSON"
vlog "Web JSON updated: $WEB_JSON"
}
# --- Check for duplicate .list files across groups --- # --- Check for duplicate .list files across groups ---
check_list_duplicates() check_list_duplicates()
{ {
...@@ -869,5 +927,6 @@ process_routes "$ROUTES_DIR" get_ipv4_list_bulk "ip" "" ...@@ -869,5 +927,6 @@ process_routes "$ROUTES_DIR" get_ipv4_list_bulk "ip" ""
process_routes "$ROUTES6_DIR" get_ipv6_list_bulk "ip -6" " (v6)" process_routes "$ROUTES6_DIR" get_ipv6_list_bulk "ip -6" " (v6)"
cleanup_state cleanup_state
generate_bird_config generate_bird_config
generate_web_json
[ -n "$SHOW" ] || log "All done" [ -n "$SHOW" ] || log "All done"
[Unit]
Description=Route management web API
After=network.target
[Service]
Type=simple
User=routeweb
Group=routeweb
WorkingDirectory=/home/routeweb/route-web-api
ExecStart=/usr/bin/python3 /home/routeweb/route-web-api/route-web-api.py
AmbientCapabilities=CAP_NET_BIND_SERVICE
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment