summary refs log tree commit diff
path: root/bin/vpnm
blob: f09b41aa122a90d6f02bbca17e91a4c37f08a623 (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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/bin/bash
set -eu

# shellcheck disable=2034
description="vpn manager"

FUZL_PROMPT=vpnm
FUZL_ICON=󰦝
. libfuzl.sh

main() {
	local conn

	conn=$(get_current_connection)
	[ -n "$conn" ] && fuzl_action_add "down" "󰦝" "Connected to $conn"
	fuzl_action_add "networks" "󰾰" "Available networks"
	fuzl_action_add "profile" "󱗼" "Switch profile"

	fuzl_action_menu || return
}

#
# helpers
#

get_emoji_flag() {
	code=
	# TODO: calc flag
	# U\1F1E6 A
	# U\200D zero-w joiner
	case "$*" in
	au-*) code=$'🦘' ;;
	be-*) code=$'🇧🇪' ;;
	br-*) code=$'🇧🇷' ;;
	ca-*) code=$'🇨🇦' ;;
	de-*) code=$'🇩🇪' ;;
	fr-*) code=$'🇫🇷' ;;
	gb-*) code=$'🇬🇧' ;;
	jp-*) code=$'🇯🇵' ;;
	no-*) code=$'🇳🇴' ;;
	se-*) code=$'🇸🇪' ;;
	us-*) code=$'🇺🇸' ;;
	*tail2d6ce*) code=$'󰠜' ;;
	*) code=$'🌐' ;;
	esac
	echo -n $code
}

get_vpn_connections() {
	(
		tailscale exit-node list |
			awk '/.tail2d6ce.ts.net/{print $2, $1}'
		tailscale exit-node list |
			awk -F '[ ]{2,}' '/.mullvad.ts.net/{print $2, $1, ($3 "/" $4)}' |
			sort -u
	) | while read -r conn ip location; do
		printf '%s\t' "$ip"
		printf '%s\t' "$(get_emoji_flag "$conn")"
		if grep -q 'mullvad.ts.net' <<<"$conn"; then
			printf '%s\t' "$location"
		else
			printf '%s\t' "$conn"
		fi
		printf '\n'
	done
}

get_current_connection() {
	tailscale exit-node list |
		grep -e selected |
		grep -v -e Any | (
		awk '/.tail2d6ce.ts.net/{print $2, $1}'
		awk -F '[ ]{2,}' '/.mullvad.ts.net/{print $2, $1, ($3 "/" $4)}'
	) | while read -r conn ip location; do
		printf '%s' "$(get_emoji_flag "$conn")"
		printf ' '
		if grep -q 'mullvad.ts.net' <<<"$conn"; then
			printf '%s' "$location"
		else
			printf '%s' "$conn"
		fi
	done
}

vpnup() {
	fuzl_try -- tailscale set --exit-node=${1:?}
	fuzl_try -- pkill -RTMIN+2 -x waybar
}

vpndown() {
	fuzl_try -- tailscale set --exit-node=
	fuzl_try -- pkill -RTMIN+2 -x waybar
}

#
# actions
#

vpnm_down() {
	fuzl_try -- vpndown
}

vpnm_networks() {
	ip=$(get_vpn_connections |
		fuzl_menu $FUZL_MENU_FILTER --with-nth='{2}  {3}' --accept-nth=1)

	[ -n "$ip" ] || main
	fuzl_try -- vpnup "$ip"

}

vpnm_profile() {
	profile=$(tailscale switch --list 2>/dev/null |
		tail -n+2 |
		awk '{printf "%s\t%s\n", $3, $2}' |
		fuzl_menu $FUZL_MENU_FILTER --accept-nth=1)

	[ -n "$profile" ] || main
	fuzl_try -- tailscale switch "$profile"
	sleep 2
	fuzl_try -- pkill -SIGRTMIN+2 waybar
}

main