181 lines
7.2 KiB
Markdown
181 lines
7.2 KiB
Markdown
# Инфраструктурный тест HAN Chat
|
||
|
||
Автономный тест запускается непосредственно на ВМ и проверяет managed PostgreSQL и
|
||
три приватных Selectel S3-бакета в соответствии с контрактами HAN Chat. Для запуска
|
||
приложение и Docker Compose не требуются.
|
||
|
||
Тест не создаёт постоянных данных:
|
||
|
||
- PostgreSQL DDL/DML выполняются в транзакции и завершаются `ROLLBACK`;
|
||
- S3-объекты создаются только под уникальным префиксом `infratest/<uuid>/`;
|
||
- все S3-объекты удаляются в блоке очистки даже при ошибке одной из проверок.
|
||
|
||
## Что проверяется
|
||
|
||
### PostgreSQL
|
||
|
||
- подключение пяти сервисных ролей с TLS `verify-full`;
|
||
- `current_user`, `search_path`, наличие своей схемы и отсутствие `USAGE` на четыре
|
||
чужие схемы;
|
||
- `CREATE TABLE`, `INSERT`, `SELECT` и фактическое отсутствие таблицы после
|
||
`ROLLBACK`;
|
||
- расширение `pgcrypto`;
|
||
- опционально — ключевые таблицы и Alembic revision после миграций.
|
||
|
||
Проверяются роли:
|
||
|
||
- `han_app` → `han_app`;
|
||
- `bitrix_local_app` → `bitrix_local`;
|
||
- `bitrix_sync_user` → `bitrix_sync`;
|
||
- `message_safety_app` → `message_safety`;
|
||
- `keycloak_user` → `keycloak`.
|
||
|
||
### S3
|
||
|
||
- `HeadBucket` для quarantine, attachments и documents;
|
||
- прямые `PutObject`, `HeadObject`, `GetObject`, `ListObjectsV2` с ВМ;
|
||
- presigned PUT и GET с побайтовой проверкой содержимого;
|
||
- проектный переход `CopyObject` из quarantine в attachments с удалением
|
||
исходного объекта;
|
||
- запрет анонимного GET;
|
||
- CORS preflight для точного `PUBLIC_WEB_URL`;
|
||
- отдельный ключ message-safety: чтение/list только quarantine, запрет записи,
|
||
удаления и доступа к attachments/documents.
|
||
|
||
Multipart API не проверяется: текущая реализация HAN Chat использует single PUT.
|
||
Прикладные сценарии авторизации, создания диалога и отправки сообщения также не
|
||
входят в этот инструмент — это E2E приложения, а не проверка инфраструктуры.
|
||
|
||
## Подготовка на ВМ
|
||
|
||
Рекомендуется скопировать всю папку в отдельный каталог:
|
||
|
||
```bash
|
||
mkdir -p /opt/han-chat/infratest
|
||
cd /opt/han-chat/infratest
|
||
```
|
||
|
||
Установите Python 3.10+ и создайте изолированное окружение:
|
||
|
||
```bash
|
||
python3 -m venv .venv
|
||
. .venv/bin/activate
|
||
python3 -m pip install --upgrade pip
|
||
python3 -m pip install -r requirements.txt
|
||
```
|
||
|
||
Создайте настройки:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
chmod 600 .env
|
||
nano .env
|
||
```
|
||
|
||
В `.env` нужны сервисные пароли PostgreSQL, основной S3 RW-ключ и отдельный
|
||
quarantine read-only ключ. Административный пароль PostgreSQL не используется.
|
||
`HAN_PG_SSLROOTCERT` должен указывать на CA-файл по пути, доступному из процесса
|
||
на ВМ, а не на контейнерный путь `/run/secrets/pg-ca.pem`.
|
||
|
||
Не передавайте секреты аргументами командной строки и не прикладывайте `.env` к
|
||
отчётам. Файл исключён через `.gitignore`.
|
||
|
||
## Запуск
|
||
|
||
Полная самочищающаяся проверка:
|
||
|
||
```bash
|
||
cd /opt/han-chat/infratest
|
||
. .venv/bin/activate
|
||
python3 infratest.py --mode full
|
||
```
|
||
|
||
Проверка без DDL и записи в S3:
|
||
|
||
```bash
|
||
python3 infratest.py --mode readonly
|
||
```
|
||
|
||
Другой файл настроек и JSON-отчёт:
|
||
|
||
```bash
|
||
python3 infratest.py \
|
||
--env-file /secure/path/infratest.env \
|
||
--mode full \
|
||
--json-report report.json
|
||
```
|
||
|
||
Скрипт возвращает:
|
||
|
||
- `0` — нет проваленных проверок;
|
||
- `1` — одна или несколько инфраструктурных проверок завершились ошибкой;
|
||
- `2` — неверная конфигурация или отсутствуют Python-зависимости.
|
||
|
||
В консоль и JSON не выводятся пароли, access keys и query-параметры presigned URL.
|
||
|
||
## Запуск до и после миграций
|
||
|
||
До запуска Alembic оставьте:
|
||
|
||
```dotenv
|
||
INFRATEST_CHECK_MIGRATIONS=false
|
||
```
|
||
|
||
После успешного `deployment/scripts/migrate.sh` измените значение на:
|
||
|
||
```dotenv
|
||
INFRATEST_CHECK_MIGRATIONS=true
|
||
```
|
||
|
||
В этом режиме дополнительно проверяются ключевые таблицы схем `han_app`,
|
||
`bitrix_local`, `bitrix_sync` и ожидаемая revision `0001_initial` для `han_app`.
|
||
|
||
## Ожидаемая IAM-модель
|
||
|
||
Основной `SELECTEL_S3_ACCESS_KEY` должен иметь:
|
||
|
||
- RW на quarantine, attachments и documents;
|
||
- `ListBucket`, `GetBucketLocation`, `PutObject`, `GetObject`, `DeleteObject`;
|
||
- `CopyObject` обеспечивается правами чтения источника и записи назначения.
|
||
|
||
Ключ `SELECTEL_S3_QUARANTINE_READ_ACCESS_KEY` должен иметь только:
|
||
|
||
- `ListBucket`, `GetBucketLocation`, `GetObject` для quarantine;
|
||
- никаких прав на Put/Delete;
|
||
- никаких прав на attachments и documents.
|
||
|
||
Если IAM-политика ограничивает основной ключ другими object prefixes, разрешите
|
||
служебный префикс `infratest/*` либо запускайте только `--mode readonly`.
|
||
|
||
## CORS
|
||
|
||
При `INFRATEST_CHECK_CORS=true` quarantine должен отвечать на preflight:
|
||
|
||
- origin — точное значение `PUBLIC_WEB_URL`, без wildcard;
|
||
- method — `PUT`;
|
||
- headers — `Content-Type`, `x-amz-*`.
|
||
|
||
Чтобы временно исключить CORS из диагностики:
|
||
|
||
```dotenv
|
||
INFRATEST_CHECK_CORS=false
|
||
```
|
||
|
||
## Интерпретация результата
|
||
|
||
- `PASS` — контракт подтверждён реальной операцией;
|
||
- `FAIL` — контракт нарушен или ресурс недоступен;
|
||
- `SKIP` — проверка отключена режимом или настройкой.
|
||
|
||
При `FAIL` сначала проверьте сетевые ACL ВМ, CA/hostname PostgreSQL, GRANT и
|
||
`search_path`, затем IAM/CORS бакетов. После аварийного прерывания процесса можно
|
||
найти остатки только под префиксом `infratest/`; удалять другие ключи не требуется.
|
||
|
||
## Локальные unit-тесты
|
||
|
||
Они не обращаются к PostgreSQL или S3:
|
||
|
||
```bash
|
||
python3 -m unittest -v test_infratest.py
|
||
```
|