Files
website/scripts/demo/up.sh
T
Christian ManivongandClaude Opus 5.5 011f816fc9 feat: replace UI mockups with real netOrk screenshots
The homepage showed seven hand-built JSX imitations of the netOrk UI. They
are gone; every image is now a screenshot of netOrk v0.28.0 itself, taken
from an anonymized copy of a production database (scripts/demo) with
scripts/screenshots/capture.py and published as WebP (~630 KB for all eight).

- Hero: the device inventory. Walkthrough: device detail, VLANs, the Security
  tab, the vulnerability triage queue (replacing the config-diff row), the
  dashboard and service checks (new row 6). NIS2: the audit log, filtered to
  what people did.
- Copy follows the images: row 3 describes the security assessment, row 4 the
  triage queue; row 2 no longer claims corrections are always automatic;
  18 widgets. Alt texts in both languages.
- Also fixed on the homepage: the NIS2 teaser for Art. 21 (2e) and the
  container list of a deployment (three worker pools, plus Flower, registry,
  APT cache and the Signal gateway).
- Demo tooling hardened on the real dump: secrets inside JSON (Wi-Fi keys),
  reverse DNS zones, glued identifiers, tens of thousands of CrowdSec
  addresses, a schema newer than the release (anonymize, then downgrade),
  MFA-enforcing roles, and click steps for view filters.
- DESIGN.md: real screenshots only. PAGES.md: the six rows as they are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 08:24:51 +02:00

90 lines
4.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Local netOrk demo instance for website screenshots.
#
# up.sh restore <dump> fresh demo DB from a pg_dump -Fc file, then anonymize
# up.sh start API on :8000 and UI on :5173 (foreground, Ctrl-C stops)
# up.sh stop stop the demo database container
#
# Only the API and the UI run: no Celery worker, no beat, no Redis. Nothing
# polls, nothing reboots, nothing reaches a device. Stored credentials are
# emptied by anonymize.py and the encryption key is a fresh random one, so
# even a leftover value could not be decrypted.
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
DEMO="${NETORK_DEMO_DIR:-$HOME/.cache/netork-demo}"
SRC="$DEMO/src"
VENV="${NETORK_VENV:-$HOME/dev/NetOrk/.venv}"
VERSION="${NETORK_DEMO_VERSION:-v0.28.0}"
NETORK_REPO="${NETORK_REPO:-$HOME/dev/NetOrk}"
DB=netork-demo-db
PORT=55432
ensure_src() {
if [ ! -d "$SRC/netork" ]; then
mkdir -p "$SRC"
git -C "$NETORK_REPO" archive "$VERSION" | tar -x -C "$SRC"
fi
}
ensure_db() {
if ! docker ps --format '{{.Names}}' | grep -qx "$DB"; then
docker start "$DB" 2>/dev/null || docker run -d --name "$DB" \
-p 127.0.0.1:$PORT:5432 -e POSTGRES_DB=netork -e POSTGRES_USER=netork \
-e POSTGRES_PASSWORD=demo -v netork-demo-pg:/var/lib/postgresql/data postgres:16-alpine
until docker exec "$DB" pg_isready -U netork -q; do sleep 1; done
fi
}
case "${1:-}" in
restore)
dump="${2:?usage: up.sh restore <dump file>}"
ensure_src; ensure_db
docker exec "$DB" psql -U netork -d postgres -q \
-c "DROP DATABASE IF EXISTS netork WITH (FORCE)" -c "CREATE DATABASE netork"
docker exec -i "$DB" pg_restore -U netork -d netork --no-owner --no-privileges < "$dump" \
|| echo "pg_restore reported errors (often only missing roles/extensions); checking ..."
got=$(docker exec "$DB" psql -U netork -tA -c "SELECT version_num FROM alembic_version")
want=$(cd "$SRC" && PATH="$VENV/bin:$PATH" alembic heads 2>/dev/null | awk '{print $1}')
echo "dump schema: $got $VERSION head: $want"
# Anonymize first: it empties every secret, so a downgrade that would
# have to decrypt something (with a key we do not have) finds nothing.
"$VENV/bin/python" "$HERE/anonymize.py"
if [ "$got" != "$want" ]; then
# The production instance runs a newer build. Walk the copy back to the
# release with the newer code's own downgrade migrations.
NEWER="${NETORK_NEWER_REF:-origin/main}"
echo "migrating the copy from $got back to $want with $NEWER's migrations"
rm -rf "$DEMO/src-newer"; mkdir -p "$DEMO/src-newer"
git -C "$NETORK_REPO" archive "$NEWER" | tar -x -C "$DEMO/src-newer"
# Rows the older schema cannot hold: CrowdSec blocklist alerts whose scope
# is a list name, longer than the column they go back into.
docker exec "$DB" psql -U netork -q -c \
"DELETE FROM crowdsec_alerts WHERE length(source_scope) > 32" 2>/dev/null || true
(cd "$DEMO/src-newer" && PATH="$VENV/bin:$PATH" \
DATABASE_URL="postgresql+asyncpg://netork:demo@127.0.0.1:$PORT/netork" alembic downgrade "$want")
"$VENV/bin/python" "$HERE/anonymize.py" --report-only
fi
;;
start)
ensure_src; ensure_db
[ -d "$SRC/ui/node_modules" ] || (cd "$SRC/ui" && npm ci --no-audit --no-fund)
export DATABASE_URL="postgresql+asyncpg://netork:demo@127.0.0.1:$PORT/netork"
export ENVIRONMENT=development
export SECRET_KEY="$(openssl rand -hex 32)"
export CREDENTIAL_ENCRYPTION_KEY="$("$VENV/bin/python" -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())')"
# Nothing listens on port 1: no task can be queued, so no worker could act.
export REDIS_URL=redis://127.0.0.1:1/0 CELERY_BROKER_URL=redis://127.0.0.1:1/0 CELERY_RESULT_BACKEND=redis://127.0.0.1:1/1
cd "$SRC"
"$VENV/bin/uvicorn" netork.api.main:app --host 127.0.0.1 --port 8000 &
api=$!
trap 'kill $api 2>/dev/null' EXIT
cd ui && npx vite --host 127.0.0.1 --port 5173 --strictPort
;;
stop)
docker stop "$DB"
;;
*)
sed -n '2,12p' "$0"; exit 1 ;;
esac