Initial commit: Message Gateway project
- FastAPI приложение для отправки мониторинговых алертов в мессенджеры - Поддержка Telegram и MAX/VK - Интеграция с Grafana, Zabbix, AlertManager - Автоматическое создание тикетов в Jira - Управление группами мессенджеров через API - Декораторы для авторизации и скрытия эндпоинтов - Подробная документация в папке docs/ Автор: Сергей Антропов Сайт: https://devops.org.ru
This commit is contained in:
105
docs/api/debug.md
Normal file
105
docs/api/debug.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# API для отладки
|
||||
|
||||
**Важно:** Эндпоинт `/api/v1/debug/dump` скрыт из Swagger UI для безопасности, но остается доступным для прямых запросов. Используйте его только для отладки.
|
||||
|
||||
## Сохранение JSON данных для отладки
|
||||
|
||||
```bash
|
||||
POST /api/v1/debug/dump
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"test": "data",
|
||||
"timestamp": "2024-01-01T00:00:00Z",
|
||||
"source": "grafana",
|
||||
"alert": {
|
||||
"title": "Test alert",
|
||||
"state": "alerting"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Данные сохранены в dump.json",
|
||||
"data": {
|
||||
"test": "data",
|
||||
"timestamp": "2024-01-01T00:00:00Z",
|
||||
"source": "grafana",
|
||||
"alert": {
|
||||
"title": "Test alert",
|
||||
"state": "alerting"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Примечания
|
||||
|
||||
- Используется для отладки входящих webhook запросов
|
||||
- Данные сохраняются в файл `/app/app/dump.json` в контейнере
|
||||
- Файл можно просмотреть через `make shell` или `make docker shell`
|
||||
- Полезно для анализа формата данных от различных источников
|
||||
- **Эндпоинт скрыт из Swagger UI** с помощью декоратора `@hide_from_api` для безопасности
|
||||
- Эндпоинт не требует авторизации (API ключ не нужен)
|
||||
- Используется только для внутренней отладки
|
||||
|
||||
## Примеры использования
|
||||
|
||||
### Сохранение данных из Grafana
|
||||
|
||||
```bash
|
||||
curl -X POST "http://your-gateway-url/api/v1/debug/dump" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"source": "grafana",
|
||||
"alert": {
|
||||
"title": "Test alert",
|
||||
"state": "alerting"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Сохранение данных из Zabbix
|
||||
|
||||
```bash
|
||||
curl -X POST "http://your-gateway-url/api/v1/debug/dump" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"source": "zabbix",
|
||||
"event": {
|
||||
"event-id": "8819711",
|
||||
"event-name": "High CPU utilization",
|
||||
"status": "PROBLEM"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Сохранение данных из AlertManager
|
||||
|
||||
```bash
|
||||
curl -X POST "http://your-gateway-url/api/v1/debug/dump" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"source": "alertmanager",
|
||||
"status": "firing",
|
||||
"commonLabels": {
|
||||
"alertname": "HighCPUUsage",
|
||||
"severity": "critical"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## Просмотр сохраненных данных
|
||||
|
||||
```bash
|
||||
# Через make shell
|
||||
make shell
|
||||
cat /app/app/dump.json
|
||||
|
||||
# Или напрямую через docker
|
||||
docker exec -it message-gateway cat /app/app/dump.json
|
||||
```
|
||||
|
||||
128
docs/api/decorators.md
Normal file
128
docs/api/decorators.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Декораторы API
|
||||
|
||||
В проекте Message Gateway используются декораторы для упрощения работы с API и обеспечения безопасности.
|
||||
|
||||
## Декораторы
|
||||
|
||||
### `@require_api_key`
|
||||
|
||||
Декоратор для пометки эндпоинта как требующего API ключ для авторизации.
|
||||
|
||||
**Использование:**
|
||||
```python
|
||||
from app.core.auth import require_api_key, require_api_key_dependency
|
||||
|
||||
@require_api_key
|
||||
@router.post("/endpoint", dependencies=[require_api_key_dependency])
|
||||
async def my_endpoint(request: Request, ...):
|
||||
...
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Декоратор используется только для пометки функции
|
||||
- Фактическая проверка API ключа выполняется через `dependencies=[require_api_key_dependency]`
|
||||
- Это обеспечивает отображение замочка в Swagger UI
|
||||
- API ключ настраивается в переменной окружения `API_KEY` в файле `.env`
|
||||
- API ключ передается в заголовке `X-API-Key`
|
||||
|
||||
**Пример:**
|
||||
```python
|
||||
from app.core.auth import require_api_key, require_api_key_dependency
|
||||
from fastapi import APIRouter, Request, Body
|
||||
|
||||
router = APIRouter(prefix="/api/v1/groups", tags=["groups"])
|
||||
|
||||
@require_api_key
|
||||
@router.post(
|
||||
"",
|
||||
name="Создать группу",
|
||||
dependencies=[require_api_key_dependency]
|
||||
)
|
||||
async def create_group(
|
||||
request: Request,
|
||||
body: CreateGroupRequest = Body(...)
|
||||
) -> Dict[str, Any]:
|
||||
...
|
||||
```
|
||||
|
||||
### `@hide_from_api`
|
||||
|
||||
Декоратор для скрытия эндпоинта из API документации (Swagger UI).
|
||||
|
||||
**Использование:**
|
||||
```python
|
||||
from app.core.auth import hide_from_api
|
||||
|
||||
@hide_from_api
|
||||
@router.post("/debug/dump", include_in_schema=False)
|
||||
async def debug_endpoint(...):
|
||||
...
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Декоратор помечает функцию как скрытую от API
|
||||
- Эндпоинт все еще будет работать, но не будет отображаться в Swagger UI
|
||||
- Рекомендуется использовать вместе с параметром `include_in_schema=False` в декораторе route для надежного скрытия
|
||||
- Используется для скрытия внутренних эндпоинтов от публичной документации
|
||||
- Полезно для отладочных эндпоинтов и административных функций
|
||||
|
||||
**Пример:**
|
||||
```python
|
||||
from app.core.auth import hide_from_api
|
||||
from fastapi import APIRouter, Body
|
||||
|
||||
router = APIRouter(prefix="/api/v1/debug", tags=["debug"])
|
||||
|
||||
@hide_from_api
|
||||
@router.post(
|
||||
"/dump",
|
||||
name="JSON Debug dump",
|
||||
include_in_schema=False, # Скрываем эндпоинт из Swagger UI
|
||||
response_model=Dict[str, Any]
|
||||
)
|
||||
async def dump_request(
|
||||
dump: Dict[str, Any] = Body(...)
|
||||
) -> Dict[str, Any]:
|
||||
...
|
||||
```
|
||||
|
||||
## Комбинирование декораторов
|
||||
|
||||
Декораторы можно комбинировать для более сложных сценариев:
|
||||
|
||||
```python
|
||||
from app.core.auth import require_api_key, require_api_key_dependency, hide_from_api
|
||||
|
||||
@require_api_key
|
||||
@hide_from_api
|
||||
@router.post(
|
||||
"/internal/admin",
|
||||
dependencies=[require_api_key_dependency],
|
||||
include_in_schema=False
|
||||
)
|
||||
async def internal_admin_endpoint(request: Request, ...):
|
||||
...
|
||||
```
|
||||
|
||||
В этом примере:
|
||||
- Эндпоинт требует API ключ для доступа
|
||||
- Эндпоинт скрыт из Swagger UI
|
||||
- Эндпоинт доступен только для администраторов с правильным API ключом
|
||||
|
||||
## Примечания
|
||||
|
||||
- Декораторы применяются снизу вверх (от функции к верхнему декоратору)
|
||||
- Порядок декораторов важен: сначала применяется декоратор route (`@router.post`), затем декораторы авторизации и скрытия
|
||||
- Декораторы не изменяют функциональность эндпоинта, они только добавляют метаданные или проверки
|
||||
- Все декораторы определены в модуле `app.core.auth`
|
||||
|
||||
## Дополнительная информация
|
||||
|
||||
- Подробная документация по API ключам: см. [API для управления группами](groups.md)
|
||||
- Подробная документация по отладочным эндпоинтам: см. [API для отладки](debug.md)
|
||||
|
||||
---
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
|
||||
164
docs/api/groups.md
Normal file
164
docs/api/groups.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# API для управления группами
|
||||
|
||||
## Получение списка поддерживаемых мессенджеров
|
||||
|
||||
```bash
|
||||
GET /api/v1/groups/messengers
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"messengers": [
|
||||
{
|
||||
"type": "telegram",
|
||||
"name": "Telegram",
|
||||
"supports_threads": true,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"type": "max",
|
||||
"name": "MAX/VK",
|
||||
"supports_threads": false,
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Получение списка групп
|
||||
|
||||
```bash
|
||||
# Без API ключа (только названия)
|
||||
GET /api/v1/groups
|
||||
|
||||
# С API ключом (полная информация)
|
||||
GET /api/v1/groups
|
||||
Headers: X-API-Key: your_api_key_here
|
||||
```
|
||||
|
||||
**Пример ответа (без API ключа):**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"groups": [
|
||||
{"name": "monitoring", "chat_id": null},
|
||||
{"name": "alerts", "chat_id": null}
|
||||
],
|
||||
"count": 2
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа (с API ключом):**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"groups": [
|
||||
{
|
||||
"name": "monitoring",
|
||||
"messenger": "telegram",
|
||||
"chat_id": -1001234567890,
|
||||
"thread_id": 0
|
||||
},
|
||||
{
|
||||
"name": "alerts_max",
|
||||
"messenger": "max",
|
||||
"chat_id": "123456789",
|
||||
"thread_id": null
|
||||
}
|
||||
],
|
||||
"count": 2
|
||||
}
|
||||
```
|
||||
|
||||
## Создание группы
|
||||
|
||||
```bash
|
||||
POST /api/v1/groups
|
||||
Headers:
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"group_name": "monitoring",
|
||||
"messenger": "telegram",
|
||||
"chat_id": -1001234567890,
|
||||
"thread_id": 0
|
||||
}
|
||||
```
|
||||
|
||||
**Пример запроса для MAX/VK:**
|
||||
```bash
|
||||
POST /api/v1/groups
|
||||
Headers:
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"group_name": "max_alerts",
|
||||
"messenger": "max",
|
||||
"chat_id": "123456789",
|
||||
"thread_id": 0,
|
||||
"config": {
|
||||
"access_token": "your_max_access_token"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Группа 'monitoring' создана с мессенджером 'telegram' и ID -1001234567890"
|
||||
}
|
||||
```
|
||||
|
||||
## Обновление группы
|
||||
|
||||
```bash
|
||||
PUT /api/v1/groups/{group_name}
|
||||
Headers:
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"messenger": "telegram",
|
||||
"chat_id": -1001234567891,
|
||||
"thread_id": 0
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Группа 'monitoring' обновлена"
|
||||
}
|
||||
```
|
||||
|
||||
## Удаление группы
|
||||
|
||||
```bash
|
||||
DELETE /api/v1/groups/{group_name}
|
||||
Headers: X-API-Key: your_api_key_here
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Группа 'monitoring' удалена"
|
||||
}
|
||||
```
|
||||
|
||||
## Примечания
|
||||
|
||||
- Требуется API ключ в заголовке X-API-Key для всех операций, кроме получения списка групп (без API ключа возвращаются только названия)
|
||||
- Группы сохраняются в `config/groups.json`
|
||||
- Chat ID можно получить, добавив бота в группу и отправив сообщение
|
||||
- Используйте `@userinfobot` в Telegram для получения Chat ID группы
|
||||
- Для MAX/VK используйте peer_id (может быть строкой или числом)
|
||||
- Thread ID поддерживается только для Telegram (для MAX/VK игнорируется)
|
||||
- Дополнительная конфигурация (config) может содержать параметры для конкретного мессенджера (например, access_token для MAX/VK)
|
||||
|
||||
63
docs/api/health.md
Normal file
63
docs/api/health.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# API для проверки здоровья
|
||||
|
||||
## Проверка здоровья и готовности приложения
|
||||
|
||||
```bash
|
||||
GET /api/v1/health
|
||||
```
|
||||
|
||||
**Пример ответа (здорово):**
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"state": "online",
|
||||
"telegram_bot_configured": true,
|
||||
"groups_config_available": true
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа (не готово):**
|
||||
```json
|
||||
{
|
||||
"status": "not_ready",
|
||||
"state": "online",
|
||||
"checks": {
|
||||
"telegram_bot_configured": false,
|
||||
"groups_config_available": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Примечания
|
||||
|
||||
- Не требует аутентификации
|
||||
- Возвращает 503 если приложение не готово
|
||||
- Используется Kubernetes для liveness и readiness probes
|
||||
- Настройте liveness и readiness probes в kubernetes.yaml
|
||||
- Приложение считается готовым, если все проверки пройдены
|
||||
|
||||
## Проверки
|
||||
|
||||
- `telegram_bot_configured` - наличие токена Telegram (TELEGRAM_BOT_TOKEN)
|
||||
- `groups_config_available` - доступность файла конфигурации групп (config/groups.json)
|
||||
|
||||
## Использование в Kubernetes
|
||||
|
||||
Настройте liveness и readiness probes в `kubernetes.yaml`:
|
||||
|
||||
```yaml
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: 8000
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: 8000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
```
|
||||
|
||||
188
docs/api/message.md
Normal file
188
docs/api/message.md
Normal file
@@ -0,0 +1,188 @@
|
||||
# API для отправки сообщений
|
||||
|
||||
**Важно:** Все эндпоинты для отправки сообщений требуют API ключ в заголовке `X-API-Key`.
|
||||
|
||||
## Аутентификация
|
||||
|
||||
Все эндпоинты требуют API ключ в заголовке запроса:
|
||||
|
||||
```bash
|
||||
X-API-Key: your_api_key_here
|
||||
```
|
||||
|
||||
API ключ настраивается в переменной окружения `API_KEY` в файле `.env`.
|
||||
|
||||
## Отправка текстового сообщения
|
||||
|
||||
```bash
|
||||
POST /api/v1/message/text
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"tg_group": "monitoring",
|
||||
"tg_thread_id": 0,
|
||||
"text": "<b>Критическое уведомление</b>\n\nСистема недоступна!\n\n<i>Время: 2024-02-08 16:49:44</i>",
|
||||
"parse_mode": "HTML",
|
||||
"disable_web_page_preview": false
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Сообщение отправлено в чат monitoring, тред 0"
|
||||
}
|
||||
```
|
||||
|
||||
**Поддерживаемые режимы парсинга:**
|
||||
- `HTML` - HTML форматирование (рекомендуется)
|
||||
- `Markdown` - Markdown форматирование
|
||||
- `MarkdownV2` - Markdown V2 форматирование
|
||||
|
||||
**Примеры форматирования:**
|
||||
- HTML: `<b>жирный</b>`, `<i>курсив</i>`, `<code>код</code>`
|
||||
- Markdown: `**жирный**`, `*курсив*`, `` `код` ``
|
||||
|
||||
## Отправка фото
|
||||
|
||||
```bash
|
||||
POST /api/v1/message/photo
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"tg_group": "monitoring",
|
||||
"tg_thread_id": 0,
|
||||
"photo": "https://grafana.example.com/render/dashboard-solo?panelId=1&width=1000&height=500",
|
||||
"caption": "<b>График CPU</b>\n\n<i>Время: 2024-02-08 16:49:44</i>",
|
||||
"parse_mode": "HTML"
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Фото отправлено в чат monitoring, тред 0"
|
||||
}
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Фото может быть передано через URL (автоматически загрузится) или как файл
|
||||
- Поддерживаются форматы: JPG, PNG, GIF, WebP
|
||||
- Максимальный размер файла: 10 МБ (Telegram), зависит от мессенджера
|
||||
- Для отправки графиков из Grafana используйте URL рендеринга дашбордов
|
||||
|
||||
## Отправка видео
|
||||
|
||||
```bash
|
||||
POST /api/v1/message/video
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"tg_group": "monitoring",
|
||||
"tg_thread_id": 0,
|
||||
"video": "https://example.com/recording.webm",
|
||||
"caption": "<b>Запись работы системы</b>\n\n<i>Длительность: 60 сек</i>",
|
||||
"parse_mode": "HTML",
|
||||
"duration": 60,
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Видео отправлено в чат monitoring, тред 0"
|
||||
}
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Видео может быть передано через URL (автоматически загрузится) или как файл
|
||||
- Поддерживаются форматы: MP4, WebM, MOV (зависит от мессенджера)
|
||||
- Максимальный размер файла: 50 МБ (Telegram), зависит от мессенджера
|
||||
- Длительность, ширина и высота опциональны, но рекомендуются для лучшего отображения
|
||||
|
||||
## Отправка аудио
|
||||
|
||||
```bash
|
||||
POST /api/v1/message/audio
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"tg_group": "monitoring",
|
||||
"tg_thread_id": 0,
|
||||
"audio": "https://example.com/notification.ogg",
|
||||
"caption": "<b>Аудио уведомление</b>\n\n<i>Система работает нормально</i>",
|
||||
"parse_mode": "HTML",
|
||||
"duration": 30,
|
||||
"performer": "System Notification",
|
||||
"title": "Alert Notification"
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Аудио отправлено в чат monitoring, тред 0"
|
||||
}
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Аудио может быть передано через URL (автоматически загрузится) или как файл
|
||||
- Поддерживаются форматы: MP3, OGG, WAV, M4A (зависит от мессенджера)
|
||||
- Максимальный размер файла: 50 МБ (Telegram), зависит от мессенджера
|
||||
- Исполнитель и название опциональны, но улучшают отображение в Telegram
|
||||
|
||||
## Отправка документа
|
||||
|
||||
```bash
|
||||
POST /api/v1/message/document
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"tg_group": "monitoring",
|
||||
"tg_thread_id": 0,
|
||||
"document": "https://example.com/report.xlsx",
|
||||
"caption": "<b>Отчет за неделю</b>\n\n<i>Дата: 2024-02-08</i>",
|
||||
"parse_mode": "HTML",
|
||||
"filename": "report_2024-02-08.xlsx"
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Документ отправлен в чат monitoring, тред 0"
|
||||
}
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Документ может быть передан через URL (автоматически загрузится) или как файл
|
||||
- Поддерживаются все форматы файлов (PDF, DOCX, XLSX, TXT, и т.д.)
|
||||
- Максимальный размер файла: 50 МБ (Telegram), зависит от мессенджера
|
||||
- Имя файла опционально, если не указано - используется имя из URL
|
||||
- Для отправки отчетов используйте прямые ссылки на файлы
|
||||
|
||||
## Параметры запроса
|
||||
|
||||
Все endpoints поддерживают параметр `messenger` (опционально):
|
||||
- `?messenger=telegram` - использовать Telegram
|
||||
- `?messenger=max` - использовать MAX/VK
|
||||
- Если не указан, используется мессенджер из конфигурации группы
|
||||
|
||||
## Общие параметры
|
||||
|
||||
- `tg_group` - имя группы из конфигурации (config/groups.json)
|
||||
- `tg_thread_id` - ID треда в группе (0 для основной группы, поддерживается только для Telegram)
|
||||
- `messenger` - тип мессенджера (опционально, `telegram`, `max`, по умолчанию используется из конфигурации группы)
|
||||
|
||||
Reference in New Issue
Block a user