mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Support device group definitions from v2 (#4591)
* Support device group definitions from v2 Disable editing v2 groups. V2 Device groups are defined as follows: pattern = WHERE query with ? placeholders for values params = json encoded array of values * Can't array_unshift something that isn't an array...
This commit is contained in:
committed by
Neil Lathwood
parent
4f90d389c6
commit
02b84cf3f7
@@ -17,8 +17,7 @@ if (is_admin() === false) {
|
||||
}
|
||||
|
||||
$rule = implode(' ', $_POST['rules']);
|
||||
$rule = rtrim($rule, '&&');
|
||||
$rule = rtrim($rule, '||');
|
||||
$rule = rtrim($rule, '&|');
|
||||
$alert_id = $_POST['alert_id'];
|
||||
$count = mres($_POST['count']);
|
||||
$delay = mres($_POST['delay']);
|
||||
|
@@ -14,9 +14,13 @@ if (!empty($group_count_check)) {
|
||||
echo '<tr id="row_'.$group['id'].'">';
|
||||
echo '<td>'.$group['name'].'</td>';
|
||||
echo '<td>'.$group['desc'].'</td>';
|
||||
echo '<td>'.$group['pattern'].'</td>';
|
||||
echo '<td>'.formatDeviceGroupPattern($group['pattern'], json_decode($group['params'])).'</td>';
|
||||
echo '<td>';
|
||||
echo "<button type='button' class='btn btn-primary btn-sm' aria-label='Edit' data-toggle='modal' data-target='#create-group' data-group_id='".$group['id']."' name='edit-device-group'><i class='fa fa-pencil' aria-hidden='true'></i></button> ";
|
||||
echo "<button type='button' class='btn btn-primary btn-sm' aria-label='Edit' data-toggle='modal' data-target='#create-group' data-group_id='".$group['id']."' name='edit-device-group'";
|
||||
if (is_null($group['params'])) {
|
||||
echo " disabled title='LibreNMS V2 device groups cannot be edited in LibreNMS V1'";
|
||||
}
|
||||
echo "><i class='fa fa-pencil' aria-hidden='true'></i></button> ";
|
||||
echo "<button type='button' class='btn btn-danger btn-sm' aria-label='Delete' data-toggle='modal' data-target='#confirm-delete' data-group_id='".$group['id']."' name='delete-device-group'><i class='fa fa-trash' aria-hidden='true'></i></button>";
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
|
@@ -73,7 +73,8 @@ function EditDeviceGroup($group_id, $name = null, $desc = null, $pattern = null)
|
||||
/**
|
||||
* Generate SQL from Group-Pattern
|
||||
* @param string $pattern Pattern to generate SQL for
|
||||
* @param string $search What to searchid for
|
||||
* @param string $search What to searchid for
|
||||
* @param int $extra
|
||||
* @return string sql to perform the search
|
||||
*/
|
||||
function GenGroupSQL($pattern, $search = '', $extra = 0)
|
||||
@@ -82,23 +83,29 @@ function GenGroupSQL($pattern, $search = '', $extra = 0)
|
||||
if ($pattern === false) {
|
||||
return false;
|
||||
}
|
||||
$tmp = explode(' ', $pattern);
|
||||
$tables = array();
|
||||
foreach ($tmp as $opt) {
|
||||
if (strstr($opt, '%') && strstr($opt, '.')) {
|
||||
$tmpp = explode('.', $opt, 2);
|
||||
$tmpp[0] = str_replace('%', '', $tmpp[0]);
|
||||
$tables[] = mres(str_replace('(', '', $tmpp[0]));
|
||||
$pattern = str_replace($opt, $tmpp[0].'.'.$tmpp[1], $pattern);
|
||||
|
||||
if (starts_with($pattern, '%')) {
|
||||
// v1 pattern
|
||||
$tables = array();
|
||||
$words = explode(' ', $pattern);
|
||||
foreach ($words as $word) {
|
||||
if (starts_with($word, '%') && str_contains($word, '.')) {
|
||||
list($table, $column) = explode('.', $word, 2);
|
||||
$table = str_replace('%', '', $table);
|
||||
$tables[] = mres(str_replace('(', '', $table));
|
||||
$pattern = str_replace($word, $table . '.' . $column, $pattern);
|
||||
}
|
||||
}
|
||||
$tables = array_keys(array_flip($tables));
|
||||
} else {
|
||||
// v2 pattern
|
||||
$tables = getTablesFromPattern($pattern);
|
||||
}
|
||||
|
||||
$pattern = rtrim($pattern, '&&');
|
||||
$pattern = rtrim($pattern, '||');
|
||||
$pattern = rtrim($pattern, '&|');
|
||||
|
||||
$tables = array_keys(array_flip($tables));
|
||||
if (dbFetchCell('SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_NAME = ? && COLUMN_NAME = ?', array($tables[0],'device_id')) != 1) {
|
||||
//Our first table has no valid glue, append the 'devices' table to it!
|
||||
if ($tables[0] != 'devices' && dbFetchCell('SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_NAME = ? && COLUMN_NAME = ?', array($tables[0],'device_id')) != 1) {
|
||||
//Our first table has no valid glue, prepend the 'devices' table to it!
|
||||
array_unshift($tables, 'devices');
|
||||
}
|
||||
$x = sizeof($tables)-1;
|
||||
@@ -137,13 +144,28 @@ function GenGroupSQL($pattern, $search = '', $extra = 0)
|
||||
$search = str_replace("(", "", $tables[0]).'.'.$search. ' AND';
|
||||
}
|
||||
if (!empty($join)) {
|
||||
$join = '('.rtrim($join, ' && ').') &&';
|
||||
$join = '('.rtrim($join, '& ').') &&';
|
||||
}
|
||||
$sql = 'SELECT DISTINCT('.str_replace('(', '', $tables[0]).'.device_id)'.$sql_extra.' FROM '.implode(',', $tables).' WHERE '.$join.' '.$search.' ('.str_replace(array('%', '@', '!~', '~'), array('', '.*', 'NOT REGEXP', 'REGEXP'), $pattern).')';
|
||||
return $sql;
|
||||
}//end GenGroupSQL()
|
||||
|
||||
|
||||
/**
|
||||
* Extract an array of tables in a pattern
|
||||
*
|
||||
* @param string $pattern
|
||||
* @return array
|
||||
*/
|
||||
function getTablesFromPattern($pattern)
|
||||
{
|
||||
preg_match_all('/[A-Za-z_]+(?=\.[A-Za-z_]+ )/', $pattern, $tables);
|
||||
if (is_null($tables)) {
|
||||
return array();
|
||||
}
|
||||
return array_keys(array_flip($tables[0])); // unique tables only
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the group queries again to get fresh list of devices for this group
|
||||
* @param integer $group_id Group-ID
|
||||
@@ -151,11 +173,12 @@ function GenGroupSQL($pattern, $search = '', $extra = 0)
|
||||
*/
|
||||
function QueryDevicesFromGroup($group_id)
|
||||
{
|
||||
$pattern = dbFetchCell('SELECT pattern FROM device_groups WHERE id = ?', array($group_id));
|
||||
$pattern = rtrim($pattern, '&&');
|
||||
$pattern = rtrim($pattern, '||');
|
||||
$group = dbFetchRow('SELECT pattern,params FROM device_groups WHERE id = ?', array($group_id));
|
||||
$pattern = rtrim($group['pattern'], '&|');
|
||||
$params = (array)json_decode($group['params']);
|
||||
if (!empty($pattern)) {
|
||||
return dbFetchColumn(GenGroupSQL($pattern));
|
||||
$result = dbFetchColumn(GenGroupSQL($pattern), $params);
|
||||
return $result;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -196,7 +219,9 @@ function QueryGroupsFromDevice($device_id, $extra = 0)
|
||||
{
|
||||
$ret = array();
|
||||
foreach (GetDeviceGroups() as $group) {
|
||||
if (dbFetchCell(GenGroupSQL($group['pattern'], 'device_id=?', $extra).' LIMIT 1', array($device_id)) == $device_id) {
|
||||
$params = (array)json_decode($group['params']);
|
||||
array_unshift($params, $device_id);
|
||||
if (dbFetchCell(GenGroupSQL($group['pattern'], 'device_id=?', $extra).' LIMIT 1', $params) == $device_id) {
|
||||
if ($extra === 0) {
|
||||
$ret[] = $group['id'];
|
||||
} else {
|
||||
@@ -257,6 +282,7 @@ function RunGroupMacros($rule, $x = 1)
|
||||
*/
|
||||
function UpdateGroupsForDevice($device_id)
|
||||
{
|
||||
d_echo("### Start Device Groups ###\n");
|
||||
$queried_groups = QueryGroupsFromDevice($device_id);
|
||||
$db_groups = GetGroupsFromDevice($device_id);
|
||||
|
||||
@@ -264,6 +290,9 @@ function UpdateGroupsForDevice($device_id)
|
||||
$added_groups = array_diff($queried_groups, $db_groups);
|
||||
$removed_groups = array_diff($db_groups, $queried_groups);
|
||||
|
||||
d_echo("Groups Added: ".implode(',', $added_groups).PHP_EOL);
|
||||
d_echo("Groups Removed: ".implode(',', $removed_groups).PHP_EOL);
|
||||
|
||||
// insert new groups
|
||||
$insert = array();
|
||||
foreach ($added_groups as $group_id) {
|
||||
@@ -277,6 +306,7 @@ function UpdateGroupsForDevice($device_id)
|
||||
if (!empty($removed_groups)) {
|
||||
dbDelete('device_group_device', '`device_id`=? AND `device_group_id` IN (?)', array($device_id, array(implode(',', $removed_groups))));
|
||||
}
|
||||
d_echo("### End Device Groups ###\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -306,3 +336,22 @@ function UpdateDeviceGroup($group_id)
|
||||
dbDelete('device_group_device', '`device_group_id`=? AND `device_id` IN (?)', array($group_id, array(implode(',', $removed_devices))));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in params into the pattern, replacing placeholders (?)
|
||||
* If $params is empty or null, just returns $pattern
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function formatDeviceGroupPattern($pattern, $params)
|
||||
{
|
||||
// fill in parameters
|
||||
foreach ((array)$params as $value) {
|
||||
if (!is_numeric($value) && !starts_with($value, "'")) {
|
||||
$value = "'".$value."'";
|
||||
}
|
||||
$pattern = preg_replace('/\?/', $value, $pattern, 1);
|
||||
}
|
||||
|
||||
return $pattern;
|
||||
}
|
||||
|
1
sql-schema/139.sql
Normal file
1
sql-schema/139.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE `device_groups` ADD `params` TEXT NULL DEFAULT NULL AFTER `pattern`;
|
Reference in New Issue
Block a user