Remove non-deploy files from public repository
This commit is contained in:
@@ -1,128 +0,0 @@
|
|||||||
# План: независимые DrHider и Obfuscator
|
|
||||||
|
|
||||||
## Цель
|
|
||||||
|
|
||||||
Получить два полностью независимых production-сервиса:
|
|
||||||
|
|
||||||
- **DrHider** — репозиторий `Nail/drhider`, отдельный Flask-инстанс и отдельный upload-буфер.
|
|
||||||
- **Obfuscator** — репозиторий `forcloud/obfuscator`, отдельный Flask-инстанс и отдельный upload-буфер.
|
|
||||||
|
|
||||||
После разделения изменения, версии, деплои, сессии и временные файлы одного сервиса не должны влиять на другой.
|
|
||||||
|
|
||||||
## Целевая схема
|
|
||||||
|
|
||||||
```text
|
|
||||||
DrHider
|
|
||||||
repo: https://gitea.services.ngcloud.ru/Nail/drhider.git
|
|
||||||
app: https://drhider.pythonk8s.dev.nubes.ru/
|
|
||||||
buffer: https://upload-drhider.sinefo.ru/buffer/
|
|
||||||
|
|
||||||
Obfuscator
|
|
||||||
repo: https://gitea.services.ngcloud.ru/forcloud/obfuscator.git
|
|
||||||
app: https://obfuscator.pythonk8s.services.ngcloud.ru/
|
|
||||||
buffer: https://upload-obfuscator.sinefo.ru/buffer/
|
|
||||||
```
|
|
||||||
|
|
||||||
Оба буфера могут находиться на VM213, но должны иметь разные hostname и разные директории:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/var/www/upload-drhider/
|
|
||||||
/var/www/upload-obfuscator/
|
|
||||||
```
|
|
||||||
|
|
||||||
Текущий адрес `https://upload.sinefo.ru/drhider-upload/` считать временным legacy-маршрутом. Его не использовать в новой конфигурации Obfuscator.
|
|
||||||
|
|
||||||
## Этап 1. Разделить production-инстансы
|
|
||||||
|
|
||||||
1. Создать отдельный Managed Flask-инстанс для `forcloud/obfuscator`.
|
|
||||||
2. Оставить DrHider подключённым только к `Nail/drhider`.
|
|
||||||
3. Проверить, что у сервисов разные:
|
|
||||||
- instance ID;
|
|
||||||
- hostname;
|
|
||||||
- переменные окружения;
|
|
||||||
- настройки Redeploy.
|
|
||||||
4. Не добавлять `upstream`, не использовать общий Git remote и не подключать один репозиторий как submodule другого.
|
|
||||||
|
|
||||||
## Этап 2. Разделить upload-буферы на VM213
|
|
||||||
|
|
||||||
1. Создать две директории с владельцем пользователя Nginx:
|
|
||||||
- `/var/www/upload-drhider/`;
|
|
||||||
- `/var/www/upload-obfuscator/`.
|
|
||||||
2. Добавить в Nginx два независимых WebDAV location:
|
|
||||||
- `/buffer/` для `upload-drhider.sinefo.ru`;
|
|
||||||
- `/buffer/` для `upload-obfuscator.sinefo.ru`.
|
|
||||||
3. Для каждого location настроить отдельно:
|
|
||||||
- `alias`;
|
|
||||||
- `PUT`, `GET`, `DELETE`;
|
|
||||||
- `client_max_body_size`;
|
|
||||||
- CORS только для своего Flask-инстанса;
|
|
||||||
- очистку старых временных файлов.
|
|
||||||
4. Не менять и не удалять старый маршрут до завершения миграции и проверки обоих сервисов.
|
|
||||||
|
|
||||||
## Этап 3. DNS и TLS
|
|
||||||
|
|
||||||
Создать A-записи на IP VM213 `5.172.178.213`:
|
|
||||||
|
|
||||||
```text
|
|
||||||
upload-drhider.sinefo.ru A 5.172.178.213
|
|
||||||
upload-obfuscator.sinefo.ru A 5.172.178.213
|
|
||||||
```
|
|
||||||
|
|
||||||
Для обоих hostname выпустить отдельные сертификаты Certbot и проверить автоматическое продление.
|
|
||||||
|
|
||||||
## Этап 4. Конфигурация приложений
|
|
||||||
|
|
||||||
В DrHider указать только его буфер. В Obfuscator указать только его буфер.
|
|
||||||
|
|
||||||
Проверить и при необходимости заменить во всех рабочих файлах:
|
|
||||||
|
|
||||||
- фронтендовый `VM_UPLOAD_URL`;
|
|
||||||
- backend `VM_UPLOAD_PREFIX`;
|
|
||||||
- значение `vmUploadPrefix` в health/config endpoint;
|
|
||||||
- CORS origin;
|
|
||||||
- пути временного хранения и очистки.
|
|
||||||
|
|
||||||
Переименовать общие переменные в нейтральные имена, например `UPLOAD_BUFFER_URL`, если это не ломает существующий публичный API.
|
|
||||||
|
|
||||||
## Этап 5. Независимые деплои
|
|
||||||
|
|
||||||
Для каждого сервиса отдельно:
|
|
||||||
|
|
||||||
1. Изменить код только в его репозитории.
|
|
||||||
2. Выполнить локальные тесты и проверку синтаксиса.
|
|
||||||
3. Сделать commit и push в его `master`.
|
|
||||||
4. Выполнить Redeploy соответствующего Managed Flask-инстанса.
|
|
||||||
5. Проверить `/health` и версию.
|
|
||||||
|
|
||||||
Push в `Nail/drhider` не должен запускать или изменять Obfuscator. Push в `forcloud/obfuscator` не должен запускать или изменять DrHider.
|
|
||||||
|
|
||||||
## Этап 6. Проверка изоляции
|
|
||||||
|
|
||||||
Для каждого сервиса отдельно проверить:
|
|
||||||
|
|
||||||
- `GET /health` возвращает правильную версию;
|
|
||||||
- браузерный `OPTIONS` возвращает CORS только для своего origin;
|
|
||||||
- `PUT -> GET -> DELETE` работает через собственный hostname;
|
|
||||||
- файл одного сервиса не виден в директории другого;
|
|
||||||
- отмена и очистка сессии не затрагивают второй сервис;
|
|
||||||
- обновление версии одного приложения не меняет `/health` второго.
|
|
||||||
|
|
||||||
## Этап 7. Удаление legacy-связей
|
|
||||||
|
|
||||||
После успешной миграции и периода наблюдения:
|
|
||||||
|
|
||||||
1. Перевести оба приложения на новые buffer hostname.
|
|
||||||
2. Проверить отсутствие `contracts.kube5s.ru` и `upload.sinefo.ru/drhider-upload/` в рабочих конфигурациях.
|
|
||||||
3. Удалить старый WebDAV location только после подтверждения, что активных клиентов больше нет.
|
|
||||||
4. Обновить README обоих проектов и документацию VM213.
|
|
||||||
|
|
||||||
## Критерий готовности
|
|
||||||
|
|
||||||
Разделение считается завершённым, когда:
|
|
||||||
|
|
||||||
- у DrHider и Obfuscator разные production-инстансы;
|
|
||||||
- у них разные Git-репозитории без общей синхронизации;
|
|
||||||
- у них разные upload hostname и директории на VM213;
|
|
||||||
- CORS и TLS настроены для каждого отдельно;
|
|
||||||
- независимый Redeploy одного сервиса не меняет другой;
|
|
||||||
- smoke-тесты обоих сервисов проходят одновременно.
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
# План: фильтрация файлов через `.lst`
|
|
||||||
|
|
||||||
## Цель
|
|
||||||
|
|
||||||
Добавить в file picker режим manifest-фильтра:
|
|
||||||
|
|
||||||
- пользователь выбирает папку целиком;
|
|
||||||
- если в корне выбранной папки есть `obscure.lst`, он ограничивает набор файлов;
|
|
||||||
- если `.lst` нет, сохраняется текущее поведение: выбираются все поддерживаемые файлы;
|
|
||||||
- сам `obscure.lst` никогда не отправляется на обработку;
|
|
||||||
- другие файлы с расширением `.lst` не являются manifest-файлами и не загружаются.
|
|
||||||
|
|
||||||
## Правила `obscure.lst`
|
|
||||||
|
|
||||||
Одна строка — одно правило.
|
|
||||||
|
|
||||||
- пустые строки игнорируются;
|
|
||||||
- строки, начинающиеся с `#`, являются комментариями;
|
|
||||||
- `!` в начале строки означает отрицательное правило;
|
|
||||||
- пути относительны к выбранной папке;
|
|
||||||
- абсолютные пути и сегменты `..` запрещены;
|
|
||||||
- разделители `\` нормализуются в `/`;
|
|
||||||
- весь путь сравнивается без учёта регистра;
|
|
||||||
- несколько совпавших правил не создают дубли.
|
|
||||||
|
|
||||||
Пример:
|
|
||||||
|
|
||||||
```text
|
|
||||||
*.pdf
|
|
||||||
reports/name*.docx
|
|
||||||
!archive/**
|
|
||||||
!**/*draft*.*
|
|
||||||
```
|
|
||||||
|
|
||||||
## Glob-маски
|
|
||||||
|
|
||||||
Поддержать общепринятые шаблоны:
|
|
||||||
|
|
||||||
- `*` — любое количество символов, кроме `/`;
|
|
||||||
- `?` — один символ, кроме `/`;
|
|
||||||
- `**` — любое количество каталогов;
|
|
||||||
- `[abc]` и `[a-z]` — классы и диапазоны символов;
|
|
||||||
- `[!a]` и `[^a]` — отрицательные классы;
|
|
||||||
- обычный путь без glob-символов — точное совпадение.
|
|
||||||
|
|
||||||
Семантика:
|
|
||||||
|
|
||||||
- `*.pdf` — PDF только в корне выбранной папки;
|
|
||||||
- `reports/*.pdf` — PDF внутри `reports`;
|
|
||||||
- `**/*.pdf` — PDF на любой глубине;
|
|
||||||
- `name*.pdf` — файлы с префиксом `name` в корне;
|
|
||||||
- `reports/name*.pdf` — файлы с префиксом `name` непосредственно в `reports`;
|
|
||||||
- `reports/` — то же, что `reports/**`;
|
|
||||||
- `a**b` — две звёздочки внутри сегмента работают как обычная `*`.
|
|
||||||
|
|
||||||
Правило без `/` не применяется рекурсивно. Для поиска на любой глубине нужно
|
|
||||||
явно использовать `**/`, например `**/*.pdf`.
|
|
||||||
|
|
||||||
Положительные правила формируют набор кандидатов. Отрицательные правила
|
|
||||||
удаляют совпавшие файлы из результата.
|
|
||||||
|
|
||||||
## Алгоритм
|
|
||||||
|
|
||||||
1. Получить все файлы выбранной папки и подпапок через `webkitdirectory`.
|
|
||||||
2. Нормализовать `webkitRelativePath`, убрав имя корневой выбранной папки.
|
|
||||||
3. Найти только `obscure.lst` в корне выбранной папки, без учёта регистра.
|
|
||||||
Остальные `.lst` игнорировать.
|
|
||||||
4. Если `obscure.lst` нет, передать в текущую логику все поддерживаемые файлы.
|
|
||||||
5. Если `obscure.lst` найден:
|
|
||||||
- прочитать UTF-8 и убрать BOM;
|
|
||||||
- разобрать строки и скомпилировать glob в RegExp;
|
|
||||||
- отбросить некорректные правила с предупреждением и номером строки;
|
|
||||||
- выбрать поддерживаемые файлы, совпавшие хотя бы с одним положительным правилом;
|
|
||||||
- удалить совпадения с отрицательными правилами;
|
|
||||||
- удалить `.lst` из результата;
|
|
||||||
- сохранить исходный порядок файлов и убрать дубли по нормализованному пути.
|
|
||||||
6. Передать итоговый список в существующий цикл построения таблицы без изменений.
|
|
||||||
|
|
||||||
Если все положительные правила отсутствуют или некорректны, результат пустой.
|
|
||||||
Автоматический fallback на все файлы запрещён.
|
|
||||||
|
|
||||||
Если положительное правило не совпало ни с одним файлом, показать предупреждение,
|
|
||||||
но продолжить обработку остальных правил. Неподдерживаемые файлы не добавлять.
|
|
||||||
|
|
||||||
`obscure.lst` во вложенной папке не является manifest-фильтром и обрабатывается как
|
|
||||||
обычный неподдерживаемый файл.
|
|
||||||
|
|
||||||
Содержимое ZIP отдельно не фильтровать: ZIP выбирается как один файл и далее
|
|
||||||
обрабатывается существующим механизмом раскрытия архивов.
|
|
||||||
|
|
||||||
## Нормализация и предупреждения
|
|
||||||
|
|
||||||
Перед сопоставлением:
|
|
||||||
|
|
||||||
- заменить `\` на `/`;
|
|
||||||
- убрать ведущие `./`;
|
|
||||||
- свернуть повторные `/`;
|
|
||||||
- убрать имя корневой выбранной папки из `webkitRelativePath`;
|
|
||||||
- отклонить абсолютные пути, сегменты `..` и пустые правила;
|
|
||||||
- отклонить незакрытые классы `[` с указанием номера строки.
|
|
||||||
|
|
||||||
Ошибки и предупреждения передавать через существующий `cfg.onError` или
|
|
||||||
`statusEl`. Ошибка одного правила не должна останавливать остальные правила.
|
|
||||||
Ошибка чтения или декодирования `obscure.lst` даёт предупреждение и пустой результат.
|
|
||||||
|
|
||||||
## Где менять код
|
|
||||||
|
|
||||||
Алгоритм фильтра вынести в чистый модуль рядом с текущим picker, например:
|
|
||||||
|
|
||||||
```text
|
|
||||||
upload/frontend/table/lst_filter.js
|
|
||||||
```
|
|
||||||
|
|
||||||
Точка подключения — `on_folder_change.js`, до существующего цикла построения
|
|
||||||
дерева. DOM и upload-транспорт в модуль фильтра не добавлять.
|
|
||||||
|
|
||||||
Сборочные `site/static/dist/*.js` изменять только штатной сборкой.
|
|
||||||
|
|
||||||
## Минимальные тесты
|
|
||||||
|
|
||||||
Проверить:
|
|
||||||
|
|
||||||
1. Папка без `.lst` сохраняет старое поведение.
|
|
||||||
2. `obscure.lst` не попадает в результат, другие `.lst` также не загружаются.
|
|
||||||
3. `*.pdf`, `name*.pdf`, `?`, `**` и классы символов.
|
|
||||||
4. `*.pdf` совпадает только с файлом в корне, а `**/*.pdf` — также с `x.pdf`
|
|
||||||
в корне и файлами в подпапках.
|
|
||||||
5. `docs/name*.pdf`, `docs/`, `a**b` и точные пути.
|
|
||||||
6. Положительные и отрицательные правила вместе.
|
|
||||||
7. Комментарии, пустые строки, BOM, CRLF и пробелы.
|
|
||||||
8. Регистр всего пути (`DOCS/A.PDF` совпадает с `docs/*.pdf`).
|
|
||||||
9. Кириллицу, пробелы, вложенные каталоги и обратные слеши (`docs\a.pdf`).
|
|
||||||
10. Дубли и перекрывающиеся маски.
|
|
||||||
11. Запрет `/etc/x`, `C:/x`, `../x`, `a/../b`.
|
|
||||||
12. Битую маску без падения всего picker.
|
|
||||||
13. Ошибка чтения `.lst` даёт пустой результат и предупреждение.
|
|
||||||
14. Правило без совпадений даёт предупреждение.
|
|
||||||
15. Только отрицательные или полностью битые правила дают пустой результат.
|
|
||||||
16. Другой `.lst` в корне не включает manifest-режим.
|
|
||||||
17. `obscure.lst` во вложенной папке не включает manifest-режим.
|
|
||||||
18. ZIP выбирается целиком, без фильтрации его внутреннего содержимого.
|
|
||||||
|
|
||||||
## Ограничения реализации
|
|
||||||
|
|
||||||
- Не менять backend-контракт.
|
|
||||||
- Не добавлять базу данных, отдельный сервис или новый формат конфигурации.
|
|
||||||
- Не переписывать существующий picker.
|
|
||||||
- Изменить минимальное число файлов.
|
|
||||||
- Сначала реализовать алгоритм и тесты, затем обновить dist штатной сборкой.
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
# DrHider Obfuscator
|
|
||||||
|
|
||||||
Чистая deploy-копия Flask-приложения DrHider без документации, истории,
|
|
||||||
тестов и временных файлов.
|
|
||||||
|
|
||||||
## Репозиторий и деплой
|
|
||||||
|
|
||||||
- репозиторий: `https://gitea.services.ngcloud.ru/forcloud/obfuscator.git`
|
|
||||||
- entrypoint: `site/app.py`, глобальный Flask `app`
|
|
||||||
- зависимости: `requirements.txt`
|
|
||||||
- публичное приложение: `https://drhider.pythonk8s.dev.nubes.ru/`
|
|
||||||
- платформа: Managed Flask / Штурвал
|
|
||||||
|
|
||||||
Порядок публикации:
|
|
||||||
|
|
||||||
1. Push в `master`.
|
|
||||||
2. В Штурвале выбрать приложение DrHider, подключённое к этой репе.
|
|
||||||
3. Нажать **Redeploy**.
|
|
||||||
4. Проверить `GET /health` и поле `version`.
|
|
||||||
|
|
||||||
## Структура
|
|
||||||
|
|
||||||
- `site/` — Flask-приложение, маршруты, шаблоны и статика.
|
|
||||||
- `drhider/` — ядро извлечения, сканирования, замены и сборки ZIP.
|
|
||||||
- `upload/` — runtime-часть загрузки файлов и WebDAV-транзита.
|
|
||||||
|
|
||||||
## Внешний upload-буфер
|
|
||||||
|
|
||||||
DrHider использует WebDAV-буфер на VM213 `5.172.178.213`:
|
|
||||||
|
|
||||||
```text
|
|
||||||
https://upload.sinefo.ru/drhider-upload/
|
|
||||||
```
|
|
||||||
|
|
||||||
Поток: браузер делает `PUT`, Flask получает ссылки через `/api/upload_refs`,
|
|
||||||
забирает файлы с VM213 и удаляет их после обработки.
|
|
||||||
|
|
||||||
Nginx, DNS и TLS буфера находятся на VM213 и не управляются этим Git-репозиторием.
|
|
||||||
Старый `contracts.kube5s.ru` не использовать.
|
|
||||||
|
|
||||||
## Отдельный upload-platform
|
|
||||||
|
|
||||||
`forcloud/upload-platform` — отдельная репа и отдельный сервис `vmfiles.service`
|
|
||||||
на VM213. Push в этот репозиторий не обновляет данный Flask-деплой, и наоборот.
|
|
||||||
Reference in New Issue
Block a user