#!/usr/bin/env bash set -euo pipefail usage() { cat < [connections...] Manage Network Manager VPN connections. Commands: up enable vpn down disable vpn toggle toggle vpn status status display vpn staus If a connection name is passed, run the command on that connection; otherwise, select the connection interactively. If multiple connections are selected, the command will be applied to them sequentially. If no arguments passed and no active connection then equal to up command, if has active connections then equals to down command EOF exit 1 } list_vpn_connections() { nmcli -t --fields=TYPE,ACTIVE,UUID,NAME connection show | awk 'BEGIN{FS=":"; OFS=FS}/^(vpn|wireguard):/{print $2, $3, $4}' } select_connection() { local state local columns=2 # shellcheck disable=SC2016 local output='{print $1}' case "$1" in up) state=no ;; down) state=yes ;; toggle) state="" columns="1,3" # shellcheck disable=SC2016 output='{if ($1=="yes"){print $2, "down"} else {print $2, "up"}}' ;; esac list_vpn_connections | awk -v state="$state" 'BEGIN{FS=":"; OFS=FS}{if ($1==state){print $2, $3} if (state=="") {print $0}}' | fzf --multi --delimiter=':' --with-nth="$columns" --exit-0 --select-1 | awk -F ':' "$output" } run_command() { local state=$1 shift if [ $# -eq 0 ]; then select_connection "$state" | while read -r connection_uuid; do nmcli connection "$state" "$connection_uuid" >/dev/null done else for connection in "$@"; do nmcli connection "$state" "$connection" >/dev/null done fi } run_toggle() { if [ $# -eq 0 ]; then select_connection toggle | while read -r connection_uuid state; do run_command "$state" "$connection_uuid" done else for connection in "$@"; do if nmcli connection show "$connection" | grep "GENERAL.STATE" >/dev/null; then run_command down "$connection" else run_command up "$connection" fi done fi } run_status() { ( echo "Active:Name" list_vpn_connections | cut --delimiter=':' --fields=1,3 ) | column --table --separator=':' } main() { if [ $# -eq 0 ]; then main down || main up exit fi command_name="$1" shift case "$command_name" in up | down) run_command "$command_name" "$@" ;; toggle | status) "run_$command_name" "$@" ;; *) usage ;; esac } main "$@"