mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
* Device Groups rewrite Updated web ui Static or dynamic groups allowed Alert rule query builder Translation support Permissions support * cleanup, make relationship save, and validate it * builder WIP * rules builder and rules saving/loading * Parse query builder to Laravel Fluent query * Upgrade existing groups when editing. Properly update only dynamic groups when polling. * remove unused old code Update API and other places to use Eloquent * debug output in poller restored * Fix up some things creating static improved validation fix js error on creation Fix static groups in polling * hide pattern for static group * Implement authorization Use in the menu too * update schema * fix rollback * Don't abort on invalid queries * fixes to query builder * add test data, looks like macros aren't handled (omitted them because groups don't use them generally) * Add macro support for QueryBuilderFluentParser * add test for macro that accepts value * More space in forms Retain rules when converted to static no duplicate names allowed * Better error feedback Update related devices on save * Add button icon * format * update docs * fix tests
167 lines
5.2 KiB
PHP
167 lines
5.2 KiB
PHP
<?php
|
|
/**
|
|
* QueryBuilderFluentParser.php
|
|
*
|
|
* -Description-
|
|
*
|
|
* 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, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 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.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* @package LibreNMS
|
|
* @link http://librenms.org
|
|
* @copyright 2019 Tony Murray
|
|
* @author Tony Murray <murraytony@gmail.com>
|
|
*/
|
|
|
|
namespace LibreNMS\Alerting;
|
|
|
|
use DB;
|
|
use Illuminate\Database\Query\Builder;
|
|
use Log;
|
|
|
|
class QueryBuilderFluentParser extends QueryBuilderParser
|
|
{
|
|
/**
|
|
* Convert the query builder rules to a Laravel Fluent builder
|
|
*
|
|
* @return Builder
|
|
*/
|
|
public function toQuery()
|
|
{
|
|
if (empty($this->builder) || !array_key_exists('condition', $this->builder)) {
|
|
return null;
|
|
}
|
|
|
|
$query = DB::table('devices');
|
|
|
|
$this->joinTables($query);
|
|
|
|
$this->parseGroupToQuery($query, $this->builder);
|
|
|
|
return $query;
|
|
}
|
|
|
|
/**
|
|
* @param Builder $query
|
|
* @param array $rule
|
|
* @param string $condition AND or OR
|
|
* @return Builder
|
|
*/
|
|
protected function parseGroupToQuery($query, $rule, $condition = 'AND')
|
|
{
|
|
foreach ($rule['rules'] as $group_rule) {
|
|
if (array_key_exists('condition', $group_rule)) {
|
|
$query->where(function ($query) use ($group_rule) {
|
|
$this->parseGroupToQuery($query, $group_rule, $group_rule['condition']);
|
|
}, null, null, $condition);
|
|
} else {
|
|
$this->parseRuleToQuery($query, $group_rule, $condition);
|
|
}
|
|
}
|
|
return $query;
|
|
}
|
|
|
|
/**
|
|
* @param Builder $query
|
|
* @param array $rule
|
|
* @param string $condition AND or OR
|
|
* @return Builder
|
|
*/
|
|
protected function parseRuleToQuery($query, $rule, $condition = 'AND')
|
|
{
|
|
list($field, $op, $value) = $this->expandRule($rule);
|
|
|
|
switch ($op) {
|
|
case 'equal':
|
|
case 'not_equal':
|
|
case 'less':
|
|
case 'less_or_equal':
|
|
case 'greater':
|
|
case 'greater_or_equal':
|
|
case 'regex':
|
|
case 'not_regex':
|
|
return $query->where($field, self::$operators[$op], $value, $condition);
|
|
case 'contains':
|
|
case 'not_contains':
|
|
return $query->where($field, self::$operators[$op], "%$value%", $condition);
|
|
case 'begins_with':
|
|
case 'not_begins_with':
|
|
return $query->where($field, self::$operators[$op], "$value%", $condition);
|
|
case 'ends_with':
|
|
case 'not_ends_with':
|
|
return $query->where($field, self::$operators[$op], "%$value", $condition);
|
|
case 'is_empty':
|
|
case 'is_not_empty':
|
|
return $query->where($field, self::$operators[$op], '');
|
|
case 'is_null':
|
|
case 'is_not_null':
|
|
return $query->whereNull($field, $condition, $op == 'is_not_null');
|
|
case 'between':
|
|
case 'not_between':
|
|
return $query->whereBetween($field, $value, $condition, $op == 'not_between');
|
|
case 'in':
|
|
case 'not_in':
|
|
$values = preg_split('/[, ]/', $value);
|
|
if ($values !== false) {
|
|
return $query->whereIn($field, $values, $condition, $op == 'not_in');
|
|
}
|
|
Log::error('Could not parse in values, use comma or space delimiters');
|
|
break;
|
|
default:
|
|
Log::error('Unhandled QueryBuilderFluentParser operation: ' . $op);
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
|
|
/**
|
|
* Extract field, operator and value from the rule and expand macros and raw values
|
|
*
|
|
* @param array $rule
|
|
* @return array [field, operator, value]
|
|
*/
|
|
protected function expandRule($rule)
|
|
{
|
|
$field = $rule['field'];
|
|
if (starts_with($field, 'macros.')) {
|
|
$field = DB::raw($this->expandMacro($field));
|
|
}
|
|
|
|
$op = $rule['operator'];
|
|
|
|
$value = $rule['value'];
|
|
if (!is_array($value) && starts_with($value, '`') && ends_with($value, '`')) {
|
|
$value = DB::raw($this->expandMacro(trim($value, '`')));
|
|
}
|
|
|
|
return [$field, $op, $value];
|
|
}
|
|
|
|
/**
|
|
* @param Builder $query
|
|
* @return Builder
|
|
*/
|
|
protected function joinTables($query)
|
|
{
|
|
foreach ($this->generateGlue() as $glue) {
|
|
list($left, $right) = explode(' = ', $glue, 2);
|
|
if (str_contains($right, '.')) { // last line is devices.device_id = ? for alerting... ignore it
|
|
list($rightTable, $rightKey) = explode('.', $right);
|
|
$query->leftJoin($rightTable, $left, $right);
|
|
}
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
}
|