#!/usr/bin/env bash
# Real demos for P105 "How a WireGuard VPN Network Works". Made on the Mac (Docker Desktop), like P093.
# A small internet in Docker, all from one image (lab/Dockerfile):
#   laptop      Ana's laptop, first on the hotel's Wi-Fi (192.168.50.20), later on her phone's hotspot (172.20.10.3)
#   hotel-wifi  the hotel's router: NAT from 192.168.50.0/24 to its public address 203.0.113.50
#   hotspot     Ana's phone as a hotspot: NAT from 172.20.10.0/24 to 203.0.113.77
#   gateway     the print shop's WireGuard server: public 203.0.113.10, office side 10.20.0.2; also the shop's
#               public page on port 80 (lab/site)
#   files       the office file server, 10.20.0.10, reachable only from the office network (lab/files)
#   stranger    someone else on the internet, 203.0.113.66
# 203.0.113.0/24 is a documentation range (RFC 5737): nobody's real addresses. Every command shown is typed into a
# real interactive bash in a pty, one per machine (demo_driver.py); the keys are made in the demo and thrown away.
set -euo pipefail
cd "$(dirname "$0")"
P=ce-p105
M="laptop hotel-wifi hotspot gateway files stranger"
cleanup() {
  for m in $M; do docker rm -f $P-$m >/dev/null 2>&1 || true; done
  for n in hotel phone inet office; do docker network rm $P-$n >/dev/null 2>&1 || true; done
}
cleanup
[ -n "${KEEP:-}" ] || trap cleanup EXIT
docker build -q -t $P lab >/dev/null
docker network create --subnet 192.168.50.0/24 $P-hotel >/dev/null
docker network create --subnet 172.20.10.0/24 $P-phone >/dev/null
docker network create --subnet 203.0.113.0/24 $P-inet >/dev/null
docker network create --subnet 10.20.0.0/24 $P-office >/dev/null
run() { # name hostname network ip [extra docker args]
  local name=$1 host=$2 net=$3 ip=$4; shift 4
  docker run -d --name $P-$name --hostname $host --network $P-$net --ip $ip --cap-add NET_ADMIN --cap-add NET_RAW \
    --sysctl net.ipv4.ip_forward=1 "$@" $P >/dev/null
}
run laptop laptop hotel 192.168.50.20
run hotel-wifi hotel-wifi hotel 192.168.50.2
run hotspot hotspot phone 172.20.10.2
run gateway gateway inet 203.0.113.10
run files files office 10.20.0.10
run stranger stranger inet 203.0.113.66
docker network connect --ip 203.0.113.50 $P-inet $P-hotel-wifi
docker network connect --ip 203.0.113.77 $P-inet $P-hotspot
docker network connect --ip 10.20.0.2 $P-office $P-gateway
docker cp lab/files $P-files:/srv/files >/dev/null
docker cp lab/site $P-gateway:/srv/site >/dev/null
python3 - $P < demo_driver.py
