Skip to content

Repository files navigation

ops-panel: панель доменных конфигураций Traefik (GitOps)

ops-panel — это веб-панель для безопасного добавления доменов через GitHub GitOps.

Текущий режим приложения: только GitOps. Локального режима с прямой записью в domains.csv и запуском скриптов Traefik из панели нет.

Что делает панель

  1. Принимает домен (Unicode/Punycode).
  2. Делает DNS-проверки (A/AAAA, www для доменов 2-го уровня, TTL, проверка дубликатов в GitOps CSV).
  3. Создаёт PR в GitHub в profiles/<profile>/domains.csv.
  4. Показывает в UI статусы:
    • проверки PR,
    • итог PR,
    • деплой (по deploy.yml),
    • ссылку на deploy run и PR.
  5. После успешного деплоя показывает блок Готово с информацией о выпуске SSL.

Текущее поведение UI

  • Автообновление статуса PR/деплоя через JSON poll endpoint.
  • Интервал опроса:
    • ~5 сек пока PR/деплой в процессе,
    • ~60 сек после завершения.
  • Время отображается в удобном формате:
    • (GMT+3) 04.03.2026 19:23:17
    • таймзона берётся из TZ.

Архитектура проекта (этап 2)

Код в app/ переведен на слойную структуру: Action + Service + DTO.

1. Точка входа

  • app/index.php — фронт-контроллер.
  • Его задачи:
    • инициализация сессии и security headers,
    • сбор config из env,
    • создание state для UI,
    • маршрутизация POST/GET действий в Action,
    • рендер views/panel.php.

2. Слой Action (app/src/Action)

Action-классы отвечают за сценарии HTTP-запросов:

  • AuthActionlogin/logout.
  • ProfileSelectAction — переключение целевого профиля.
  • GithubPollAction — JSON endpoint ?github_pr_poll=1.
  • DomainSubmitAction — основной flow проверки домена и создания PR.

Action не содержит низкоуровневой инфраструктуры, а вызывает сервисы.

3. Слой Service (app/src/Service)

Сервисы инкапсулируют бизнес-логику:

  • AuthService
    • remember-me,
    • rate-limit,
    • авторизация/разлогин.
  • DnsValidationService
    • валидация домена,
    • DNS/WHOIS проверки,
    • формирование итогового результата проверки.
  • GitHubPrService
    • создание PR,
    • refresh snapshot,
    • поиск последнего PR по профилю,
    • преобразование данных для poll/UI.

4. Слой DTO (app/src/DTO)

DTO фиксируют структуру данных между слоями:

  • ValidationResult — результат DNS/WHOIS проверки.
  • AuthResult — результат auth-действия (нужен ли redirect).
  • GithubPrSnapshot — типизированная обертка над snapshot PR/деплоя.

5. Библиотеки в app/lib

app/lib/*.php сохраняет инфраструктурные и совместимые функции:

  • target_dns.php — DNS/WHOIS/профили,
  • auth.php — токены, rate-limit, audit log,
  • github.php — GitHub API, PR/deploy state,
  • ui_helpers.php — форматирование времени и экранирование.

Сервисы используют эти функции как низкоуровневый слой.

6. Поток основного сценария (добавление домена)

  1. POST action=domain_submit приходит в index.php.
  2. DomainSubmitAction:
    • проверяет CSRF/авторизацию,
    • вызывает DnsValidationService,
    • при успехе вызывает GitHubPrService::createPullRequest,
    • пишет audit log,
    • обновляет session snapshot.
  3. state сохраняется в flash (storePanelResultFlash) и выполняется PRG redirect.
  4. После redirect UI берет flash и показывает сообщения/статусы.

7. Поток статусов PR/деплоя

  1. JS вызывает GET /?github_pr_poll=1.
  2. GithubPollAction:
    • поднимает snapshot из сессии,
    • при force=1 может искать последний PR по профилю,
    • обновляет snapshot через GitHub API,
    • возвращает JSON (snapshot, poll_interval, deploy_success).
  3. app/assets/panel.js обновляет блок статусов без перезагрузки страницы.

8. Почему эта архитектура лучше

  • index.php стал короче и предсказуемее.
  • Логика разделена по ответственности, проще менять и тестировать.
  • Поведение UI и бизнес-правила сохранены без изменения UX.

Переменные окружения

Минимально обязательные:

  • PANEL_PASSWORD
  • GITHUB_TOKEN
  • GITHUB_REPO

Основные:

  • TARGET_PROFILE_IDS=ru,fi,kz
  • TARGET_PROFILE_DEFAULT=ru
  • TARGET_PROFILE_<ID>_NAME
  • TARGET_PROFILE_<ID>_FLAG
  • TARGET_PROFILE_<ID>_IP
  • TARGET_PROFILE_<ID>_ENABLED=1|0
  • TARGET_PROFILES_JSON (опциональный полный override)
  • AUDIT_LOG_PATH=/logs/domain-additions.log
  • AUTH_MAX_ATTEMPTS=5
  • AUTH_BLOCK_SECONDS=300
  • AUTH_ATTEMPTS_PATH=/logs/login-attempts.json
  • REMEMBER_COOKIE_NAME=panel_remember
  • REMEMBER_TOKENS_PATH=/logs/remember-tokens.json
  • REMEMBER_TTL_SECONDS=2592000
  • GITHUB_BASE_BRANCH=main
  • GITHUB_PROFILE_PATH_PREFIX=profiles
  • PANEL_UID=1000
  • PANEL_GID=1000
  • TZ=Europe/Moscow

Полный актуальный шаблон: .env.example.

Запуск

  1. Создать env:
cp .env.example .env
  1. Запустить контейнеры:
docker compose up -d --build

Traefik

В docker-compose.yml уже зашиты labels для:

  • https://ops-panel.example.com
  • TLS certresolver=letsEncrypt

GitOps workflow-файлы в этом проекте

В репозитории сейчас лежат:

  • .github/workflows/pr-validate.yml
  • .github/workflows/pr-enable-auto-merge.yml
  • .github/workflows/deploy.yml

Важно:

  • Текущие workflow ограничены профилями ru|fi|kz.
  • Если добавляете новые профили в панели (TARGET_PROFILE_IDS), обновите regex/матрицу в workflow.

Логи

./logs:

  • nginx-access.log
  • nginx-error.log
  • php-error.log
  • domain-additions.log
  • login-attempts.json
  • remember-tokens.json

Безопасность

  • Индексация отключена (X-Robots-Tag, meta robots, robots.txt).
  • CSRF для POST-действий.
  • Ограничение попыток входа по IP (файл + flock).
  • Серверный remember-me токен (без хранения пароля в браузере).
  • В Nginx включен Content-Security-Policy (CSP): разрешены только источники self для script-src, style-src, connect-src, font-src; изображения — self и data:.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages