20. Модули

Обзор

Можно улучшить функциональность веб-интерфейса Zabbix, добавив сторонние модули или разработав собственные модули без необходимости изменения исходного кода Zabbix.

Обратите внимание, что код модуля будет работать с теми же привилегиями, что и исходный код Zabbix. Это означает, что:

  • сторонние модули могут быть вредными. Вы должны доверять модулям, которые вы устанавливаете;
  • ошибки в коде стороннего модуля могут привести к сбою интерфейса. Если это произойдёт, просто удалите код модуля из веб-интерфейса. Как только вы перезагрузите веб-интерфейс Zabbix, вы увидите уведомление о том, что некоторые модули отсутствуют. Перейдите к Администрирование модулей (в разделе АдминистрированиеОбщиеМодули) и нажмите Сканировать директорию, чтобы удалить несуществующие модули из базы данных.

Установка

Пожалуйста, всегда читайте руководство по установке для конкретного модуля. Рекомендуется устанавливать новые модули по одному, чтобы легко обнаруживать сбои.

Непосредственно перед установкой модуля:

  • Убедитесь, что вы загрузили модуль из надёжного источника. Установка вредоносного кода может привести к таким последствиям, как потеря данных
  • Различные версии одного и того же модуля (с тем же идентификатором) могут быть установлены параллельно, но одновременно может быть активирована только одна версия

Шаги по установке модуля:

  • Распакуйте модуль в отдельную папку в папке modules веб-интерфейса Zabbix;
  • Убедитесь, что папка устанавливаемого модуля содержит как минимум файл manifest.json;
  • Перейдите к администрированию модулей и нажмите кнопку Сканировать директорию ;
  • Новый модуль появится в списке вместе с описанием, статусом и информацией о версии и авторе модуля;
  • Активируйте модуль, нажав на его статус.

Разрешение проблем:

Проблема Решение
Модуль не появился в списке Убедитесь, что файл manifest.json присутствует в папке modules/ваш-модуль/ веб-интерфейса Zabbix. Если это так, значит, модуль не соответствует текущей версии Zabbix. Если файл manifest.json не существует, возможно, вы распаковали его не в ту папку.
Веб-интерфейс не запускается Код модуля не совместим с текущей версией Zabbix или конфигурацией сервера. Пожалуйста, удалите файлы модуля и перезагрузите интерфейс. Вы увидите уведомление, что некоторые модули отсутствуют. Перейдите к администрированию модулей и нажмите Сканировать директорию снова, чтобы удалить несуществующие модули из базы данных.
Появляются сообщения об идентичном пространстве имен, ID или действии Новый модуль попытался зарегистрировать пространство имен, ID или действия, которые уже зарегистрированы другим активированным модулем. Деактивируйте конфликтующий модуль (упомянутый в сообщении об ошибке) перед активацией нового.
Появляются технические сообщения об ошибке Сообщите об ошибках разработчику модуля.

Разработка модулей

Модули написаны на языке PHP. Предпочтительнее использовать шаблон проектрования Model-View-Controller (MVC, «Модель-Представление-Контроллер»), так как он также используется в веб-интерфейсе Zabbix и облегчит разработку. Строгая типизация PHP также приветствуется, но не обязательна.

Обратите внимание, что с модулями вы можете легко добавлять новые пункты меню и соответствующие представления и действия в веб-интерфейс Zabbix. В настоящее время невозможно зарегистрировать новый API или создать новые таблицы базы данных с помощью модулей.

Структура модуля

Каждый модуль представляет собой папку (помещённую в папку modules) с вложенными папками, содержащими контроллеры, представления и любой другой код:

example_module_directory/           (required)
           manifest.json                   (required)  Metadata and action definition.
           Module.php                                  Module initialization and event handling.
           actions/                                    Action controller files.
               SomethingView.php
               SomethingCreate.php
               SomethingDelete.php
               data_export/                                 
                   ExportAsXml.php
                   ExportAsExcel.php
           views/                                      View files.
               example.something.view.php
               example.something.delete.php
               js/                                     JavaScript files used in views.
                   example.something.view.js.php
           partials/                                   View partial files.
               example.something.reusable.php
               js/                                     JavaScript files used in partials.
                   example.something.reusable.js.php

Как видите, единственным обязательным файлом в директории пользовательских модулей является manifest.json. Модуль не будет регистрироваться без этого файла. Module.php отвечает за регистрацию пунктов меню и обработку событий, таких как «onBeforeAction» и «onTerminate». Директории actions (действия), views (представления) и partials (составляющие) содержат код PHP и JavaScript, необходимый для действий модуля.

Соглашение об именах

Прежде чем создавать модуль, важно придти к соглашению об именах для различных элементов модуля, таких как папки и файлы, чтобы мы могли придерживаться организованной структуры. Вы также можете найти примеры выше, в разделе Структура модуля.

Элемент Правила именования Пример
Папка модуля Строчные буквы [a-z], нижнее подчёркивание и десятичные цифры example_v2
Папки действий Строчные буквы [a-z] и нижнее подчёркивание data_export
Файлы действий CamelCase, заканчивающийся типом действия SomethingView.php
Файлы представлений и составляющих Строчные буквы [a-z]
Слова, разделённые точкой
С префиксом module., за которым следует имя модуля
Оканчивается типом действия и расширением файла .php
module.example.something.view.php
Файлы Javascript Те же правила, что и для файлов представлений и составляющих, за исключением расширения: .js.php . module.example.something.view.js.php

Обратите внимание, что префикс 'module' и включение имени модуля является обязательным для файлов представлений и составляющих, за исключением случаев, когда нужно заменить базовые отображаемые элементы или составляющие Zabbix. Однако, это правило не распространяется на имена файлов действий.

Подготовка манифеста

Ожидается, что каждый модуль будет иметь файл manifest.json со следующими полями в формате JSON:

Параметр Обязательный Тип По умолчанию Описание
manifest_version Да Double - Манифестная версия модуля. В настоящее время поддерживается версия 1.
id Да String - Идентификатор модуля (Module ID). Только один модуль с данным ID может быть активирован одновременно.
name Да String - Название модуля как отображается в разделе «Администрирование».
version Да String - Версия модуля как отображается в разделе «Администрирование».
namespace Да String - Пространство имен PHP для Module.php и классов действий.
author Нет String "" Автор модуля как отображается в разделе «Администрирование».
url Нет String "" URL модуля как отображается в разделе «Администрирование».
description Нет String "" Описание модуля как отображается в разделе «Администрирование».
actions Нет Object {} Действия для регистрации с этим модулем. Смотрите «Действия».
config Нет Object {} Конфигурация модуля.

Для справки см. пример файла manifest.json в разделе Справочные материалы section.

Действия

Модуль будет иметь контроль над действиями веб-интерфейса, определёнными в объекте actions в файле manifest.json. Таким образом определяются новые действия. Таким же образом вы можете переопределить существующие действия. Каждый ключ действий должен представлять имя действия, а соответствующее значение должно содержать ключи class и, по желанию, layout и view.

Одно действие определяется четырьмя составляющими: name, controller, view и layout. Проверка и подготовка данных обычно выполняются в controller, форматирование вывода выполняется во view или в partials, а layout отвечает за оформление страницы такими элементами, как меню, верхний колонтитул, нижний колонтитул и другие. :

Действия модуля должны быть определены в файле manifest.json как объект actions:

Параметр Обязательный Тип По умолчанию Описание
key Да String - Название действия, строчные буквы [a-z], разделяя слова точкой.
class Да String - Имя класса действия, включая путь к вложенной папке (если используется) в папке actions.
layout Нет String "layout.htmlpage" Макет действия.
view Нет String null Отображение действия.

Существует несколько готовых макетов, таких как layout.json или layout.xml. Они предназначены для действий, которые дают результат, отличный от HTML. Вы можете изучить готовые макеты в директории app/views/ или создать свой собственный.

В некоторых случаях необходимо изменить только представление (view) некоторого действия, не изменяя контроллер. В таком случае просто поместите необходимые элементы отображения и/или составляющие в папку views модуля.

Для справки см. пример файла Action controller в разделе Справочные материалы. Пожалуйста, не стесняйтесь изучать текущие действия исходного кода Zabbix, расположенного в папке app/.

Module.php

Этот необязательный файл PHP отвечает за инициализацию модуля, а также за обработку событий. Предполагается, что в этом файле будет определен класс «Module», расширяющий базовый класс «\Core\CModule». Класс «Module» должен быть определён в пространстве имен, указанном в файле manifest.json.

<?php
       
       namespace Modules\Example;
       use Core\CModule as BaseModule;
       
       class Module extends BaseModule {
           ...
       }

Для справки см. пример файла Module.php в разделе Справочные материалы.

Справочные материалы

Этот раздел содержит базовые версии различных элементов модуля, представленных в предыдущих разделах.

manifest.json

{
           "manifest_version": 1.0,
           "id": "example_module",
           "name": "Example module",
           "version": "1.0",
           "namespace": "Example",
           "author": "John Smith",
           "url": "http://module.example.com",
           "description": "Short description of the module.",
           "actions": {
               "example.something.view": {
                   "class": "SomethingView",
                   "view": "module.example.something.view"
               },
               "example.something.create": {
                   "class": "SomethingCreate",
                   "layout": null
               },
               "example.something.delete": {
                   "class": "SomethingDelete",
                   "layout": null
               },
               "example.something.export.xml": {
                   "class": "data_export/ExportAsXml",
                   "layout": null
               },
               "example.something.export.excel": {
                   "class": "data_export/ExportAsExcel",
                   "layout": null
               }
           },
           "config": {
               "username": "john_smith"
           }
       }

Module.php

<?php declare(strict_types = 1);
       
       namespace Modules\Example;
       
       use APP;
       use CController as CAction;
       
       /**
        * Please see Core\CModule class for additional reference.
        */
       class Module extends \Core\CModule {
       
           /**
            * Initialize module.
            */
           public function init(): void {
               // Initialize main menu (CMenu class instance).
               APP::Component()->get('menu.main')
                   ->findOrAdd(_('Reports'))
                       ->getSubmenu()
                           ->add((new \CMenuItem(_('Example wide report')))
                               ->setAction('example.report.wide.php')
                           )
                           ->add((new \CMenuItem(_('Example narrow report')))
                               ->setAction('example.report.narrow.php')
                           );
           }
       
           /**
            * Event handler, triggered before executing the action.
            *
            * @param CAction $action  Action instance responsible for current request.
            */
           public function onBeforeAction(CAction $action): void {
           }
       
           /**
            * Event handler, triggered on application exit.
            *
            * @param CAction $action  Action instance responsible for current request.
            */
           public function onTerminate(CAction $action): void {
           }
       }

Action controller

<?php declare(strict_types = 1);
       
       namespace Modules\Example\Actions;
       
       use CControllerResponseData;
       use CControllerResponseFatal;
       use CController as CAction;
       
       /**
        * Example module action.
        */
       class SomethingView extends CAction {
       
           /**
            * Initialize action. Method called by Zabbix core.
            *
            * @return void
            */
           public function init(): void {
               /**
                * Disable SID (Session ID) validation. Session ID validation should only be used for actions which involve data
                * modification, such as update or delete actions. In such case Session ID must be presented in the URL, so that
                * the URL would expire as soon as the session expired.
                */
               $this->disableSIDvalidation();
           }
       
           /**
            * Check and sanitize user input parameters. Method called by Zabbix core. Execution stops if false is returned.
            *
            * @return bool true on success, false on error.
            */
           protected function checkInput(): bool {
               $fields = [
                   'name'  => 'required|string',
                   'email' => 'required|string',
                   'phone' => 'string'
               ];
       
               // Only validated data will further be available using $this->hasInput() and $this->getInput().
               $ret = $this->validateInput($fields);
       
               if (!$ret) {
                   $this->setResponse(new CControllerResponseFatal());
               }
       
               return $ret;
           }
       
           /**
            * Check if the user has permission to execute this action. Method called by Zabbix core.
            * Execution stops if false is returned.
            *
            * @return bool
            */
           protected function checkPermissions(): bool {
               $permit_user_types = [USER_TYPE_ZABBIX_ADMIN, USER_TYPE_SUPER_ADMIN];
       
               return in_array($this->getUserType(), $permit_user_types);
           }
       
           /**
            * Prepare the response object for the view. Method called by Zabbix core.
            *
            * @return void
            */
           protected function doAction(): void {
               $contacts = $this->getInput('email');
       
               if ($this->hasInput('phone')) {
                   $contacts .= ', '.$this->getInput('phone');
               }
       
               $data = [
                   'name' => $this->getInput('name'),
                   'contacts' => $contacts
               ];
       
               $response = new CControllerResponseData($data);
       
               $this->setResponse($response);
           }
       }

Action view

<?php declare(strict_types = 1);
       
       /**
        * @var CView $this
        */
       
       $this->includeJsFile('example.something.view.js.php');
       
       (new CWidget())
           ->setTitle(_('Something view'))
           ->addItem(new CDiv($data['name']))
           ->addItem(new CPartial('module.example.something.reusable', [
               'contacts' => $data['contacts']
           ])
           ->show();