Интеграция Zabbix + GLPI: автоматическое создание заявок

Как NexTool связывает Zabbix и GLPI, чтобы создавать заявки с ответственным, приоритетом и SLA — и автоматически закрывать их при восстановлении: webhook Media Type, карта серьёзности и идемпотентность по event_id против лавины заявок.

В этой статьеРазделов: 7

Оповещение, которое приходит только по e-mail, — это инцидент без ответственного. Интеграция Zabbix и GLPI нужна, чтобы превращать каждую обнаруженную проблему в отслеживаемую заявку — с номером, ответственным, категорией, приоритетом и SLA — и автоматически закрывать её, когда Zabbix подтверждает восстановление. Секрет не в том, чтобы «создать заявку», а в том, чтобы не создать сорок.

Что должна обеспечивать интеграция

Мост Zabbix → GLPI, выдерживающий продуктив, должен давать четыре гарантии, а не просто «отправлять заявку»:

  • Идемпотентность: одна проблема порождает одну заявку, а не по одной на каждый шаг эскалации.
  • Корреляция проблемы и восстановления: событие recovery должно найти и закрыть именно ту заявку, которую открыло.
  • Сопоставление серьёзности: серьёзность в Zabbix последовательно превращается в приоритет GLPI, а не остаётся на усмотрение каждого аналитика.
  • Достаточный контекст: хост, IP, триггер, время и сообщение в теле, чтобы аналитик мог действовать, не открывая Zabbix.

Архитектура: где webhook превращается в заявку

Zabbix срабатывает через Action; Action выполняет медиа-операцию типа Webhook; Webhook — это встроенный в Zabbix скрипт на JavaScript, который делает POST на конечную точку на стороне GLPI. На стороне GLPI мы используем приёмник модуля Automations, который проверяет подпись HMAC, применяет карту полей и создаёт (или закрывает) заявку. Мы избегаем прямого вызова REST API GLPI из Zabbix, потому что каждый вызов требовал бы пары app-token/user-token и пары initSession/killSession — при лавине оповещений это перегружает API и вдобавок исчерпывает сессии.

Артефакт: Media Type webhook в Zabbix

Параметры сопоставляют макросы события; скрипт собирает payload и обрабатывает HTTP-код. Проблема и восстановление используют один и тот же Media Type — их различает поле event_value (1 = проблема, 0 = восстановление):

// Zabbix -> Media type -> Webhook -> Parametros
// endpoint     = https://glpi.cliente.com/plugins/nextool/automations/webhook/zabbix
// event_id     = {EVENT.ID}        // estavel no par problema/recovery
// event_value  = {EVENT.VALUE}     // 1 = problema, 0 = recuperacao
// host_name    = {HOST.NAME}
// host_ip      = {HOST.IP}
// trigger_name = {TRIGGER.NAME}
// severity     = {TRIGGER.SEVERITY}
// occurred     = {EVENT.DATE} {EVENT.TIME}
// message      = {ALERT.MESSAGE}
// hmac         = {$NEXTOOL_HMAC}    // macro secreta, nunca no corpo do alerta

var p = JSON.parse(value);
var req = new HttpRequest();
req.addHeader('Content-Type: application/json');
req.addHeader('X-Nextool-Signature: ' + p.hmac);

var payload = JSON.stringify({
    event_id: p.event_id,
    recovery: p.event_value === '0',
    host:     p.host_name,
    host_ip:  p.host_ip,
    trigger:  p.trigger_name,
    severity: p.severity,
    occurred: p.occurred,
    message:  p.message
});

var resp = req.post(p.endpoint, payload);
var code = req.getStatus();
if (code < 200 || code >= 300) {
    Zabbix.log(3, '[nextool] falha HTTP ' + code + ': ' + resp);
    throw 'Envio ao GLPI falhou: HTTP ' + code;
}
return resp;

Карта серьёзности Zabbix → приоритет GLPI

В Zabbix шесть уровней серьёзности, в GLPI — пять приоритетов. Мы фиксируем карту в приёмнике, чтобы не оставлять это на усмотрение каждого аналитика:

Серьёзность ZabbixПриоритет GLPIСтановится заявкой?
Not classified / Information-Нет (только запись)
WarningНизкийДа
AverageСреднийДа
HighВысокийДа
DisasterОчень высокийДа + уведомление дежурной смены

Дедупликация и автоматическое закрытие

Именно это отличает игрушечную интеграцию от той, что выдерживает продуктив. При создании заявки приёмник записывает tickets_id GLPI как тег события в Zabbix (или в таблицу корреляции с индексом по event_id). Когда Zabbix отправляет recovery с тем же event_id, приёмник находит эту заявку и добавляет комментарий о восстановлении — или закрывает её, в зависимости от политики клиента. Без этого ключа recovery не знает, какую из заявок закрыть, и у вас копятся открытые заявки по уже решённым проблемам.

Типичные ошибки, которые мы исправляем при сопровождении

При сопровождении самый частый инцидент — не оповещение, которое не стало заявкой, а оповещение, которое стало сорока заявками. Интерфейс, «моргавший» (flapping) в 3 часа ночи, создал десятки одинаковых заявок, потому что Action срабатывал на каждом шаге эскалации, а приёмник не выполнял дедупликацию. Исправление двустороннее: в Zabbix — зависимость триггеров, гистерезис в выражении восстановления и медиа-операция только на первом шаге; в GLPI — идемпотентность по event_id. Ещё две повторяющиеся ошибки: передавать категорию заявки свободным текстом (GLPI ожидает числовой itilcategories_id — новый текст не совпадает, и заявка остаётся без категории) и помещать секрет HMAC в тело оповещения вместо защищённого макроса, такого как {$NEXTOOL_HMAC}.

Сравнение способов интеграции

СпособБез кода?Дедупликация/recoveryКогда использовать
Модуль Automations (приёмник)Да (карта через JSONPath)Встроенная, по event_idСтандарт для большинства клиентов
REST API GLPI напрямуюНетРеализуете выБез модуля; немного хостов
Внешний скрипт (Python/Bash)НетРеализуете и поддерживаете выНестандартные бизнес-правила

Если у вас уже работает Zabbix, но оповещения умирают в почтовом ящике, который никто не читает, NexTool внедрит этот мост с модулем Automations и будет поддерживать правила в актуальном состоянии в рамках сопровождения — триггеры, карту серьёзности и политику закрытия. Узнайте о модуле Automations.


Проверено командой NexTool Solutions.

Часто задаваемые вопросы

Да. Action в Zabbix выполняет Webhook (Media Type), который делает POST на приёмник модуля Automations в GLPI. Один и тот же Media Type обрабатывает проблему и восстановление: при проблеме создаёт заявку; при recovery, сопоставляя по event_id, добавляет комментарий или закрывает заявку, в зависимости от политики.

На двух уровнях. В Zabbix: зависимость триггеров, гистерезис в выражении восстановления и медиа-операция только на первом шаге эскалации. В GLPI: идемпотентность по event_id, с записью tickets_id как тега события, чтобы повторные отправки обновляли ту же заявку, а не создавали новые.

Не обязательно. С модулем Automations вы сопоставляете поля payload из Zabbix с полями GLPI через JSONPath, без кода. Прямой REST API или внешний скрипт (Python/Bash) — альтернативы, но они требуют, чтобы вы сами реализовали и поддерживали дедупликацию и обработку recovery.

В Zabbix шесть уровней серьёзности, а в GLPI пять приоритетов. Мы фиксируем карту в приёмнике: Warning становится «Низким», Average — «Средним», High — «Высоким», а Disaster — «Очень высоким» и вдобавок уведомляет дежурную смену. Not classified и Information обычно создают только запись, без заявки.

Каждый вызов REST API требует пары app-token/user-token и цикла initSession/killSession. При лавине оповещений это перегружает API и исчерпывает сессии. Приёмник модуля Automations принимает подписанный HMAC webhook на одной конечной точке, без затрат на открытие и закрытие сессии для каждого события.

Нужна помощь?