344 lines
No EOL
11 KiB
Markdown
344 lines
No EOL
11 KiB
Markdown
# grafana_gen — Руководство пользователя
|
||
|
||
Утилита автоматически генерирует дашборды Grafana на основе данных из PostgreSQL. При каждом запуске она читает список клиентов и их ресурсов из БД, сравнивает с предыдущим состоянием и пересоздаёт единый дашборд только при наличии изменений.
|
||
|
||
---
|
||
|
||
## Как это работает
|
||
|
||
```
|
||
PostgreSQL (test_info)
|
||
↓
|
||
Список клиентов и ресурсов (SID, domain_name, aliases)
|
||
↓
|
||
Проверка изменений (state.json)
|
||
↓ нет изменений → выход
|
||
Загрузка шаблона (dashboard_template.json из Git)
|
||
↓
|
||
Генерация JSON дашборда
|
||
↓
|
||
Grafana API → создание/обновление дашборда
|
||
```
|
||
|
||
На каждый запуск создаётся **один дашборд** со всеми клиентами. Каждый клиент отображается как свёрнутая строка (collapsed row), внутри которой — панели по каждому ресурсу.
|
||
|
||
---
|
||
|
||
## Требования
|
||
|
||
- Go 1.21+
|
||
- PostgreSQL с базой `test_info`
|
||
- Grafana с API-доступом (Service Account Token или Legacy API Key)
|
||
- Git (для загрузки шаблонов)
|
||
- Доступ к Gitea-репозиторию с шаблоном
|
||
|
||
---
|
||
|
||
## Установка и запуск
|
||
|
||
### Сборка
|
||
|
||
```bash
|
||
git clone <репозиторий утилиты>
|
||
cd grafana_gen
|
||
go build -o grafana_gen .
|
||
```
|
||
|
||
### Первый запуск
|
||
|
||
```bash
|
||
./grafana_gen \
|
||
-grafana-url https://grafana.example.com \
|
||
-grafana-api-key glsa_xxxxxxxxxxxx \
|
||
-db-user waf_reader \
|
||
-db-password secret
|
||
```
|
||
|
||
### Через .env файл (рекомендуется)
|
||
|
||
Создайте файл `/etc/grafana_gen/grafana_gen.env`:
|
||
|
||
```env
|
||
GRAFANA_URL=https://grafana.example.com
|
||
GRAFANA_API_KEY=glsa_xxxxxxxxxxxx
|
||
DB_USER=waf_reader
|
||
DB_PASSWORD=secret
|
||
GIT_TOKEN=your-gitea-token
|
||
```
|
||
|
||
Затем просто:
|
||
|
||
```bash
|
||
./grafana_gen
|
||
```
|
||
|
||
---
|
||
|
||
## Конфигурация
|
||
|
||
### Способы задать параметры (в порядке приоритета)
|
||
|
||
| Приоритет | Способ | Пример |
|
||
|-----------|--------|--------|
|
||
| 1 | Флаг командной строки | `-grafana-url https://...` |
|
||
| 2 | Переменная окружения | `export GRAFANA_URL=https://...` |
|
||
| 3 | `.env` файл | `GRAFANA_URL=https://...` |
|
||
| 4 | Константа в `config.go` | `DefaultGrafanaURL = "https://..."` |
|
||
|
||
### Пути поиска .env файла
|
||
|
||
Утилита ищет `.env` файл в следующем порядке:
|
||
|
||
1. Путь из переменной `GRAFANA_GEN_ENV_FILE`
|
||
2. `/etc/grafana_gen/grafana_gen.env`
|
||
3. `./grafana_gen.env` (рядом с бинарником)
|
||
4. `./.env`
|
||
|
||
---
|
||
|
||
## Флаги командной строки
|
||
|
||
### База данных
|
||
|
||
| Флаг | Переменная окружения | По умолчанию | Описание |
|
||
|------|---------------------|--------------|----------|
|
||
| `-db-host` | — | `10.100.10.8` | Хост PostgreSQL |
|
||
| `-db-port` | — | `5432` | Порт PostgreSQL |
|
||
| `-db-user` | `DB_USER` | — | Пользователь БД (**обязательно**) |
|
||
| `-db-password` | `DB_PASSWORD` | — | Пароль БД (**обязательно**) |
|
||
| `-db-name` | — | `test_info` | Имя базы данных |
|
||
| `-use-manual` | — | `false` | Использовать таблицу `manual_info` вместо `sp_info` |
|
||
|
||
### Grafana
|
||
|
||
| Флаг | Переменная окружения | По умолчанию | Описание |
|
||
|------|---------------------|--------------|----------|
|
||
| `-grafana-url` | `GRAFANA_URL` | — | URL Grafana (**обязательно**) |
|
||
| `-grafana-api-key` | `GRAFANA_API_KEY` | — | API-ключ Grafana (**обязательно**) |
|
||
| `-grafana-folder` | `GRAFANA_FOLDER` | `WAF - Auto Generated` | Папка в Grafana для дашборда |
|
||
| `-dashboard-title` | `DASHBOARD_TITLE` | `PT AF Nodes` | Название дашборда |
|
||
|
||
### Git / шаблоны
|
||
|
||
| Флаг | Переменная окружения | По умолчанию | Описание |
|
||
|------|---------------------|--------------|----------|
|
||
| `-git-token` | `GIT_TOKEN` | — | Токен доступа к Gitea |
|
||
| `-templates-repo` | — | *(см. config.go)* | URL Git-репозитория с шаблонами |
|
||
| `-templates-branch` | — | `master` | Ветка репозитория |
|
||
| `-templates-path` | — | `/etc/grafana_gen/templates` | Локальный путь для шаблонов |
|
||
| `-skip-git-pull` | — | `false` | Не обновлять шаблоны из Git |
|
||
|
||
### Управление запуском
|
||
|
||
| Флаг | По умолчанию | Описание |
|
||
|------|--------------|----------|
|
||
| `-dry-run` | `false` | Сгенерировать JSON, но не отправлять в Grafana |
|
||
| `-force` | `false` | Принудительная регенерация даже без изменений |
|
||
| `-state-file` | `/var/lib/grafana_gen/state.json` | Путь к файлу состояния |
|
||
|
||
---
|
||
|
||
## Приоритет параметров
|
||
|
||
Пример: если одновременно задан флаг `-grafana-api-key`, переменная `GRAFANA_API_KEY` и значение в `.env` — используется **флаг командной строки** как наиболее приоритетный.
|
||
|
||
```
|
||
Флаг CLI > Переменная окружения > .env файл > константа в config.go
|
||
```
|
||
|
||
Это позволяет безопасно хранить секреты в `.env` и при необходимости переопределять их на лету без изменения файлов.
|
||
|
||
---
|
||
|
||
## State-файл
|
||
|
||
Утилита сохраняет состояние после каждого успешного запуска в JSON-файл (по умолчанию `/var/lib/grafana_gen/state.json`).
|
||
|
||
При следующем запуске сравниваются:
|
||
|
||
- Коммит шаблона в Git
|
||
- Версия шаблона (`version` в `dashboard_template.json`)
|
||
- SHA-256 хэш данных из БД (список клиентов, доменов, SID)
|
||
- Количество клиентов и доменов
|
||
|
||
Если ничего не изменилось — дашборд не пересоздаётся, утилита завершается с кодом 0.
|
||
|
||
```
|
||
=== No Changes Detected ===
|
||
No changes in templates or database since last run.
|
||
Skipping dashboard generation.
|
||
|
||
Use -force flag to regenerate anyway.
|
||
```
|
||
|
||
Если изменения есть — выводится подробный отчёт:
|
||
|
||
```
|
||
=== Changes Detected ===
|
||
Changes detected:
|
||
Template commit changed: abc12345 -> def67890
|
||
Database content changed
|
||
- New SIDs: [SID_001, SID_002]
|
||
```
|
||
|
||
---
|
||
|
||
## Режим dry-run
|
||
|
||
Позволяет проверить что будет сгенерировано без отправки в Grafana:
|
||
|
||
```bash
|
||
./grafana_gen -dry-run
|
||
```
|
||
|
||
В лог выводится превью JSON дашборда и итоговая статистика:
|
||
|
||
```
|
||
DRY RUN: Dashboard generated but not sent to Grafana
|
||
=== Summary ===
|
||
Clients: 12
|
||
Skipped: 0
|
||
```
|
||
|
||
---
|
||
|
||
## Запуск через cron
|
||
|
||
Рекомендуемый вариант — запуск каждые 15 минут:
|
||
|
||
```cron
|
||
*/15 * * * * /usr/local/bin/grafana_gen >> /var/log/grafana_gen.log 2>&1
|
||
```
|
||
|
||
Утилита сама определяет нужно ли обновлять дашборд — частые запуски без изменений завершаются мгновенно.
|
||
|
||
### Systemd timer (альтернатива)
|
||
|
||
`/etc/systemd/system/grafana-gen.service`:
|
||
```ini
|
||
[Unit]
|
||
Description=Grafana Dashboard Generator
|
||
After=network.target postgresql.service
|
||
|
||
[Service]
|
||
Type=oneshot
|
||
EnvironmentFile=/etc/grafana_gen/grafana_gen.env
|
||
ExecStart=/usr/local/bin/grafana_gen
|
||
StandardOutput=journal
|
||
StandardError=journal
|
||
```
|
||
|
||
`/etc/systemd/system/grafana-gen.timer`:
|
||
```ini
|
||
[Unit]
|
||
Description=Run grafana-gen every 15 minutes
|
||
|
||
[Timer]
|
||
OnBootSec=2min
|
||
OnUnitActiveSec=15min
|
||
|
||
[Install]
|
||
WantedBy=timers.target
|
||
```
|
||
|
||
```bash
|
||
systemctl enable --now grafana-gen.timer
|
||
```
|
||
|
||
---
|
||
|
||
## Типичные сценарии
|
||
|
||
### Первое развёртывание
|
||
|
||
```bash
|
||
# 1. Создать .env
|
||
cp grafana_gen.env.example /etc/grafana_gen/grafana_gen.env
|
||
vim /etc/grafana_gen/grafana_gen.env
|
||
|
||
# 2. Проверить без отправки
|
||
./grafana_gen -dry-run
|
||
|
||
# 3. Создать дашборд
|
||
./grafana_gen
|
||
```
|
||
|
||
### Принудительное обновление после изменения шаблона
|
||
|
||
```bash
|
||
./grafana_gen -force
|
||
```
|
||
|
||
### Переключение на резервную БД
|
||
|
||
```bash
|
||
./grafana_gen -db-host 10.10.10.5
|
||
```
|
||
|
||
### Тестирование с другим шаблоном
|
||
|
||
```bash
|
||
./grafana_gen \
|
||
-templates-path /tmp/my-templates \
|
||
-skip-git-pull \
|
||
-dry-run
|
||
```
|
||
|
||
### Использование таблицы ручного ввода
|
||
|
||
```bash
|
||
./grafana_gen -use-manual
|
||
```
|
||
|
||
---
|
||
|
||
## Структура БД
|
||
|
||
Утилита читает данные из двух таблиц базы `test_info`.
|
||
|
||
### Таблица `sp_info` (основная)
|
||
|
||
| Колонка | Тип | Описание |
|
||
|---------|-----|----------|
|
||
| `sid` | text | Идентификатор ресурса |
|
||
| `domain_name` | text | Доменное имя |
|
||
| `aliases` | jsonb | JSON-массив дополнительных доменов |
|
||
|
||
### Таблица `apps_settings` (справочник клиентов)
|
||
|
||
| Колонка | Тип | Описание |
|
||
|---------|-----|----------|
|
||
| `l7resourceid` | text | SID ресурса (связь с `sp_info.sid`) |
|
||
| `client_title` | text | Название клиента |
|
||
|
||
Если `client_title` не найден — клиент группируется под именем `Unknown`.
|
||
|
||
Таблица `manual_info` имеет ту же структуру, что и `sp_info`, и используется при флаге `-use-manual` для ручного управления данными без изменения основной таблицы.
|
||
|
||
---
|
||
|
||
## Файловая система
|
||
|
||
```
|
||
/etc/grafana_gen/
|
||
├── grafana_gen.env # Конфигурация (секреты)
|
||
└── templates/ # Клонированный Git-репозиторий с шаблонами
|
||
└── dashboard_template.json
|
||
|
||
/var/lib/grafana_gen/
|
||
└── state.json # Состояние последнего запуска
|
||
|
||
/usr/local/bin/
|
||
└── grafana_gen # Бинарник утилиты
|
||
```
|
||
|
||
### Права доступа
|
||
|
||
```bash
|
||
# Директории
|
||
install -d -m 755 /etc/grafana_gen
|
||
install -d -m 755 /var/lib/grafana_gen
|
||
|
||
# .env файл — только для владельца процесса
|
||
chmod 600 /etc/grafana_gen/grafana_gen.env
|
||
``` |