Zabbix支持通过添加第三方组件或自研的组件来增强Zabbix前端的功能,而无需更改Zabbix的源代码。
需要注意的是组件代码将被赋予与Zabbix源代码相同的权限运行。这意味着:
请务必阅读特定组件的安装手册。建议逐个安装新的组件以便于捕捉安装过程中的失败信息。
在安装组件之前:
组件安装步骤:
modules
文件夹下。故障排除:
故障 解 | 方法 |
---|---|
组件在列表中不可见 确保在Zabbi | 前端modules/your-module/ 文件夹中包含manifest.json配置文件,若上述条件已满足,那意味着组件版本与Zabbix版本存在冲突。若在 modules/your-module/ 中找不到manifest.json配置文件,可能是由于您在错误的目录中进行解包导致。 |
前端崩溃 可能是 | 于组件代码与当前Zabbix版本或服务器配置不兼容导致,请删除这些组件文件并重新加载Zabbix前端,您将看到这些组件已被禁用。前往Module administration并再次单击Scan directory来移除这些无效组件。 |
出现相同的命名、ID或操作的错误信息 新组件会尝试去注册一个新的组件 | ,组件ID或操作,如果被已有组件占用,在启用新组件之前,请禁用这些冲突组件(错误信息中已提到)。 |
出现其他技术错误提示 请将这些组件的报错 | 息反馈至开发者。 |
组件是基于PHP语言编写的,建议使用Zabbix模型-视图-控制器(MVC)软件设计模式,好处在于其同时也应用于Zabbix前端,有利于后续开发。我们推崇使用PHP严格模式进行开发,但这并非强制性的要求。
请注意,您可以通过组件功能轻松地在Zabbix前端中添加新的菜单项以及对应各自的视图和操作,但暂时无法通过组件功能注册新的API或创建新的数据库表。
每个组件都包含一个单独的目录(位于modules
目录中),其子目录包含控制器、视图和任何其他代码:
example_module_directory/ (必须)
manifest.json (必须) 元数据和操作定义。
Module.php 组件初始化和事件处理。
actions/ 操作控制器文件。
SomethingView.php
SomethingCreate.php
SomethingDelete.php
data_export/
ExportAsXml.php
ExportAsExcel.php
views/ 视图文件。
example.something.view.php
example.something.delete.php
js/ 使用在视图中的JavaScript文件。
example.something.view.js.php
partials/ 视图局部文件。
example.something.reusable.php
js/ 使用在局部中的JavaScript文件。
example.something.reusable.js.php
显而易见,自定义组件目录中唯一的强制要求需包含的配置文件是manifest.json
,没有此配置文件,组件将无法注册。Module.php
负责注册菜单项并处理诸如“onBeforeAction”和“onTerminate”之类的事件。actions、views和partials目录中包含组件操作所需的PHP和JavaScript代码。
在创建组件之前,首当其冲的是要统一不同组件项之间(如组件目录和文件)的命名约定,这样我们就可以使这些组件项的名称井然有序,通俗易懂。您也可以在 module_structure找到示例。
组件项 命名 | 则 示例 | |
---|---|---|
组件目录 小写 |
a-z]、下划线加十进制数字 example_v2 | |
操作子目录 小写[ | -z]、下划线加字符 data_export | |
操作文件 驼峰式 | 名法,以操作类型作为结尾 SomethingView.php | |
视图和局部文件 小写[a- | ] module.e单词用点进行分隔 以 module. 作为前缀,后接组件名称以操作类型和.php文件扩展名作结尾。 |
ample.something.view.php |
Javascript文件 除 | 尾文件扩展名为'.js.php'之外,与'视图和局部文件'项的命名规则保持一致。 module.example.something.view.js | php |
请注意,'module'前缀对于视图和部分文件名是必需的,除非您需要覆盖Zabbix核心视图或部分文件,该条规则不适用于操作文件命名。
每个组件都需要一个包含以下JSON格式的Manifest.json配置文件
参数 是 | 必填 类型 | 默认 描述 | ||
---|---|---|---|---|
manifest_version | 是 | ouble | - | anifest当前版本,当前可支持的版本号为1。 |
id | 是 | tring | - | 件ID,同一ID的组件在同一时间内仅允许启用一个。 |
name | 是 | tring | - | 管理菜单中展示的组件名称。 |
version | 是 | tring | - | 管理菜单中展示的组件版本。 |
namespace | 是 | tring | - | odule.php和操作类的PHP命名规则。 |
author | 否 | tring | " | 理菜单中展示的组件作者。 |
url | 否 | tring | " | 理菜单中展示的组件URL。 |
description | 否 | tring | " | 理菜单中展示的组件描述。 |
actions | 否 | bject | } | 组件中注册的操作,详情参见“操作”。 |
config | 否 | bject | } | 件配置。 |
详情可参见reference中manifest.json配置文件说明的部分。
组件会对manifest.json配置文件里actions对象定义的前端操作进行控制,使用这个方法可以定义新的操作,同样可以对已有操作进行定义。每个操作的键值都应该表示操作名称,相应的值应该包含class
键和可选的layout
键和view
键。
一个操作由四个对应项定义:名称、控制器、视图和布局。数据验证和数据准备工作通常在控制器中完成,格式化输出在视图或局部视图中完成,布局则主要负责用菜单、页眉、页脚等元素装饰前端页面。
组件操作必须在manifest.json配置文件的actions对象中进行定义。
参数 是 | 必填 类型 | 默认 | 描述 | |
---|---|---|---|---|
*key* | 是 | tring | - | 作名称。小写[a-z],单词之间用点进行分隔 |
class | 是 | tring | - | 作的类名称。包含actions 目录中的子目录路径(如果使用到的话)。 |
layout | 否 | tring | layout.htmlpage" | 作布局 |
view | 否 | tring | 操 | 视图 |
目前已经有一些预定义好的布局,例如layout.json
或layout.xml
。这些预定义的布局可用于产生与HTML不同效果的操作。您可以在app/views/directory目录下浏览预定义的布局,甚至可以创建自己的布局。
有时为了保持控制器的完整性而单独重定义部分操作的视图是有必要的。这种情况下只需要把必要的视图或局部文件放在组件的views
目录下即可。
请参考Reference部分中的动作控制器文件示例。请尽情探索现有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在Reference中描述的部分。
本章节包含前面几个章节中介绍的不同组件元素的基础版本。
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;
/**
* 有关其他参考,请参阅Core\CModule类。
*/
class Module extends \Core\CModule {
/**
* 组件初始化。
*/
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 {
}
}
操作控制器
<?php declare(strict_types = 1);
namespace Modules\Example\Actions;
use CControllerResponseData;
use CControllerResponseFatal;
use CController as CAction;
/**
* 操作组件示例。
*/
class SomethingView extends CAction {
/**
* 初始化操作。Zabbix核心调用方法。
*
* @return void
*/
public function init(): void {
/**
* 禁用SID(Sessoin ID)验证。会话ID验证只能用于涉及数据修改的操作,如更新或删除操作。
* 在这种情况下,必须在URL中显示会话ID,这样一旦会话过期,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(new 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);
}
/**
* 准备视图的响应对象。Zabbix核心调用方法。
*
* @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);
}
}
操作视图