20. Модулі

Огляд

Ви можете розширити функціональність інтерфейсу Zabbix, додавши сторонні модулі або розробивши власні модулі без необхідності змінювати вихідний код Zabbix.

Зверніть увагу, що код модуля буде виконуватися з тими ж привілеями, що і вихідний код Zabbix. Це означає, що

  • сторонні модулі можуть бути небезпечними. Ви повинні довіряти модулям, які ви встановлюєте;
  • помилки в коді сторонніх модулів можуть призвести до аварійного завершення роботи фронтенду. Якщо це сталося, просто видаліть код модуля з фронтенду. Як тільки ви перезавантажите фронтенд Zabbix, ви побачите повідомлення про те, що деякі модулі відсутні. Перейдіть у Адміністрування модулів (в розділі АдмініструванняЗагальніМодулі) і натисніть Сканувати директорію ще раз, щоб видалити неіснуючі модулі з бази даних

Установка

Завжди читайте інструкцію зі встановлення конкретного модуля. Це Рекомендується встановлювати нові модулі по одному, щоб було легше виявити збої.

Безпосередньо перед встановленням модуля:

  • Переконайтеся, що ви завантажили модуль із надійного джерела. Встановлення шкідливого коду може призвести до таких наслідків, як втрата даних
  • Різні версії одного модуля (з однаковим ідентифікатором) можуть бути встановлені паралельно, але одночасно може бути активована лише одна версія

Кроки для встановлення модуля:

  • Розпакуйте свій модуль у власну папку в каталозі modules в тому місці, де встановлено web-інтерфейс Zabbix
  • Переконайтеся, що папка вашого модуля містить принаймні файл manifest.json
  • Перейдіть до Адміністрування модулів і натисніть кнопку Сканувати директорію
  • Новий модуль з'явиться в списку разом із його версією, автором, описом і статусом
  • Увімкніть модуль, натиснувши на його статус

Вирішення проблем:

|Проблема|Рішення| |---------|-------------------------------------------- -| |Модуль не з’явився у списку|Переконайтеся, що файл manifest.json існує в папці modules/your-module/ інтерфейсу Zabbix. Якщо так, це означає, що модуль не підходить для поточної версії Zabbix. Якщо файл manifest.json не існує, ймовірно, ви розпакували не в той каталог.| |Збій інтерфейсу|Код модуля несумісний із поточною версією Zabbix або конфігурацією сервера. Будь ласка, видаліть файли модуля та перезавантажте інтерфейс. Ви побачите повідомлення про те, що деякі модулі відсутні. Перейдіть до Адміністрування модулів і знову натисніть Сканувати директорію, щоб видалити неіснуючі модулі з бази даних.| |З’являється повідомлення про помилку щодо ідентичного простору імен, ідентифікатора або дій|Новий модуль намагався зареєструвати простір імен, ідентифікатор або дії, які вже зареєстровані іншими активними модулями. Вимкніть конфліктуючий модуль (згаданий у повідомленні про помилку), перш ніж увімкнути новий.| |З’являються повідомлення про технічні помилки|Повідомити про помилки розробнику модуля.|

Розробка модулів

Перевага надається проектуванню шаблонів програмного забезпечення за моделлю "модель-вид-контролер" (MVC - Model-view-controller), оскільки вона також використовується в Zabbix frontend і полегшить розробку. Сувора типізація PHP також вітається, але не є обов'язковою.

Зверніть увагу, що за допомогою модулів ви можете легко додавати нові пункти меню та відповідні візуалізації і дії до фронтенду Zabbix. Наразі неможливо зареєструвати новий API або створити нові таблиці бази даних за допомогою модулів.

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

Кожен модуль є каталогом (розміщеним у каталозі modules) з вкладеними папками, що містять контролери, views та будь-який інший код:

example_module_directory/ (обов’язково) manifest.json (обов’язково) Метадані та визначення дії. Module.php Ініціалізація модуля та обробка подій. actions/ Файли управління діями. SomethingView.php SomethingCreate.php SomethingDelete.php data_export/ ExportAsXml.php ExportAsExcel.php views/ view файли. example.something.view.php example.something.delete.php js/файли JavaScript, які використовуються у view. example.something.view.js.php partials/ Будь-які додаткові файли для використання у view example.something.reusable.php js/файли JavaScript, що використовуються в 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
Файли view і partials Малі літери [a-z]
Слова, розділені крапкою
З префіксом module., після якого йде назва модуля
Закінчується типом дії та розширенням файлу .php
module.example .something.view.php
Файли Javascript Застосовуються ті самі правила, що й для view та partials, за винятком розширення файлу .js.php. module.example.something.view.js.php

Зауважте, що префікс 'module' є обов'язковим для назв файлів view і partials, якщо тільки вам не потрібно перевизначити основні стандартні view або partials файли Zabbix. Це правило, однак, не стосується назв файлів дій.

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

Кожен модуль повинен мати файл manifest.json з наступними полями у форматі JSON:

Параметр Обов'язковий Тип За замовчуванням Опис
manifest_version Так Double - Версія маніфесту модуля. Наразі підтримується версія 1.
id Так String - Ідентифікатор модуля. Одночасно можна ввімкнути лише один модуль із заданим ідентифікатором.
name Так String - Назва модуля, що відображається в розділі "Адміністрування"
version Так String - Версія модуля, що відображається в розділі "Адміністрування".
namespace Так String - Простір імен PHP для Module.php і класів дій.
author Ні String "" Автор модуля, що відображається в розділі "Адміністрування".
url Ні Рядок "" URL-адреса модуля, яка відображається в розділі адміністрування.
description Ні String "" Опис модуля, що відображається в розділі "Адміністрування".
actions No Object {} Дії для реєстрації в цьому модулі. Див. Дії.
config Ні Object {} Конфігурація модуля.

Для довідки перегляньте приклад manifest.json у розділі Довідка.

Actions

Модуль матиме контроль над діями фронтенду, визначеними в об'єкті actions у файлі manifest.json. Таким чином визначаються нові дії. Так само ви можете перевизначити існуючі дії. Кожен ключ у actions повинен представляти назву дії, а відповідні значення повинні містити ключі class і, за бажанням, ключі layout і view.

Одна дія визначається чотирма компонентами: ім'ям, контролером, view і layout. Перевірка та підготовка даних зазвичай виконується в контролері, форматування виводу виконується у view або його частинах, а 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 деякої дії, залишивши контролер недоторканим. У такому випадку просто помістіть необхідні файли view та/або partial файли view у каталог views модуля.

Для довідки перегляньте приклад файлу контролера дій у розділі Довідка. Будь ласка, не соромтеся досліджувати поточні дії вихідного коду 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": "Приклад модуля",
           "version": "1.0",
           "namespace": "Example",
           "author": "Лесь Подервʼянський",
           "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;
       
       /**
        * Дивіться клас Core\CModule для додаткової інформації.
        */
       class Module extends \Core\CModule {
       
           /**
            * Initialize module.
            */
           public function init(): void {
               // Ініціалізація головного меню (екземпляр класу CMenu).
               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')
                           );
           }
       
           /**
            * Обробник подій, що запускається перед виконанням дії.
            *
            * @param CAction $action Екземпляр дії, відповідальний за поточний запит.
            */
           public function onBeforeAction(CAction $action): void {
           }
       
           /**
            * Обробник подій, що запускається при виході з програми.
            *
            * @param CAction $action Екземпляр дії, відповідальний за поточний запит.
            */
           public function onTerminate(CAction $action): void {
           }
       }

Action controller

<?php declare(strict_types = 1);
       
       namespace Modules\Example\Actions;
       
       use CControllerResponseData;
       use CControllerResponseFatal;
       use CController як CAction;
       
       /**
        * Приклад action модуля.
        */
       class SomethingView extends CAction {
       
           /**
            * Ініціалізація дії. Метод викликається ядром Zabbix.
            *
            * @return void
            */
           public function init(): void {
               /**
                * Вимкнути перевірку SID (ID сеансу). Перевірку ідентифікатора сеансу слід використовувати лише для дій, які включають дані
                * модифікації, наприклад оновлення або видалення. У такому випадку ідентифікатор сеансу повинен бути представлений в URL-адресі, щоб
                * термін дії URL-адреси закінчився, щойно завершиться сесія.
                */
               $this->disableSIDvalidation();
           }
       
           /**
            * Перевірка та очищення вхідних параметрів користувача. Метод, що викликається ядром Zabbix. Виконання зупиняється, якщо повертається false.
            *
            * @return bool true on success, false on error.
            */
           protected function checkInput(): bool {
               $fields = [
                   'name' => 'required|string',
                   'email' => 'required|string',
                   'phone' => 'string'
               ];
       
               // Лише підтверджені дані надалі будуть доступні за допомогою $this->hasInput() і $this->getInput().
               $ret = $this->validateInput($fields);
       
               if (!$ret) {
                   $this->setResponse(новий CControllerResponseFatal());
               }
       
               return $ret;
           }
       
           /**
            * Перевірте, чи має користувач дозвіл на виконання цієї дії. Метод викликається ядром Zabbix.
            * Виконання зупиняється, якщо повертається false.
            *
            * @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);
           }
       
           /**
            * Підготуйте об'єкт відповіді для view. Метод викликається ядром Zabbix.
            *
            * @return void
            */
           protected function$data 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();