chore(#16): каркас пакетов backend, тестов и заглушки ui/deploy/tests

This commit is contained in:
2026-10-21 23:28:59 +03:00
parent 63c4fa930d
commit 5647d339b1
8 changed files with 91 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
# awg_agent — привилегированный агент
Запускается как root в контейнере: всё, что требует NET_ADMIN и доступа к ядру.
| Модуль | Ответственность | Задача |
|---|---|---|
| `vpn/` | парсинг/валидация `.conf`, up/down/restart туннеля, `awg show` → статус | #22 |
| `watchdog/` | контроль handshake, авто-восстановление, fail-closed | #23 |
| `netfilter/` | iptables/ipset, policy routing, atomic swap, MSS clamping, IPv6 | #24 |
| `geoip/` | RIPE Stat, кэш-снапшот, расписание, fallback | #25 |
| `dns/` | dnsmasq, домены → ipset, защита от DNS-утечки | #26 |
| `routing/` | режимы (GeoIP / DNS / All-VPN / Direct-only), reconcile, исключения | #27 |
| `metrics/` | RX/TX, direct vs VPN, история, агрегаты | #28 |
| `devices/` | активные устройства LAN и их политики | #29 |
Интерфейс для `awg_api` — unix-socket `/run/awg/agent.sock` (см. ADR-002).
+5
View File
@@ -0,0 +1,5 @@
"""Привилегированный агент awg-dash: туннель, маршрутизация, GeoIP, DNS, метрики."""
__version__ = "0.0.1"
__all__ = ["__version__"]
+13
View File
@@ -0,0 +1,13 @@
# awg_api — control plane
Непривилегированный процесс: FastAPI + REST API v1 + WebSocket + отдача статики UI.
| Модуль | Ответственность | Задача |
|---|---|---|
| `app.py` | lifespan, конфиг, логирование, error model, статика | #31 |
| `routers/` | эндпоинты по OpenAPI (status, config, routing, devices, logs, auth) | #32 |
| `ws/` | `/api/v1/metrics/stream` | #33 |
| `security/` | токен, CSRF, rate limit, маскировка секретов | #34 |
| `store/` | SQLite (WAL), миграции, audit log, apply/rollback | #20 |
Контракт — `docs/openapi.yaml` (задача #19), TS-клиент генерируется в `ui/src/api/generated/`.
+5
View File
@@ -0,0 +1,5 @@
"""FastAPI-приложение awg-dash: REST API v1, WebSocket, статика UI."""
__version__ = "0.0.1"
__all__ = ["__version__"]
+13
View File
@@ -0,0 +1,13 @@
"""Скелетные тесты: пакеты импортируются, версия объявлена."""
import awg_agent
import awg_api
def test_versions_match() -> None:
assert awg_agent.__version__ == awg_api.__version__
def test_public_api_declared() -> None:
assert "__version__" in awg_agent.__all__
assert "__version__" in awg_api.__all__
+12
View File
@@ -0,0 +1,12 @@
# deploy — сборка и развёртывание
| Артефакт | Назначение | Задача |
|---|---|---|
| `Dockerfile` | multi-stage: amneziawg-go + awg-tools → runtime alpine | #18 |
| `entrypoint.sh` | супервизор: `awg-agent` (root) + `awg-api` | #18 |
| `docker-compose.dev.yml` | dev-стенд: порт 8080, тома `/config` `/data`, healthcheck | #21 |
| `docker-compose.test.yml` | стенд для тестов | #21 |
| `grafana/` | дашборд JSON (опциональный профиль monitoring) | #46 |
| `awg0.conf.example` | пример клиентского конфига | #22 |
Запуск по ТЗ (после релиза): `--network=host`, `--device=/dev/net/tun`, `--cap-add=NET_ADMIN --cap-add=SYS_MODULE`, `--restart always`.
+13
View File
@@ -0,0 +1,13 @@
# tests/netns — сетевой тестовый стенд
Задача **#21**, используется тестами #41 и #43.
Цель: проверять split-tunnel без реального VPN-провайдера и без доступа к продакшн-сети.
План харнесса:
1. Создать netns: `client`, `gw` (шлюз с awg-интерфейсом), `uplink` (имитация ISP).
2. Поднять мок WireGuard-endpoint (userspace) вместо реального сервера.
3. Запустить шлюз в netns с теми же правилами, что в контейнере.
4. Проверить, куда ушёл пакет: интерфейс/метка/счётчики ipset и iptables.
Точки входа: `tests/netns/run.sh` (вызывается через `make test-netns`).
+14
View File
@@ -0,0 +1,14 @@
# ui — Web UI (React + TypeScript + Tailwind + shadcn-ui)
Тёмная тема, 6 страниц из ТЗ. Каркас — задача **#35**, страницы — #36–#39, E2E — #42.
| Маршрут | Страница | Задача |
|---|---|---|
| `/` | Dashboard: статус, трафик, handshake, аптайм | #36 |
| `/routing` | редактор правил, ipset, домены, режимы, DnD+diff | #37 |
| `/config` | загрузка `.conf`, валидация, маскировка ключей | #38 |
| `/devices` | устройства и политики | #39 |
| `/logs` | журнал, счётчики RETURN vs MARK | #39 |
| `/settings` | GeoIP-расписание, обновления, интеграции | #39 |
API-клиент генерируется из OpenAPI (#19) в `src/api/generated/`. Взаимодействие: REST + WebSocket.