Sidebar

Become a monitoring expert!
Sign up for Zabbix training

20. モジュール

概要

Zabbixフロントエンドは、サードパーティモジュールの追加や独自モジュールの開発により、
Zabbixのソースコードを変更することなく、機能を拡張することができます。

モジュールコードは、Zabbixのソースコードと同じ権限で実行されることに注意してください。
これはつまり、以下のことを意味します。

  • サードパーティーモジュールは有害である可能性があります。インストールするモジュールを信頼する必要があります。
  • サードパーティモジュールのコードにエラーがあると、フロントエンドがクラッシュすることがあります。
    そのような場合は、当該のモジュールコードをフロントエンドから削除してください。
    Zabbixフロントエンドをリロードするとすぐに、いくつかのモジュールが存在しないことを示すというメモが表示されます。
    Module administration (AdministrationGeneralModules) にアクセスし、Scan directory を再度クリックして、
    存在しないモジュールをデータベースから削除します。

インストール方法

各モジュールのインストールマニュアルを必ずお読みください。
また新しいモジュールは、故障を未然に防ぐため、1つずつインストールすることをお勧めします。

モジュールをインストールする前に :

  • 信頼できるソースからモジュールをダウンロードしたことを確認してください。
    有害なコードをインストールすると、データ損失のような結果につながる可能性があります。
  • 同じモジュールの異なるバージョン(同じID)を並行してインストールすることができます。
    ただし、一度に有効化できるのは1つのバージョンだけです。

モジュールをインストールする手順 :

  • Zabbixフロントエンドのmodulesフォルダにあるモジュール専用のフォルダに解凍します。
  • モジュールフォルダに少なくともmanifest.jsonが含まれていることを確認してください。
  • Module administrationに移動し、
    Scan directory ボタンをクリックします。
  • 新しいモジュールは、バージョン、作者、説明、ステータスとともにリストに表示されます。
  • そのステータスをクリックして、モジュールを有効にします。

トラブルシューティング

問題点 解決策
モジュールが一覧に表示されない Zabbixフロントエンドのmodules/your-module/`フォルダにmanifest.jsonファイルが存在することを確認してください。
存在する場合、そのモジュールは現在のZabbixのバージョンに対応していないことを意味します。
manifest.jsonファイルが存在しない場合、間違ったディレクトリで解凍された可能性があります。
*フロントエンドがクラッシュしました 現在のZabbixのバージョンまたはサーバ構成とモジュールコードが互換性がありません。
モジュールファイルを削除し、フロントエンドを再読み込みしてください。
いくつかのモジュールが存在しないという通知が表示されます。Module administrationに移動し、
Scan directoryをもう一度クリックして、存在しないモジュールをデータベースから削除してください。
*同一の名前空間、ID、アクションに関するエラーメッセージが表示されます。 新しいモジュールを有効にする前に、競合するモジュール(エラーメッセージに記載)を無効にしてください。
技術的なエラーメッセージが表示される モジュールの開発者にエラーを報告してください。

モジュール開発

モジュールはPHP言語で記述されます。モデル・ビュー・コントローラ(MVC)ソフトウェアパターンデザインは、
Zabbixのフロントエンドでも使用されており、開発が容易になるため、推奨されています。
PHPの strict typing も歓迎されますが、必須ではありません。

モジュールを使用することで、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' などのイベントの処理を担当します。
actionsviewspartials ディレクトリには、モジュールのアクションに必要なPHPとJavaScriptのコードが含まれています。

命名規則

モジュールを作成する前に、ディレクトリやファイルなど、モジュールの各項目の命名規則について合意しておくことが重要です。
また、上記の例 Module structure の項を参照してください。

Item 命名ルール
Module directory Lowercase [a-z], underscore and decimal digits example_v2
Action subdirectories Lowercase [a-z] and underscore character data_export
Action files CamelCase, ending with action type SomethingView.php
View and partial files Lowercase [a-z]
Words separated with dot
Prefixed by module. followed by module name
Ending with action type and .php file extension
module.example.something.view.php
Javascript files The same rules apply as for view and partial files, except the .js.php file extension. module.example.something.view.js.php

Zabbixコアのビューまたはパーシャルを上書きする必要がある場合を除き、ビューとパーシャルのファイル名には'module'の
プレフィックスと名前のインクルージョンが必須であることに注意してください。
ただし、このルールはアクションファイル名には適用されません。

マニフェストの準備

各モジュールは、次のようなフィールドを持つ JSON 形式の manifest.json ファイルを用意する必要があります。

Parameter 必須? デフォルト値 説明
manifest_version Yes Double - モジュールのマニフェスト・バージョン。現在サポートされているバージョンは 1 です
id Yes String - モジュールID。同時に有効にできるのは、指定されたIDを持つ1つのモジュールのみです
name Yes String - 管理セクションに表示されるモジュール名
version Yes String - 管理セクションに表示されるモジュールのバージョン
namespace Yes String - Module.php およびアクションクラス用の PHP 名前空間
author No String "" 管理セクションに表示されるモジュール作成者
url No String "" 管理セクションに表示されるモジュールURL
description No String "" 管理セクションに表示されるモジュールの説明
actions No Object {} このモジュールに登録するアクション。アクションを参照
config No Object {} モジュール設定

参考までに、Referenceセクションの manifest.json の例をご覧ください。

アクション

このモジュールは、manifest.json ファイル内のactionsオブジェクトで定義された
フロントエンドのアクションを制御します。このようにして、新しいアクションを定義することができます。
同じように、既存のアクションを再定義することもできます。アクションの各キーはアクション名を表し、
対応する値には class を含み、オプションで layoutview のキーを含みます。

1つのアクションは、名前、コントローラ、ビュー、レイアウトの4つの対応関係で定義されます。
データの検証や準備は一般的にコントローラで行われ、出力のフォーマッティングはビューまたはパーシャルで行われます。
レイアウトは、ページをメニュー、ヘッダ、フッタなどの要素で装飾する役割を果たします。

モジュールのアクションは、manifest.json ファイルに actions オブジェクトとして定義する必要があります。

パラメータ 必須? デフォルト値 説明
*key* Yes String - Action の名前, 小文字の [a-z], ドット(.)で区切られる
class Yes String - アクションクラスの名前。actions ディレクトリ内のサブディレクトリのパス (使用されている場合) も含める。
layout No String "layout.htmlpage" アクションレイアウト
view No String null アクションビュー

あらかじめ定義されたレイアウトがいくつかあり、例えば layout.json のような定義済みのレイアウトがいくつかあります。
これらは、HTMLとは異なる結果を生成するアクションのために用意されています。
app/views/ディレクトリにある定義済みレイアウトを探したり、自分でレイアウトを作成することもできます。

時には、アクションのビュー部分のみを再定義する必要がある場合もあります。
そのような場合は、コントローラはそのままで必要なビューや部分ファイルをモジュールの views ディレクトリに配置します。

参考までに、Referenceセクションのアクションコントローラファイルの例をご覧ください。
またZabbixソースコードの現在のアクションは、app/ ディレクトリにあります。

Module.php

このオプションの PHP ファイルは、モジュールの初期化およびイベント処理に使用されます。
クラス 'Module' は、ベースクラス CoreCModule を拡張して、このファイルで定義されることが期待されます。
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 (Sessoin ID) validation. Session ID validation should only be used for actions which involde 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();