summaryrefslogtreecommitdiff
path: root/vpn
blob: 980fe635f99c2f24cc1f9a419a25e4eb73f9d9f2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env bash

set -euo pipefail

usage() {
  cat <<EOF
Usage: ${0##*/} <command> [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 "$@"