# 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 ```