コンソール拡張の開発
概要
拡張は、Pandora FMS Web コンソールの新しい機能をプラグインとして開発する方法です。
「拡張」の種類
拡張には次の種類があります。
- エージェントタブ拡張は、エージェント表示または編集画面のヘッダーのタブに表示されます。
- 表示される拡張は、Pandora のメニューに表示されます。
- 非表示の拡張は、Pandora メニューである index.php からロードされ実行されますが、Pandora メニューには表示されません。
「拡張」のディレクトリ
拡張のディレクトリは、Pandora FMS コンソールをインストールしたディレクトリ内の extensions
というサブディレクトリです。このディレクトリは、次のようは拡張が含まれています。
拡張のメインファイル
Pandora FMS コンソールにロードされるコードです。
拡張のサブディレクトリ
これはオプションで、メニュー内の拡張名の隣に表示されるアイコンの画像ファイル (18×18 のサイズ) および、その他、翻訳、モジュール、画像ファイルなどが含まれます。
「拡張」の構造
<?php <Comments with license, author/s, etc...> <php auxiliary code as functions, variables, classes that your extension use> function <name of main function> () { <Main function Code> } /*-------------------------------------*/ /* Adds the link in the operation menu */ extensions_add_operation_menu_option ('<Name Extension>', '<father ID menu>', '<relative path Icon>'); /* Adds the link in the godmode menu */ extensions_add_godmode_menu_option ('<Name Extension>', '<ACL level>', '<father ID menu>', '<relative path Icon>') /*-------------------------------------*/ /* Sets the callback function to be called when the extension is selected in the operation menu */ extensions_add_main_function ('<name of main function>'); /* Sets the callback function to be called when the extension is selected in the godmode menu */ extensions_add_godmode_function('<name of godmode function>'); ?>
「拡張」の API
拡張の API はまだ開発途上で、将来変更するかもしれません。
extensions_add_operation_menu_option
extensions_add_operation_menu_option ('<名前文字列>', '<メニュー親ID>', '<アイコン相対パス>')
この関数は、拡張へのリンクを指定した名称で 操作(Operations) メニューに追加します。3番目のパラメータはオプションで、アイコン画像 (18×18 ピクセル) への相対パスを指定します。
この最後のパラメータが定義されていない場合は、プラグのアイコンが使用されます ()。
extensions_add_godmode_menu_option
extensions_add_godmode_menu_option ('<拡張名>', '<ACL レベル>' , '<メニュー親ID>', '<アイコン相対パス>')
この関数は、ユーザが 2番目のパラメータで指定された ACL レベルを満たす場合に、拡張へのリンクを指定した名称で システム管理(Godmode) メニューに追加します。4番目のパラメータはオプションで、アイコン画像 (18×18 ピクセル) への相対パスを指定します。
この最後のパラメータが定義されていない場合は、プラグのアイコンが使用されます ( )。
extensions_add_main_function
extensions_add_main_function ('<メイン関数名>')
操作(operation)メニューで拡張のリンクをクリックしたときに呼び出される関数を設定します。
extensions_add_godmode_function
extensions_add_godmode_function ('<システム管理メニュー関数名>')
Pandora FMS コンソールのシステム管理メニューの拡張のリンクをクリックしたときに呼び出される関数を設定します。
extensions_add_login_function
extensions_add_login_function ('<ログイン関数名>')
Pandora FMS コンソールへユーザが正しくログインしたときに呼び出される関数を設定します。
extensions_add_godmode_tab_agent
extensions_add_godmode_tab_agent('<拡張タブID>', '<拡張タブ名>', '<画像ファイルの相対パス>', '<エージェント管理のタブから実行される関数名>')
エージェント編集画面に 1つ以上のタブを追加します。それが選択された場合は、指定した名前の関数が呼び出されます。
extensions_add_opemode_tab_agent
extensions_add_opemode_tab_agent('<拡張タブID>', '<拡張タブ名>', '<画像ファイルの相対パス>', '<エージェント参照のタブから実行される関数名>')
エージェント参照画面に 1つ以上のタブを追加します。それが選択された場合は、指定した名前の関数が呼び出されます。
extensions_add_translation_string_function
extensions_add_translation_string_function('<翻訳関数名>')
拡張共通の翻訳関数 ___() から呼び出される関数を設定します。
メニューの親 ID
拡張 API で利用できる ID 文字列を示します。呼び出し関数で指定しなかったり、パラメータを指定しない場合は、拡張のサブメニューにのみ表示されます。
操作
estado
: エージェント参照(View agents)network
: ネットワーク表示(Network view)reporting
: レポート(Reporting)gismaps
: GIS 表示(GIS view)eventos
: イベント参照(View events)workspace
: ユーザのワークスペース(User's workspace)
システム管理
gagente
: エージェント管理(Manage agents)gmassive
: 一括操作(Massive operations)gmodules
: モジュール管理(Manage modules)galertas
: アラート管理(Manage alerts)gusuarios
: ユーザ管理(Manage users)\godgismaps
: GIS管理(Manage GIS)gservers
: サーバ管理(Manage servers)glog
: システム監査ログ(System audit log)gsetup
: 設定(Setup)gdbman
: DBメンテナンス(DB maintenance)gpolicies
: ポリシー管理
例
列がモジュールのグループ、行がエージェントグループの表を表示する拡張です。また、それぞれのセルは、次のような意味の色が表示されます。
- 緑: すべてのモジュールが正常
- 黄色: 少なくとも一つのモニタ項目が警告状態
- 赤: 少なくとも一つのモニタ項目が障害状態
そして、この拡張は、操作メニューのエージェント参照から呼び出されます。
ソースコード
<?php /** * Pandora FMS - http://pandorafms.com * ================================================== * Copyright (c) 2005-2024 PFMS * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation for version 2. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /** * Extension specific translation function */ function extensions_translation() { $translates = array( 'es' => array( "sentence" => "translated sentence" ), /* ... for other language's definitions. */ ); $args = func_get_args(); $string = array_shift($args); $user_language = get_user_language (); if(isset($translates[$user_language][$string])){ return vsprintf($translates[$user_language][$string], $args); } else{ return false; } } /** * Translate the array texts using gettext */ function translate(&$item, $key) { $item = ___($item); } /** * The main function of module groups and the enter point to * execute the code. */ function mainModuleGroups() { global $config; //the useful global var of Pandora Console, it has many data can you use //The big query $sql = "select COUNT(id_agente) AS count, estado FROM tagente_estado WHERE utimestamp != 0 AND id_agente IN (SELECT id_agente FROM tagente WHERE id_grupo = %d AND disabled IS FALSE) AND id_agente_modulo IN (SELECT id_agente_modulo FROM tagente_modulo WHERE id_module_group = %d AND disabled IS FALSE AND delete_pending IS FALSE) GROUP BY estado"; echo "<h1>" . ___("Combine table of agent group and module group") . "</h1>"; echo "<p>" . ___("This table show in columns the modules group and for rows agents group. The cell show all modules") . "</p>"; $agentGroups = get_user_groups ($config['id_user']); $modelGroups = get_all_model_groups(); array_walk($modelGroups, 'translate'); //Translate all head titles to language is set $head = $modelGroups; array_unshift($head, ' '); //Metaobject use in print_table $table = null; $table->align[0] = 'right'; //Align to right the first column. $table->style[0] = 'color: #ffffff; background-color: #778866; font-weight: bolder;'; $table->head = $head; //The content of table $tableData = array(); //Create rows and celds foreach ($agentGroups as $idAgentGroup => $name) { $row = array(); array_push($row, $name); foreach ($modelGroups as $idModelGroup => $modelGroup) { $query = sprintf($sql,$idAgentGroup, $idModelGroup); $rowsDB = get_db_all_rows_sql ($query); $states = array(); if ($rowsDB !== false) { foreach ($rowsDB as $rowDB) { $states[$rowDB['estado']] = $rowDB['count']; } } $count = 0; foreach ($states as $idState => $state) { $count = $state; } $color = 'transparent'; //Defaut color for cell if ($count == 0) { $color = '#babdb6'; //Grey when the cell for this model group and agent group hasn't modules. $alinkStart = ''; $alinkEnd = ''; } else { $alinkStart = '<a href="index.php?sec=estado&sec2=operation/agentes/status_monitor&status=-1&ag_group=' . $idAgentGroup . '&modulegroup=' . $idModelGroup . '">'; $alinkEnd = '</a>'; if (array_key_exists(0,$states) && (count($states) == 1)) $color = '#8ae234'; //Green when the cell for this model group and agent has OK state all modules. else { if (array_key_exists(1,$states)) $color = '#cc0000'; //Red when the cell for this model group and agent has at least one module in critical state and the rest in any state. else $color = '#fce94f'; //Yellow when the cell for this model group and agent has at least one in warning state and the rest in green state. } } array_push($row, '<div style="background: ' . $color . ' ; height: 15px; margin-left: auto; margin-right: auto; text-align: center; padding-top: 5px;"> ' . $alinkStart . $count . ' modules' . $alinkEnd . '</div>'); } array_push($tableData,$row); } $table->data = $tableData; print_table($table); echo "<p>" . ___("The colours meaning:") . "<ul>" . '<li style="clear: both;"> <div style="float: left; background: #babdb6; height: 20px; width: 80px;margin-right: 5px; margin-bottom: 5px;"> </div>' . ___("Grey when the cell for this model group and agent group hasn't modules.") . "</li>" . '<li style="clear: both;"> <div style="float: left; background: #8ae234; height: 20px; width: 80px;margin-right: 5px; margin-bottom: 5px;"> </div>' . ___("Green when the cell for this model group and agent has OK state all modules.") . "</li>" . '<li style="clear: both;"><div style="float: left; background: #cc0000; height: 20px; width: 80px;margin-right: 5px; margin-bottom: 5px;"> </div>' . ___("Red when the cell for this model group and agent has at least one module in critical state and the rest in any state.") . "</li>" . '<li style="clear: both;"><div style="float: left; background: #fce94f; height: 20px; width: 80px;margin-right: 5px; margin-bottom: 5px;"> </div>' . ___("Yellow when the cell for this model group and agent has at least one in warning state and the rest in green state.") . "</li>" . "</ul>" . "</p>"; } extensions_add_operation_menu_option("Modules groups", 'estado', 'module_groups/icon_menu.png'); extensions_add_main_function('mainModuleGroups'); extensions_add_translation_string_function('extensions_translation'); ?>
説明
ソースコードは、2つのパーツにわかれています。
- 拡張のソースコード
- API を呼び出す関数
パーツの順番は関係ありませんが、APIを呼び出す関数は拡張ファイルの下の方が良いです。なぜなら、スタイルのガイドラインでは、この部分を下に書くようにアドバイスしているためです。それにより、すべての拡張は同じようなスタイルになります。
拡張のソースコード
この例の場合、同じファイルに 3つの関数があります。しかし、共通のコードがあるのであれば、複数ファイルに分割する方が良いです(そして、拡張のサブディレクトリに保存します)。関数は次の通りです。
extensions_translation()
関数
拡張独自の翻訳に使用されます。共通の翻訳関数から呼び出されます。mainModuleGroups()
関数
これは、拡張のコードで何行もあります。重要な部分のみ示します。
- 最初は、設定のグローバル変数へのアクセスです。この変数に、Pandora コンソールに関する多くの設定やデフォルト値が含まれます。
- 2つ目の変数は、MySQL のクエリを文字列で設定しています。ここで、
%d
は、グループID および モジュールグループID を示す、書式化文字列です。これらの変数は、foreach ループの中の sprintf 関数 で使われます。 - 次に表示するためのいくつかの
echo
があります。 - DB のデータを 1次元の 2つの配列に展開し、id がインデックスで、内容は列(モジュールグループと行(エージェントグループ)にタイトルです。
- モジュールグループ配列のタイトルを変換します。
- メタオブジェクトの $table を作成し、行を埋めて表示します。
- foreach ループの前に、
$table
に、テーブルのヘッダとスタイルを定義します。 - 最初のループは行のデータ用です。(それぞれのエージェントグループ)
- 2つ目のループは、現在の行に対する列のデータ用です。(それぞれのモジュールグループ)
- そして、それぞれのセルに、モジュールグループとエージェントグループの ID の 2つの数字が当てはまり、この 2つの数字を使ってデータベースクエリを実施し、データを取得します。
- 異なる種類のモニタ状態および、状態の数の合計の結果の配列を生成します。
- そして残りは、セルを html に整形する処理です。仕組みは簡単です。すべての状態の合計がゼロであれば、CSS の div で背景をグレーにします。もし、
$states[1] != 0
もしくは、何らかの文字で、少なくとも一つのモニタ状態が障害であれば、div
を赤にします。配列が一つのセルで正常状態であれば、div
を緑にします。そして、その他の場合は、div
を黄色にします。 - 合計が
0
より大きければ、セルにリンクを加えます。 - 行を
$table
に保存し、foreach で繰り返します。 - 表を表示します。
- 凡例とその他注意をページの下に表示します。
API 呼び出し関数
- Pandora FMS メニューへの拡張機能の挿入:
extensions_add_operation_menu_option("Modules groups", 'estado', 'module_groups/icon_menu.png');
- 'Modules groups' は、エージェントのサブメニューに表示される名前です。
- 'estado' は、拡張に関連付けるエレメントです。
- 'module_groups/icon_menu.png' は、サブメニューに表示されるアイコンです。パスは、拡張のディレクトリからの相対パスです。
- この拡張機能のメイン関数を定義します。これは
extensions_add_main_function('mainModuleGroups');
として表示されます。ここで、mainModuleGroups
は拡張機能のメイン関数の名前です。
関数の順序は関係ありません。
ディレクトリ構成
拡張機能のディレクトリ構造は次のとおりです。
+module_groups | +--icon_menu.png | +module_groups.php
拡張のディレクトリは /var/www/pandora_console
にあります。
すべての拡張ファイルは、Pandora FMS コンソール の拡張ディレクトリにのみコピーする必要があります。Pandora FMS コンソールがファイルと拡張サブディレクトリを読み取ることができるように、権限を調整する必要があります。Pandora FMS コンソールは新しい拡張を検索し、見つかった場合はシステムに追加します。
サブディレクトリ
この場合、例では一つのサブディレクトリがあります。そして、通常、拡張は一つのサブディレクトリを持つ必要があります。サブディレクトリは、拡張のメインファイルと同じ名前です。この例のサブディレクトリには、アイコンファイル (icon_menu.png
) のみがあります。このアイコンは、 Pandora FMS メニューに表示されます。