aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/test/test.sh
blob: c0b4b94614c1a77c479f594cdbc2ff26fe078dce (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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#!/usr/bin/env bash

set -o errexit -o nounset -o pipefail
shopt -s inherit_errexit lastpipe

script_dir="$( dirname -- "${BASH_SOURCE[0]}" )"
script_dir="$( cd -- "$script_dir" && pwd )"
readonly script_dir

devices_only=

base_dir="$( mktemp -d )"
readonly base_dir

readonly subnet_base=192.168.166
ip_counter=1
port_counter=561

add_device() {
    local name
    for name; do
        local dir
        dir="$base_dir/devices/$name"
        mkdir -p -- "$dir"

        local ip
        ip="$subnet_base.$ip_counter"
        ip_counter=$((ip_counter + 1))
        echo "$ip" > "$dir/ip"

        local port
        port="$port_counter"
        port_counter=$((port_counter + 1))
        echo "$port" > "$dir/port"

        wg genkey | tee "$dir/private" | wg pubkey > "$dir/public"
        ip link add dev "$name" type wireguard
        ip addr add "$ip/24" dev "$name"
        wg set "$name" private-key "$dir/private"
        wg set "$name" listen-port "$port"
    done
}

connect_devices() {
    if [ "$#" -ne 2 ]; then
        echo "usage: ${FUNCNAME[0]} DEV1 DEV2" >&2
        return 1
    fi

    local dev1="$1"
    local dev2="$2"

    local dev1_dir
    dev1_dir="$base_dir/devices/$dev1"
    local dev2_dir
    dev2_dir="$base_dir/devices/$dev2"

    local pubkey1
    pubkey1="$( cat -- "$dev1_dir/public" )"
    local port
    port="$( cat -- "$dev1_dir/port" )"
    local pubkey2
    pubkey2="$( cat -- "$dev2_dir/public" )"
    local ip
    ip="$( cat -- "$dev2_dir/ip" )"

    wg set "$dev1" peer "$pubkey2" allowed-ips "$ip/32"
    wg set "$dev2" peer "$pubkey1" allowed-ips "$subnet_base.0/24" endpoint "127.0.0.1:$port" persistent-keepalive 25
}

up_device() {
    local name
    for name; do
        ip link set "$name" up
    done
}

show_device() {
    local name
    for name; do
        echo ------------------------------------------------------------------
        echo "Device: $name"
        echo ------------------------------------------------------------------
        wg show "$name"
        echo
    done
}

add_devices() {
    add_device server
    add_device client1
    add_device client2
    add_device client3
    connect_devices server client1
    connect_devices server client2
    connect_devices server client3
    up_device server client1 client2 client3
    sleep 2
    show_device server client1 client2 client3
}

build_services() {
    echo ------------------------------------------------------------------
    echo Building
    echo ------------------------------------------------------------------

    docker-compose pull api
    docker-compose build --force-rm --pull web
    WG_IFACE=server docker-compose up -d
}

run_curl() {
    curl -sS -D - --connect-timeout 3 http://192.168.177.1:1234/ "$@"
}

run_curl_api() {
    run_curl -H 'Content-Type: application/json' "$@"
}

call_api_method() {
    local method
    for method; do
        run_curl_api -d '{"jsonrpc": "2.0", "method": "'"$method"'", "params": {}}'
    done
}

check_api() {
    call_api_method ListPeers
    call_api_method GetDeviceInfo
}

cleanup() {
    echo ------------------------------------------------------------------
    echo Cleaning up
    echo ------------------------------------------------------------------

    if [ -d "$base_dir/devices" ]; then
        local name
        find "$base_dir/devices" -mindepth 1 -maxdepth 1 -type d -printf '%P\0' \
                | while IFS= read -d '' -r name; do
            echo "Removing device: $name"
            ip link delete "$name" type wireguard || true
        done
    fi

    echo "Removing $base_dir"
    rm -rf -- "$base_dir"

    if [ -z "$devices_only" ]; then
        echo "Brining down containers..."
        docker-compose down -v --remove-orphans
    fi
}

main() {
    cd -- "$script_dir/.."
    trap cleanup EXIT

    local opt
    while getopts ':i' opt "$@"; do
        case "$opt" in
            i)
                devices_only=1
                ;;
            :)
                echo "usage error: required argument missing for option -$OPTARG" >&2
                exit 1;
                ;;
            *)
                echo "usage error: invalid option -$OPTARG" >&2;
                exit 1;
                ;;
        esac
    done

    add_devices

    if [ -z "$devices_only" ]; then
        build_services
        check_api
    else
        while true; do sleep 1; done
    fi
}

main "$@"