Files

187 lines
7.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Инфраструктурный тест 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 по
**vHosted** URL (`<bucket>.<s3_domain>`). У Selectel CORS не работает на
path-style адресации, даже если presigned PUT с сервера проходит.
Требования к правилу CORS на `han-chat-quarantine`:
- бакет с включённой Virtual-Hosted адресацией;
- origin — точное значение `PUBLIC_WEB_URL`, без wildcard;
- method — `PUT` (можно также `GET`, `HEAD`, `POST`);
- headers — минимум `content-type`; wildcard `x-amz-*` в панели Selectel обычно
**не работает**, надёжнее указать `*` или перечислить заголовки явно.
Чтобы временно исключить 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
```