Mattermost. Интеграция с GLPI

СВК
Published

Выбирая замену, используемой у нас, системы обмена сообщениями, наткнулся на описание Mattermost, и решил попробовать. Одним из плюсов, описываемой системы, является простая интеграция со сторонними сервисами, так называемые "хуки" (outgoing и incoming hooks). Вот про настройку взаимодействия через хуки с внешними системами и будет данная статья (в нашем конкретном случае это zabbix и glpi).

Часть первая. Интеграция с GLPI

Так как мы, в своей работе, для учета оборудования, программного обеспечения, соединений, регистрации обращений в техподдержку используем GLPI, то логично было-бы организовать возможность для пользователей отправлять заявки в ТП из mattermost.

API

Для интеграции с внешними сервисами у GLPI есть http rest api. Документация по нему доступна в установленной системе по ссылке http://glpi/apirest.php/#glossary (где "glpi" адрес вашего сервера). Слегка подумав над задачей, было решено алгоритм обмена реализовать на php, в пользу данного решения говорит то факт, что php уже установлен в системе и скрипт был органично вписан в glpi и доступен по адресу http://glpi/mm.php. Получился, своего рода, "прокси", который принимает запрос от mattermost, преобразует в нужный формат и отправляет GLPI. Все http-запросы передаются в JSON-формате.

Процедура работы состоит из 5-ти частей:

  1. Получение запроса от mattermost
  2. Инициализация сессии в glpi
  3. Получение данных из запроса
  4. Отправка данных в glpi
  5. Закрытие сессии

Перед тем как приступить к описанию кода срипта, проведём подготовительную работу как в mattermost так и в glpi.

GLPI

  1. Cоздадим пользователя helpdesk, от имени которого, будут создаваться запросы, и зайдя в настройки этого пользователя сгенерируем токены: token.png Тот, что обведен красным, будет user_token.
  2. В настройках системы необходимо добавить клиента для взаимодействия с API. Для этого идём в "Настройки"->"Общие"->"API" и нажав кнопку "Добавить клиента", добавляем запись и генерируем токен (app_token)

app_token.png 3. Для идентификации источника запросов в системе, добавим запись в справочник "Источники запросов" и зайдя в, только что, добавленную запись запомним его id (обведено красным) glpi<em>tiket</em>source.png

На этом настройка АПИ в GLPI закончена.

Mattermost

В меню клиента Mattermost идём в "Inegration"->"Outgoing Webhooks" жмем "Add" и добавлем запись. На скрине я поддеркнул значимые поля. Тут следует сделать отступление: в mattermost "спусковым крючком" для запуска процедуры отправки запроса служит слово или фраза, которая, будучи указанной в начале сообщения, собственно, и запускает процесс. В нащем случае слово-тригер - "112" (тут прямая ассоциация с МЧС).

mm_outwebhooks.png

Имя пользователя по умолчанию и ссылку на аватарку можно добавить (а можно не добавлять), так как эти параметры будут переданы в запросе. Но для того, чтобы mattermost смог обрабатывать данные параметры, в настройках сервера надо поменять пару опций в файле /opt/mattermost/config/config.json

 "EnablePostUsernameOverride": true,
 "EnablePostIconOverride": true,

На этом настройка окончена. Настало время перейти к написанию кода. Скрипт скопирован в корневой каталог с файлами glpi, в моём случае это /var/www/html/glpi/mm.php

 <?php
 # GLPI токены сгенерированные в настройках
 $app_token = '7uizyyildM71x84j1UxeABXTuCHdPoLRW45Tx2wG';
 $user_app_token ='dZdCqc10Xhb1TxCT4OsXp8qqDSEqILASf2wZot0w';
 # Тип источника запроса (значение из справочника, которое запомнили чуть раньше)
 $requesttypes_id = '7';
 # Код типа запроса GLPI (1 - Инцидент, 2 - Запрос)
 $type = '1';

 # Принимает запрос и декодируем данные
 $postData = file_get_contents('php://input');
 $data = json_decode($postData, true);

 # Разбор json от MatterMost. Если эти данные нужны соответствующую строку
 # можно раскоментировать и использовать перменную ниже по коду
 #$message_text = $data["text"];
 #$user_name = $data["user_name"];
 #$user_id = $data["user_id"];
 #$channel_name = $data["channel_name"];
 #$channel_id = $data["channel_id"];
 #$team_domain = $data["team_domain"];
 #$team_id = $data["team_id"];
 #$post_id = $data["post_id"];

 # обрезаем "112" от сообщения, точнее обрезаем первые 4 символа.
 $message_text = substr($data["text"],4);

 # Ответ на POST запрос, который будет выведен пользователю в mattermost
 #HTTP/1.1 200 OK
 header('Content-Type: application/json');
 $reply = array(
    'response_type' => 'comment',
    'text'=> 'Ваш запрос передан в службу технической поддержки'
 );
 echo json_encode($reply);

 # Инициируем пользовательскую сессию в glpi
 # тут нам и понадобятся ранее сгенерированные токены
 # данный запрос вернёт идентификатор сессии для дальнейшей работы
 if( $curl = curl_init() ) {
    curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: user_token '.$user_app_token, 'App-Token: '.$app_token));
    curl_setopt($curl, CURLOPT_URL, 'http://glpi/apirest.php/initSession');
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $out = curl_exec($curl);
    $session = json_decode($out, true);
    $session_token = $session["session_token"];
    #echo $session_token;
    curl_close($curl);
 }

 # подготовим текст для запроса создания заявки
 $json = array(
    'input'=> array(
        'name'=>'Заявка от '.$data["user_name"],
        'requesttypes_id'=>$requesttypes_id,
        'content'=>$message_text,
        'type'=>$type
    )
 );

 # Отправим запрос
 if( $curl = curl_init() ) {
    curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'App-Token: '.$app_token, 'Session-token: '.$session_token));
    curl_setopt($curl, CURLOPT_URL, 'http://glpi/apirest.php/Ticket');
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($json));
    $out = curl_exec($curl);
    curl_close($curl);
 }

 # Закроем сессию
 if( $curl = curl_init() ) {
    curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'App-Token: '.$app_token, 'Session-token: '.$session_token));
    curl_setopt($curl, CURLOPT_URL, 'http://glpi/apirest.php/killSession');
    curl_setopt($curl, CURLOPT_POST, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $out = curl_exec($curl);
    curl_close($curl);
 }
 ?>

Результатом работы данного скрипта будет добавленный запрос в системе регистрации инцидентов в GLPI. В картинках это выглядит следующим образом:

Пишем сообщение в mattermost:

mm<em>tiket</em>1.png

Идём в GLPI "Поддержка"->"Заявки" и в списке должно появится новое сообщение:

glpi<em>tiket</em>1.png

Ткнув на заголовок сообщения, откроется более подробная информация (красным обведены поля, значения которых передаются в скрипте)

glpi<em>tiket</em>2.png

На этом настройку отправки сообщений в GLPI из Mattermost, можно считать завершенной. Поработав немного над кодом, ничто не помешает реализовать изменение типа запроса (инцидент или заявка).