mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
First full commit of plugin system
This commit is contained in:
61
doc/Plugin_System.md
Normal file
61
doc/Plugin_System.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# Developing for the Plugin System
|
||||||
|
|
||||||
|
This documentation will hopefully give you a basis for how to write a plugin for LibreNMS.
|
||||||
|
|
||||||
|
A test plugin is available on GitHib: https://github.com/laf/Test
|
||||||
|
|
||||||
|
Plugins need to be installed into html/plugins
|
||||||
|
|
||||||
|
The structure of a plugin is follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
html/plugins
|
||||||
|
/PluginName
|
||||||
|
/PluginName.php
|
||||||
|
/PluginName.inc.php
|
||||||
|
```
|
||||||
|
|
||||||
|
The above structure is checked before a plugin can be installed.
|
||||||
|
|
||||||
|
All files / folder names are case sensitive and must match.
|
||||||
|
|
||||||
|
PluginName - This is a directory and needs to be named as per the plugin you are creating.
|
||||||
|
|
||||||
|
PluginName.php - This file is used to process calls into the plugin from the main LibreNMS install.
|
||||||
|
Here only functions within the class for your plugin that LibreNMS calls will be executed.
|
||||||
|
For a list of currently enabled system hooks, please see further down.
|
||||||
|
The minimum code required in this file is (replace Test with the name of your plugin):
|
||||||
|
```
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
PluginName.inc.php - This file is the main included file when browsing to the plugin itself.
|
||||||
|
You can use this to display / edit / remove whatever you like.
|
||||||
|
The minimum code required in this file is:
|
||||||
|
```
|
||||||
|
<?php
|
||||||
|
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
### System Hooks ###
|
||||||
|
|
||||||
|
System hooks are called as functions within your plugin class, so for example to create a menu entry within the PLugin dropdown you would do:
|
||||||
|
|
||||||
|
```
|
||||||
|
public function menu() {
|
||||||
|
echo('<li><a href="plugin/p='.get_class().'">'.get_class().'</a></li>');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This would then add the name and a link to your plugin.
|
||||||
|
|
||||||
|
The following system hooks are currently available:
|
||||||
|
|
||||||
|
menu()
|
||||||
|
* This is called to build the plugin menu system and you can use this to link to your plugin (you don't have to).
|
68
html/includes/plugins.inc.php
Normal file
68
html/includes/plugins.inc.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Plugins
|
||||||
|
{
|
||||||
|
private static $plugins = array();
|
||||||
|
|
||||||
|
public static function start()
|
||||||
|
{
|
||||||
|
global $config;
|
||||||
|
if(file_exists($config['plugin_dir']))
|
||||||
|
{
|
||||||
|
//$plugin_files = scandir($config['plugin_dir']);
|
||||||
|
$plugin_files = dbFetchRows("SELECT * FROM `plugins` WHERE `plugin_active` = '1'");
|
||||||
|
foreach($plugin_files as $plugins)
|
||||||
|
{
|
||||||
|
$plugin_info = pathinfo($config['plugin_dir'].'/'.$plugins['plugin_name'].'/'.$plugins['plugin_name'].'.php');
|
||||||
|
if($plugin_info['extension'] == 'php')
|
||||||
|
{
|
||||||
|
if(is_file($config['plugin_dir'].'/'.$plugins['plugin_name'].'/'.$plugins['plugin_name'].'.php'))
|
||||||
|
{
|
||||||
|
self::load($config['plugin_dir'].'/'.$plugins['plugin_name'].'/'.$plugins['plugin_name'].'.php', $plugin_info['filename']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function load($file, $pluginName)
|
||||||
|
{
|
||||||
|
include($file);
|
||||||
|
$plugin = new $pluginName;
|
||||||
|
$hooks = get_class_methods($plugin);
|
||||||
|
|
||||||
|
foreach($hooks as $hookName)
|
||||||
|
{
|
||||||
|
if($hookName{0} != '_')
|
||||||
|
{
|
||||||
|
self::$plugins[$hookName][] = $pluginName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function call($hook, $params=false)
|
||||||
|
{
|
||||||
|
if(count(self::$plugins[$hook]) != 0)
|
||||||
|
{
|
||||||
|
foreach(self::$plugins[$hook] as $name)
|
||||||
|
{
|
||||||
|
if(!is_array($params))
|
||||||
|
{
|
||||||
|
call_user_func(array($name, $hook));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
call_user_func_array(array($name, $hook), $params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
@ -484,15 +484,19 @@ if(is_file("includes/print-menubar-custom.inc.php"))
|
|||||||
</form>
|
</form>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"> Plugins<b class="caret"></b></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
<?php
|
<?php
|
||||||
if($_SESSION['widescreen'] === 1)
|
Plugins::call('menu');
|
||||||
{
|
|
||||||
echo(' <a href="' . $toggle_url . 'widescreen=no" title="Switch to normal screen width layout">Normal width</a>');
|
|
||||||
} else {
|
|
||||||
echo(' <a href="' . $toggle_url . 'widescreen=yes" title="Switch to wide screen layout">Widescreen</a>');
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
<li role="presentation" class="divider"></li>
|
||||||
|
<?php
|
||||||
|
if ($_SESSION['userlevel'] >= '10')
|
||||||
|
{
|
||||||
|
echo(' <li><a href="plugin/view=admin">Plugin Admin</a></li>');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
<a href="#" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><img src="images/16/wrench.png" border="0" align="absmiddle" /> System<b class="caret"></b></a>
|
<a href="#" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><img src="images/16/wrench.png" border="0" align="absmiddle" /> System<b class="caret"></b></a>
|
||||||
|
@ -17,6 +17,8 @@ include("../config.php");
|
|||||||
include_once("../includes/definitions.inc.php");
|
include_once("../includes/definitions.inc.php");
|
||||||
include("../includes/functions.php");
|
include("../includes/functions.php");
|
||||||
include("includes/functions.inc.php");
|
include("includes/functions.inc.php");
|
||||||
|
include('includes/plugins.inc.php');
|
||||||
|
Plugins::start();
|
||||||
|
|
||||||
// Check for install.inc.php
|
// Check for install.inc.php
|
||||||
if (!file_exists('../config.php') && $_SERVER['PATH_INFO'] != '/install.php') {
|
if (!file_exists('../config.php') && $_SERVER['PATH_INFO'] != '/install.php') {
|
||||||
|
20
html/pages/plugin.inc.php
Normal file
20
html/pages/plugin.inc.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$link_array = array('page' => 'plugin');
|
||||||
|
|
||||||
|
$pagetitle[] = "Plugin";
|
||||||
|
|
||||||
|
if ($vars['view'] == "admin")
|
||||||
|
{
|
||||||
|
include_once('pages/plugin/admin.inc.php');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$plugin = dbFetchRow("SELECT `plugin_name` FROM `plugins` WHERE `plugin_name` = '".$vars['p']."'");
|
||||||
|
if(!empty($plugin))
|
||||||
|
{
|
||||||
|
require('plugins/'.$plugin['plugin_name'].'/'.$plugin['plugin_name'].'.inc.php');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
95
html/pages/plugin/admin.inc.php
Normal file
95
html/pages/plugin/admin.inc.php
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
if ($_SESSION['userlevel'] >= '10')
|
||||||
|
{
|
||||||
|
|
||||||
|
// Scan for new plugins and add to the database
|
||||||
|
$new_plugins = scan_new_plugins();
|
||||||
|
|
||||||
|
|
||||||
|
// Check if we have to toggle enabled / disable a particular module
|
||||||
|
$plugin_id = $_POST['plugin_id'];
|
||||||
|
$plugin_active = $_POST['plugin_active'];
|
||||||
|
if(is_numeric($plugin_id) && is_numeric($plugin_active))
|
||||||
|
{
|
||||||
|
if( $plugin_active == '0')
|
||||||
|
{
|
||||||
|
$plugin_active = 1;
|
||||||
|
}
|
||||||
|
elseif( $plugin_active == '1')
|
||||||
|
{
|
||||||
|
$plugin_active = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$plugin_active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbUpdate(array('plugin_active' => $plugin_active), 'plugins', '`plugin_id` = ?', array($plugin_id));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="panel panel-default panel-condensed">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<strong>System plugins</strong>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
if($new_plugins > 0)
|
||||||
|
{
|
||||||
|
echo('<div class="panel-body">
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
We have found ' . $new_plugins . ' new plugins that need to be configured and enabled
|
||||||
|
</div>
|
||||||
|
</div>');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<table class="table table-condensed">
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
foreach (dbFetchRows("SELECT * FROM plugins") as $plugins)
|
||||||
|
{
|
||||||
|
if($plugins['plugin_active'] == 1)
|
||||||
|
{
|
||||||
|
$plugin_colour = 'bg-success';
|
||||||
|
$plugin_button = 'danger';
|
||||||
|
$plugin_label = 'Disable';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$plugin_colour = 'bg-danger';
|
||||||
|
$plugin_button = 'success';
|
||||||
|
$plugin_label = 'Enable';
|
||||||
|
}
|
||||||
|
echo('<tr class="'. $plugin_colour .'">
|
||||||
|
<td>
|
||||||
|
'. $plugins['plugin_name'] . '
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<form class="form-inline" role="form" action="" method="post" id="'.$plugins['plugin_id'].'" name=="'.$plugins['plugin_id'].'">
|
||||||
|
<input type="hidden" name="plugin_id" value="'.$plugins['plugin_id'].'">
|
||||||
|
<input type="hidden" name="plugin_active" value="'.$plugins['plugin_active'].'">
|
||||||
|
<button type="submit" class="btn btn-sm btn-'.$plugin_button.'">'.$plugin_label.'</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>');
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
include("includes/error-no-perm.inc.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
2
html/plugins/.gitignore
vendored
Normal file
2
html/plugins/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
@ -1218,5 +1218,6 @@ if (!isset($config['html_dir'])) { $config['html_dir'] = $config['install_dir']
|
|||||||
if (!isset($config['rrd_dir'])) { $config['rrd_dir'] = $config['install_dir'] . '/rrd'; }
|
if (!isset($config['rrd_dir'])) { $config['rrd_dir'] = $config['install_dir'] . '/rrd'; }
|
||||||
if (!isset($config['log_dir'])) { $config['log_dir'] = $config['install_dir'] . '/logs'; }
|
if (!isset($config['log_dir'])) { $config['log_dir'] = $config['install_dir'] . '/logs'; }
|
||||||
if (!isset($config['log_file'])) { $config['log_dir'] . "/" . $config['project_id'] . ".log"; }
|
if (!isset($config['log_file'])) { $config['log_dir'] . "/" . $config['project_id'] . ".log"; }
|
||||||
|
if (!isset($config['plugin_dir'])) { $config['plugin_dir'] = $config['html_dir'] . '/plugins'; }
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -876,4 +876,40 @@ function is_port_valid($port, $device)
|
|||||||
return $valid;
|
return $valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function scan_new_plugins()
|
||||||
|
{
|
||||||
|
|
||||||
|
global $config, $debug;
|
||||||
|
|
||||||
|
$installed = 0; // Track how many plugins we install.
|
||||||
|
|
||||||
|
if(file_exists($config['plugin_dir']))
|
||||||
|
{
|
||||||
|
$plugin_files = scandir($config['plugin_dir']);
|
||||||
|
foreach($plugin_files as $name)
|
||||||
|
{
|
||||||
|
if(is_dir($config['plugin_dir'].'/'.$name))
|
||||||
|
{
|
||||||
|
if($name != '.' && $name != '..')
|
||||||
|
{
|
||||||
|
if(is_file($config['plugin_dir'].'/'.$name.'/'.$name.'.php') && is_file($config['plugin_dir'].'/'.$name.'/'.$name.'.inc.php'))
|
||||||
|
{
|
||||||
|
$plugin_id = dbFetchRow("SELECT `plugin_id` FROM `plugins` WHERE `plugin_name` = '$name'");
|
||||||
|
if(empty($plugin_id))
|
||||||
|
{
|
||||||
|
if(dbInsert(array('plugin_name' => $name, 'plugin_active' => '0'), 'plugins'))
|
||||||
|
{
|
||||||
|
$installed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return( $installed );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
1
sql-schema/030.sql
Normal file
1
sql-schema/030.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS `plugins` ( `plugin_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `plugin_name` VARCHAR( 60 ) NOT NULL , `plugin_active` INT NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
Reference in New Issue
Block a user