Files
ss-tools/examples/maintenance

Maintenance API — примеры интеграции

Примеры внешних вызовов API обслуживания (баннеры «ведутся технические работы» на дашбордах Superset) из скриптов: CI/CD, cron, Airflow DAG, ad-hoc отладка.

Содержимое

Файл Назначение
maintenance-api-bash.sh Пример на bash (curl) — для shell-окружений без Python
maintenance-api-python.py Пример на Python (requests) — для ETL-пайплайнов

Возможности

  • start — создать событие обслуживания для таблиц (1..100) с окном начала/окончания, сообщением баннера и опциональным авто-завершением (--auto-end / auto_end=true); environment_id опционален — если его не указать, старт выполняется во ВСЕХ PROD-окружениях (fan-out, batch-ответ);
  • end — завершить конкретное событие (снять баннеры);
  • end-all — аварийно завершить ВСЕ активные события в окружении.

API — кратко

  • Базовый URL: {BASE_URL}/api/maintenance
  • Аутентификация: заголовок X-API-Key: <API_KEY> (или JWT)
  • Разрешения ключа: maintenance:start, maintenance:end, maintenance:end_all
  • Все мутационные эндпоинты возвращают HTTP 202 и task_id — операция выполняется асинхронно через TaskManager.
  • Ответы — сырые тела схем (без обёртки), например: { "task_id": "...", "maintenance_id": "...", "status": "pending" }.

Эндпоинты

Метод Путь Разрешение Описание
POST /api/maintenance/start maintenance:start Создать событие (202)
POST /api/maintenance/{id}/end maintenance:end Завершить событие (202)
POST /api/maintenance/end-all maintenance:end_all Завершить все (202)
GET /api/maintenance/events maintenance READ Активные/завершённые события
GET /api/maintenance/events/{id}/dashboards maintenance READ Дашборды события (для завершённых — полная история)
GET /api/maintenance/dashboard-banners maintenance READ Баннеры по дашбордам
POST /api/maintenance/preview-dashboards maintenance READ Какие дашборды затронуты
GET/PUT /api/maintenance/settings READ / admin Настройки обслуживания

Параметры start

{
  "tables": ["public.messages", "public.users"],
  "start_time": "2026-08-10T08:00:00Z",
  "end_time": "2026-08-10T12:00:00Z",
  "environment_id": "ss-dev",
  "auto_end": false,
  "message": "Плановое обновление данных"
}
  • tables — обязателен (1..100); start_time — обязателен.

  • environment_id — опционален. Если указан — старт в одном окружении (одиночный ответ {task_id, maintenance_id, status}). Если опущен — fan-out: обслуживание стартует во ВСЕХ PROD-окружениях, ответ 202 приходит в batch-форме:

    {
      "status": "pending",
      "events": [
        {
          "environment_id": "ss-prod-a",
          "task_id": "task-123",
          "maintenance_id": "event-123",
          "status": "pending"
        },
        {
          "environment_id": "ss-prod-b",
          "task_id": "task-456",
          "maintenance_id": "event-456",
          "status": "pending"
        }
      ]
    }
    
  • auto_end — по умолчанию false; если true и задан end_time, планировщик сам завершит обслуживание ровно в end_time. Без auto_end событие останется активным до ручного завершения командой end.

  • Ошибки: 400 (невалидные данные, end_time <= start_time, >100 таблиц), 401, 403, 404 (неизвестное окружение при явном environment_id), 422 (environment_id опущен, но PROD-окружения не сконфигурированы — fan-out стартовать негде), 409 — идемпотентность (status: "already_active" — такое же окно уже активно).

  • Идемпотентность скоупится по environment_id: 409 возвращается только для явного одиночного старта; в batch-режиме (fan-out) повтор по конкретному окружению отражается как status: "already_active" в соответствующем элементе events[] внутри ответа 202 — без 409.

  • end идемпотентен: повторное завершение уже завершённого события даёт 202 с status: "already_completed" (считается успехом).

Настройки (PUT /settings, admin)

Тело PUT /api/maintenance/settings — все поля опциональны (частичное обновление):

  • target_environment_id — окружение по умолчанию;
  • display_timezone — таймзона отображения;
  • date_format — формат дат;
  • banner_template — шаблон баннера;
  • default_message — сообщение по умолчанию (макс. 500 симв.);
  • banner_height — высота баннера (1..200);
  • dashboard_scope — область дашбордов;
  • excluded_dashboard_ids — исключённые дашборды ([int]);
  • forced_dashboard_ids — принудительно затронутые дашборды ([int]).

Использование

Требования

  • bash: curl, желательно jq (форматирование ответов; без него вывод остаётся сырым JSON).
  • python: Python 3.10+, requests (pip install requests).

Подготовка

  1. Создайте API-ключ в superset-tools с разрешениями maintenance:start / maintenance:end / maintenance:end_all.
  2. Задайте переменные окружения (bash) или флаги --base-url / --api-key (python).

Bash

export SS_TOOLS_URL=http://localhost:8000
export SS_TOOLS_API_KEY=ssk_ваш_ключ

# Обслуживание на 4 часа (без авто-завершения)
./maintenance-api-bash.sh start public.messages 4 ss-dev

# Fan-out: без environment — старт во ВСЕХ PROD-окружениях (batch-ответ)
./maintenance-api-bash.sh start public.messages 4

# Несколько таблиц, сообщение, автоснятие баннера через 4 часа
./maintenance-api-bash.sh start public.messages,public.users 4 ss-prod \
    "Плановый ETL" --auto-end

# Завершить конкретное событие
./maintenance-api-bash.sh end m-abc123

# Аварийно снять ВСЕ баннеры в окружении ss-dev
./maintenance-api-bash.sh end-all ss-dev

Выходные коды: 0 — успех; 1 — ошибка (данные, права, ключ, недоступность сервера). end-all в интерактивном режиме запрашивает подтверждение; в неинтерактивных окружениях (cron/CI) подтверждение пропускается.

Python

# Старт (аргументы можно указывать и после подкоманды)
python maintenance-api-python.py start \
    --api-key ssk_ваш_ключ \
    --base-url https://superset-tools.example.com \
    --tables public.messages,public.users \
    --environment ss-dev --duration-hours 4 \
    --message "Плановый ETL" --auto-end

# Fan-out: без --environment — старт во ВСЕХ PROD-окружениях (batch-ответ)
python maintenance-api-python.py start \
    --api-key ssk_ваш_ключ \
    --base-url https://superset-tools.example.com \
    --tables public.messages --duration-hours 4

# Завершить конкретное событие
python maintenance-api-python.py end \
    --api-key ssk_ваш_ключ \
    --base-url https://superset-tools.example.com \
    --event-id m-abc123

# Аварийно завершить всё в окружении
python maintenance-api-python.py end-all \
    --api-key ssk_ваш_ключ \
    --base-url https://superset-tools.example.com \
    --environment ss-dev

Функции start_maintenance / end_maintenance / end_all_maintenance можно импортировать напрямую в свой ETL-пайплайн.

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

  • Не передавайте API-ключ аргументами командной строки (попадает в историю shell/ps) — используйте переменные окружения или защищённые секреты (CI/CD secrets, vault).
  • Ключ с ограниченным окружением может работать только с этим окружением — выберите правильный environment_id.
  • end-all снимает баннеры со всех дашбордов — применяйте только в аварийных сценариях.

Примеры автоматизации

  • cron (снятие баннера ровно в конце окна через auto_end не нужно — планировщик сам завершит; end пригодится для досрочного завершения).
  • CI/CD pipeline: после деплоя ETL — start; по завершении джобы — end.
  • Airflow DAG: Python-функции из maintenance-api-python.py в PythonOperator либо BashOperator со скриптом.