mirror of
https://github.com/librenms/librenms.git
synced 2024-09-21 02:18:39 +00:00
Apply fixes from StyleCI (#12117)
* Apply fixes from StyleCI * Disable style check
This commit is contained in:
parent
8ec9183df5
commit
77c531527c
@ -38,7 +38,6 @@ use LibreNMS\Alerting\QueryBuilderParser;
|
||||
|
||||
class AlertDB
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $rule
|
||||
* @param $query_builder
|
||||
@ -56,7 +55,7 @@ class AlertDB
|
||||
/**
|
||||
* Generate SQL from Rule
|
||||
* @param string $rule Rule to generate SQL for
|
||||
* @return string|boolean
|
||||
* @return string|bool
|
||||
*/
|
||||
public static function genSQLOld($rule)
|
||||
{
|
||||
@ -66,29 +65,29 @@ class AlertDB
|
||||
return false;
|
||||
}
|
||||
//Pretty-print rule to dissect easier
|
||||
$pretty = array('&&' => ' && ', '||' => ' || ');
|
||||
$pretty = ['&&' => ' && ', '||' => ' || '];
|
||||
$rule = str_replace(array_keys($pretty), $pretty, $rule);
|
||||
$tmp = explode(" ", $rule);
|
||||
$tables = array();
|
||||
$tables = [];
|
||||
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]));
|
||||
$rule = str_replace($opt, $tmpp[0].'.'.$tmpp[1], $rule);
|
||||
$rule = str_replace($opt, $tmpp[0] . '.' . $tmpp[1], $rule);
|
||||
}
|
||||
}
|
||||
$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) {
|
||||
if (dbFetchCell('SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_NAME = ? && COLUMN_NAME = ?', [$tables[0], 'device_id']) != 1) {
|
||||
//Our first table has no valid glue, append the 'devices' table to it!
|
||||
array_unshift($tables, 'devices');
|
||||
}
|
||||
$x = sizeof($tables)-1;
|
||||
$x = sizeof($tables) - 1;
|
||||
$i = 0;
|
||||
$join = "";
|
||||
while ($i < $x) {
|
||||
if (isset($tables[$i+1])) {
|
||||
$gtmp = ResolveGlues(array($tables[$i+1]), 'device_id');
|
||||
if (isset($tables[$i + 1])) {
|
||||
$gtmp = ResolveGlues([$tables[$i + 1]], 'device_id');
|
||||
if ($gtmp === false) {
|
||||
//Cannot resolve glue-chain. Rule is invalid.
|
||||
return false;
|
||||
@ -97,22 +96,23 @@ class AlertDB
|
||||
$qry = "";
|
||||
foreach ($gtmp as $glue) {
|
||||
if (empty($last)) {
|
||||
list($tmp,$last) = explode('.', $glue);
|
||||
$qry .= $glue.' = ';
|
||||
[$tmp,$last] = explode('.', $glue);
|
||||
$qry .= $glue . ' = ';
|
||||
} else {
|
||||
list($tmp,$new) = explode('.', $glue);
|
||||
$qry .= $tmp.'.'.$last.' && '.$tmp.'.'.$new.' = ';
|
||||
[$tmp,$new] = explode('.', $glue);
|
||||
$qry .= $tmp . '.' . $last . ' && ' . $tmp . '.' . $new . ' = ';
|
||||
$last = $new;
|
||||
}
|
||||
if (!in_array($tmp, $tables)) {
|
||||
if (! in_array($tmp, $tables)) {
|
||||
$tables[] = $tmp;
|
||||
}
|
||||
}
|
||||
$join .= "( ".$qry.$tables[0].".device_id ) && ";
|
||||
$join .= "( " . $qry . $tables[0] . ".device_id ) && ";
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
$sql = "SELECT * FROM ".implode(",", $tables)." WHERE (".$join."".str_replace("(", "", $tables[0]).".device_id = ?) && (".str_replace(array("%","@","!~","~"), array("",".*","NOT REGEXP","REGEXP"), $rule).")";
|
||||
$sql = "SELECT * FROM " . implode(",", $tables) . " WHERE (" . $join . "" . str_replace("(", "", $tables[0]) . ".device_id = ?) && (" . str_replace(["%", "@", "!~", "~"], ["", ".*", "NOT REGEXP", "REGEXP"], $rule) . ")";
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ class AlertData extends \Illuminate\Support\Collection
|
||||
if ($this->has($name)) {
|
||||
return $this->get($name);
|
||||
}
|
||||
|
||||
return "$name is not a valid \$alert data name";
|
||||
}
|
||||
}
|
||||
|
@ -35,8 +35,8 @@ namespace LibreNMS\Alert;
|
||||
|
||||
use App\Models\Device;
|
||||
use Carbon\Carbon;
|
||||
use LibreNMS\Alert\AlertUtil;
|
||||
use LibreNMS\Alert\AlertDB;
|
||||
use LibreNMS\Alert\AlertUtil;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class AlertRules
|
||||
@ -47,6 +47,7 @@ class AlertRules
|
||||
//Check to see if under maintenance
|
||||
if (AlertUtil::isMaintenance($device_id) > 0) {
|
||||
echo "Under Maintenance, skipping alert rules check.\r\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
//Check to see if disable alerting is set
|
||||
@ -55,12 +56,13 @@ class AlertRules
|
||||
$device_alert['state'] = AlertState::CLEAR;
|
||||
$device_alert['alerted'] = 0;
|
||||
$device_alert['open'] = 0;
|
||||
dbUpdate($device_alert, 'alerts', '`device_id` = ?', array($device_id));
|
||||
dbUpdate($device_alert, 'alerts', '`device_id` = ?', [$device_id]);
|
||||
|
||||
return false;
|
||||
}
|
||||
//Checks each rule.
|
||||
foreach (AlertUtil::getRules($device_id) as $rule) {
|
||||
c_echo('Rule %p#'.$rule['id'].' (' . $rule['name'] . '):%n ');
|
||||
c_echo('Rule %p#' . $rule['id'] . ' (' . $rule['name'] . '):%n ');
|
||||
$extra = json_decode($rule['extra'], true);
|
||||
if (isset($extra['invert'])) {
|
||||
$inv = (bool) $extra['invert'];
|
||||
@ -72,7 +74,7 @@ class AlertRules
|
||||
$rule['query'] = AlertDB::genSQL($rule['rule'], $rule['builder']);
|
||||
}
|
||||
$sql = $rule['query'];
|
||||
$qry = dbFetchRows($sql, array($device_id));
|
||||
$qry = dbFetchRows($sql, [$device_id]);
|
||||
$cnt = count($qry);
|
||||
for ($i = 0; $i < $cnt; $i++) {
|
||||
if (isset($qry[$i]['ip'])) {
|
||||
@ -99,20 +101,20 @@ class AlertRules
|
||||
// NOCHG here doesn't mean no change full stop. It means no change to the alert state
|
||||
// So we update the details column with any fresh changes to the alert output we might have.
|
||||
$alert_log = dbFetchRow('SELECT alert_log.id, alert_log.details FROM alert_log,alert_rules WHERE alert_log.rule_id = alert_rules.id && alert_log.device_id = ? && alert_log.rule_id = ? && alert_rules.disabled = 0
|
||||
ORDER BY alert_log.id DESC LIMIT 1', array($device_id, $rule['id']));
|
||||
ORDER BY alert_log.id DESC LIMIT 1', [$device_id, $rule['id']]);
|
||||
$details = [];
|
||||
if (!empty($alert_log['details'])) {
|
||||
if (! empty($alert_log['details'])) {
|
||||
$details = json_decode(gzuncompress($alert_log['details']), true);
|
||||
}
|
||||
$details['contacts'] = AlertUtil::getContacts($qry);
|
||||
$details['rule'] = $qry;
|
||||
$details = gzcompress(json_encode($details), 9);
|
||||
dbUpdate(array('details' => $details), 'alert_log', 'id = ?', array($alert_log['id']));
|
||||
dbUpdate(['details' => $details], 'alert_log', 'id = ?', [$alert_log['id']]);
|
||||
} else {
|
||||
$extra = gzcompress(json_encode(array('contacts' => AlertUtil::getContacts($qry), 'rule'=>$qry)), 9);
|
||||
$extra = gzcompress(json_encode(['contacts' => AlertUtil::getContacts($qry), 'rule'=>$qry]), 9);
|
||||
if (dbInsert(['state' => AlertState::ACTIVE, 'device_id' => $device_id, 'rule_id' => $rule['id'], 'details' => $extra], 'alert_log')) {
|
||||
if (is_null($current_state)) {
|
||||
dbInsert(array('state' => AlertState::ACTIVE, 'device_id' => $device_id, 'rule_id' => $rule['id'], 'open' => 1,'alerted' => 0), 'alerts');
|
||||
dbInsert(['state' => AlertState::ACTIVE, 'device_id' => $device_id, 'rule_id' => $rule['id'], 'open' => 1, 'alerted' => 0], 'alerts');
|
||||
} else {
|
||||
dbUpdate(['state' => AlertState::ACTIVE, 'open' => 1, 'timestamp' => Carbon::now()], 'alerts', 'device_id = ? && rule_id = ?', [$device_id, $rule['id']]);
|
||||
}
|
||||
@ -120,7 +122,7 @@ class AlertRules
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!is_null($current_state) && $current_state == AlertState::RECOVERED) {
|
||||
if (! is_null($current_state) && $current_state == AlertState::RECOVERED) {
|
||||
c_echo('Status: %bNOCHG');
|
||||
} else {
|
||||
if (dbInsert(['state' => AlertState::RECOVERED, 'device_id' => $device_id, 'rule_id' => $rule['id']], 'alert_log')) {
|
||||
|
@ -34,7 +34,6 @@ use PHPMailer\PHPMailer\PHPMailer;
|
||||
class AlertUtil
|
||||
{
|
||||
/**
|
||||
*
|
||||
* Get the rule_id for a specific alert
|
||||
*
|
||||
* @param $alert_id
|
||||
@ -43,11 +42,11 @@ class AlertUtil
|
||||
private static function getRuleId($alert_id)
|
||||
{
|
||||
$query = "SELECT `rule_id` FROM `alerts` WHERE `id`=?";
|
||||
|
||||
return dbFetchCell($query, [$alert_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the transport for a given alert_id
|
||||
*
|
||||
* @param $alert_id
|
||||
@ -57,11 +56,11 @@ class AlertUtil
|
||||
{
|
||||
$query = "SELECT b.transport_id, b.transport_type, b.transport_name FROM alert_transport_map AS a LEFT JOIN alert_transports AS b ON b.transport_id=a.transport_or_group_id WHERE a.target_type='single' AND a.rule_id=? UNION DISTINCT SELECT d.transport_id, d.transport_type, d.transport_name FROM alert_transport_map AS a LEFT JOIN alert_transport_groups AS b ON a.transport_or_group_id=b.transport_group_id LEFT JOIN transport_group_transport AS c ON b.transport_group_id=c.transport_group_id LEFT JOIN alert_transports AS d ON c.transport_id=d.transport_id WHERE a.target_type='group' AND a.rule_id=?";
|
||||
$rule_id = self::getRuleId($alert_id);
|
||||
|
||||
return dbFetchRows($query, [$rule_id, $rule_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns the default transports
|
||||
*
|
||||
* @return array
|
||||
@ -69,6 +68,7 @@ class AlertUtil
|
||||
public static function getDefaultAlertTransports()
|
||||
{
|
||||
$query = "SELECT transport_id, transport_type, transport_name FROM alert_transports WHERE is_default=true";
|
||||
|
||||
return dbFetchRows($query);
|
||||
}
|
||||
|
||||
@ -84,21 +84,22 @@ class AlertUtil
|
||||
}
|
||||
if (Config::get('alert.default_only') === true || Config::get('alerts.email.default_only') === true) {
|
||||
$email = Config::get('alert.default_mail', Config::get('alerts.email.default'));
|
||||
|
||||
return $email ? [$email => ''] : [];
|
||||
}
|
||||
$users = User::query()->thisAuth()->get();
|
||||
$contacts = array();
|
||||
$uids = array();
|
||||
$contacts = [];
|
||||
$uids = [];
|
||||
foreach ($results as $result) {
|
||||
$tmp = null;
|
||||
if (is_numeric($result["bill_id"])) {
|
||||
$tmpa = dbFetchRows("SELECT user_id FROM bill_perms WHERE bill_id = ?", array($result["bill_id"]));
|
||||
$tmpa = dbFetchRows("SELECT user_id FROM bill_perms WHERE bill_id = ?", [$result["bill_id"]]);
|
||||
foreach ($tmpa as $tmp) {
|
||||
$uids[$tmp['user_id']] = $tmp['user_id'];
|
||||
}
|
||||
}
|
||||
if (is_numeric($result["port_id"])) {
|
||||
$tmpa = dbFetchRows("SELECT user_id FROM ports_perms WHERE port_id = ?", array($result["port_id"]));
|
||||
$tmpa = dbFetchRows("SELECT user_id FROM ports_perms WHERE port_id = ?", [$result["port_id"]]);
|
||||
foreach ($tmpa as $tmp) {
|
||||
$uids[$tmp['user_id']] = $tmp['user_id'];
|
||||
}
|
||||
@ -106,15 +107,15 @@ class AlertUtil
|
||||
if (is_numeric($result["device_id"])) {
|
||||
if (Config::get('alert.syscontact') == true) {
|
||||
if (dbFetchCell("SELECT attrib_value FROM devices_attribs WHERE attrib_type = 'override_sysContact_bool' AND device_id = ?", [$result["device_id"]])) {
|
||||
$tmpa = dbFetchCell("SELECT attrib_value FROM devices_attribs WHERE attrib_type = 'override_sysContact_string' AND device_id = ?", array($result["device_id"]));
|
||||
$tmpa = dbFetchCell("SELECT attrib_value FROM devices_attribs WHERE attrib_type = 'override_sysContact_string' AND device_id = ?", [$result["device_id"]]);
|
||||
} else {
|
||||
$tmpa = dbFetchCell("SELECT sysContact FROM devices WHERE device_id = ?", array($result["device_id"]));
|
||||
$tmpa = dbFetchCell("SELECT sysContact FROM devices WHERE device_id = ?", [$result["device_id"]]);
|
||||
}
|
||||
if (!empty($tmpa)) {
|
||||
if (! empty($tmpa)) {
|
||||
$contacts[$tmpa] = '';
|
||||
}
|
||||
}
|
||||
$tmpa = dbFetchRows("SELECT user_id FROM devices_perms WHERE device_id = ?", array($result["device_id"]));
|
||||
$tmpa = dbFetchRows("SELECT user_id FROM devices_perms WHERE device_id = ?", [$result["device_id"]]);
|
||||
foreach ($tmpa as $tmp) {
|
||||
$uids[$tmp['user_id']] = $tmp['user_id'];
|
||||
}
|
||||
@ -127,7 +128,7 @@ class AlertUtil
|
||||
if (empty($user['realname'])) {
|
||||
$user['realname'] = $user['username'];
|
||||
}
|
||||
if (Config::get('alert.globals') && ( $user['level'] >= 5 && $user['level'] < 10 )) {
|
||||
if (Config::get('alert.globals') && ($user['level'] >= 5 && $user['level'] < 10)) {
|
||||
$contacts[$user['email']] = $user['realname'];
|
||||
} elseif (Config::get('alert.admins') && $user['level'] == 10) {
|
||||
$contacts[$user['email']] = $user['realname'];
|
||||
@ -136,12 +137,12 @@ class AlertUtil
|
||||
}
|
||||
}
|
||||
|
||||
$tmp_contacts = array();
|
||||
$tmp_contacts = [];
|
||||
foreach ($contacts as $email => $name) {
|
||||
if (strstr($email, ',')) {
|
||||
$split_contacts = preg_split('/[,\s]+/', $email);
|
||||
foreach ($split_contacts as $split_email) {
|
||||
if (!empty($split_email)) {
|
||||
if (! empty($split_email)) {
|
||||
$tmp_contacts[$split_email] = $name;
|
||||
}
|
||||
}
|
||||
@ -150,7 +151,7 @@ class AlertUtil
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($tmp_contacts)) {
|
||||
if (! empty($tmp_contacts)) {
|
||||
// Validate contacts so we can fall back to default if configured.
|
||||
$mail = new PHPMailer();
|
||||
foreach ($tmp_contacts as $tmp_email => $tmp_name) {
|
||||
@ -160,12 +161,12 @@ class AlertUtil
|
||||
}
|
||||
}
|
||||
|
||||
# Copy all email alerts to default contact if configured.
|
||||
// Copy all email alerts to default contact if configured.
|
||||
$default_mail = Config::get('alert.default_mail');
|
||||
if (!isset($tmp_contacts[$default_mail]) && Config::get('alert.default_copy')) {
|
||||
if (! isset($tmp_contacts[$default_mail]) && Config::get('alert.default_copy')) {
|
||||
$tmp_contacts[$default_mail] = '';
|
||||
}
|
||||
# Send email to default contact if no other contact found
|
||||
// Send email to default contact if no other contact found
|
||||
if (empty($tmp_contacts) && Config::get('alert.default_if_none') && $default_mail) {
|
||||
$tmp_contacts[$default_mail] = '';
|
||||
}
|
||||
@ -187,6 +188,7 @@ class AlertUtil
|
||||
)";
|
||||
|
||||
$params = [$device_id, $device_id, $device_id, $device_id, $device_id, $device_id, $device_id, $device_id];
|
||||
|
||||
return dbFetchRows($query, $params);
|
||||
}
|
||||
|
||||
@ -208,22 +210,23 @@ class AlertUtil
|
||||
public static function hasDisableNotify($device_id)
|
||||
{
|
||||
$device = Device::find($device_id);
|
||||
return !is_null($device) && $device->disable_notify;
|
||||
|
||||
return ! is_null($device) && $device->disable_notify;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Macros
|
||||
* @param string $rule Rule to process
|
||||
* @param int $x Recursion-Anchor
|
||||
* @return string|boolean
|
||||
* @return string|bool
|
||||
*/
|
||||
public static function runMacros($rule, $x = 1)
|
||||
{
|
||||
$macros = Config::get('alert.macros.rule', []) .
|
||||
krsort($macros);
|
||||
foreach ($macros as $macro => $value) {
|
||||
if (!strstr($macro, " ")) {
|
||||
$rule = str_replace('%macros.'.$macro, '('.$value.')', $rule);
|
||||
if (! strstr($macro, " ")) {
|
||||
$rule = str_replace('%macros.' . $macro, '(' . $value . ')', $rule);
|
||||
}
|
||||
}
|
||||
if (strstr($rule, "%macros.")) {
|
||||
@ -233,6 +236,7 @@ class AlertUtil
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $rule;
|
||||
}
|
||||
}
|
||||
|
@ -32,18 +32,17 @@ namespace LibreNMS\Alert;
|
||||
|
||||
use App\Models\DevicePerf;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\Util\Time;
|
||||
use LibreNMS\Enum\Alert;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Util\Time;
|
||||
use Log;
|
||||
|
||||
class RunAlerts
|
||||
{
|
||||
|
||||
/**
|
||||
* Populate variables
|
||||
* @param string $txt Text with variables
|
||||
* @param boolean $wrap Wrap variable for text-usage (default: true)
|
||||
* @param bool $wrap Wrap variable for text-usage (default: true)
|
||||
* @return string
|
||||
*/
|
||||
public function populate($txt, $wrap = true)
|
||||
@ -53,37 +52,38 @@ class RunAlerts
|
||||
$orig = $tmp;
|
||||
$rep = false;
|
||||
if ($tmp == 'key' || $tmp == 'value') {
|
||||
$rep = '$'.$tmp;
|
||||
$rep = '$' . $tmp;
|
||||
} else {
|
||||
if (strstr($tmp, '.')) {
|
||||
$tmp = explode('.', $tmp, 2);
|
||||
$pre = '$'.$tmp[0];
|
||||
$pre = '$' . $tmp[0];
|
||||
$tmp = $tmp[1];
|
||||
} else {
|
||||
$pre = '$obj';
|
||||
}
|
||||
|
||||
$rep = $pre."['".str_replace('.', "']['", $tmp)."']";
|
||||
$rep = $pre . "['" . str_replace('.', "']['", $tmp) . "']";
|
||||
if ($wrap) {
|
||||
$rep = '{'.$rep.'}';
|
||||
$rep = '{' . $rep . '}';
|
||||
}
|
||||
}
|
||||
|
||||
$txt = str_replace('%'.$orig, $rep, $txt);
|
||||
$txt = str_replace('%' . $orig, $rep, $txt);
|
||||
}
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe Alert
|
||||
* @param array $alert Alert-Result from DB
|
||||
* @return array|boolean
|
||||
* @return array|bool
|
||||
*/
|
||||
public function describeAlert($alert)
|
||||
{
|
||||
$obj = array();
|
||||
$obj = [];
|
||||
$i = 0;
|
||||
$device = dbFetchRow('SELECT hostname, sysName, sysDescr, sysContact, os, type, ip, hardware, version, purpose, notes, uptime, status, status_reason, locations.location FROM devices LEFT JOIN locations ON locations.id = devices.location_id WHERE device_id = ?', array($alert['device_id']));
|
||||
$device = dbFetchRow('SELECT hostname, sysName, sysDescr, sysContact, os, type, ip, hardware, version, purpose, notes, uptime, status, status_reason, locations.location FROM devices LEFT JOIN locations ON locations.id = devices.location_id WHERE device_id = ?', [$alert['device_id']]);
|
||||
$attribs = get_dev_attribs($alert['device_id']);
|
||||
|
||||
$obj['hostname'] = $device['hostname'];
|
||||
@ -125,7 +125,7 @@ class RunAlerts
|
||||
$template = $tpl->getTemplate($obj);
|
||||
|
||||
if ($alert['state'] >= AlertState::ACTIVE) {
|
||||
$obj['title'] = $template->title ?: 'Alert for device '.$device['hostname'].' - '.($alert['name'] ? $alert['name'] : $alert['rule']);
|
||||
$obj['title'] = $template->title ?: 'Alert for device ' . $device['hostname'] . ' - ' . ($alert['name'] ? $alert['name'] : $alert['rule']);
|
||||
if ($alert['state'] == AlertState::ACKNOWLEDGED) {
|
||||
$obj['title'] .= ' got acknowledged';
|
||||
} elseif ($alert['state'] == AlertState::WORSE) {
|
||||
@ -139,40 +139,40 @@ class RunAlerts
|
||||
$obj['faults'][$i] = $incident;
|
||||
$obj['faults'][$i]['string'] = null;
|
||||
foreach ($incident as $k => $v) {
|
||||
if (!empty($v) && $k != 'device_id' && (stristr($k, 'id') || stristr($k, 'desc') || stristr($k, 'msg')) && substr_count($k, '_') <= 1) {
|
||||
$obj['faults'][$i]['string'] .= $k.' = '.$v.'; ';
|
||||
if (! empty($v) && $k != 'device_id' && (stristr($k, 'id') || stristr($k, 'desc') || stristr($k, 'msg')) && substr_count($k, '_') <= 1) {
|
||||
$obj['faults'][$i]['string'] .= $k . ' = ' . $v . '; ';
|
||||
}
|
||||
}
|
||||
}
|
||||
$obj['elapsed'] = $this->timeFormat(time() - strtotime($alert['time_logged']));
|
||||
if (!empty($extra['diff'])) {
|
||||
if (! empty($extra['diff'])) {
|
||||
$obj['diff'] = $extra['diff'];
|
||||
}
|
||||
} elseif ($alert['state'] == AlertState::RECOVERED) {
|
||||
// Alert is now cleared
|
||||
$id = dbFetchRow('SELECT alert_log.id,alert_log.time_logged,alert_log.details FROM alert_log WHERE alert_log.state != ? && alert_log.state != ? && alert_log.rule_id = ? && alert_log.device_id = ? && alert_log.id < ? ORDER BY id DESC LIMIT 1', array(AlertState::ACKNOWLEDGED, AlertState::RECOVERED, $alert['rule_id'], $alert['device_id'], $alert['id']));
|
||||
$id = dbFetchRow('SELECT alert_log.id,alert_log.time_logged,alert_log.details FROM alert_log WHERE alert_log.state != ? && alert_log.state != ? && alert_log.rule_id = ? && alert_log.device_id = ? && alert_log.id < ? ORDER BY id DESC LIMIT 1', [AlertState::ACKNOWLEDGED, AlertState::RECOVERED, $alert['rule_id'], $alert['device_id'], $alert['id']]);
|
||||
if (empty($id['id'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$extra = [];
|
||||
if (!empty($id['details'])) {
|
||||
if (! empty($id['details'])) {
|
||||
$extra = json_decode(gzuncompress($id['details']), true);
|
||||
}
|
||||
|
||||
// Reset count to 0 so alerts will continue
|
||||
$extra['count'] = 0;
|
||||
dbUpdate(array('details' => gzcompress(json_encode($id['details']), 9)), 'alert_log', 'id = ?', array($alert['id']));
|
||||
dbUpdate(['details' => gzcompress(json_encode($id['details']), 9)], 'alert_log', 'id = ?', [$alert['id']]);
|
||||
|
||||
$obj['title'] = $template->title_rec ?: 'Device '.$device['hostname'].' recovered from '.($alert['name'] ? $alert['name'] : $alert['rule']);
|
||||
$obj['title'] = $template->title_rec ?: 'Device ' . $device['hostname'] . ' recovered from ' . ($alert['name'] ? $alert['name'] : $alert['rule']);
|
||||
$obj['elapsed'] = $this->timeFormat(strtotime($alert['time_logged']) - strtotime($id['time_logged']));
|
||||
$obj['id'] = $id['id'];
|
||||
foreach ($extra['rule'] as $incident) {
|
||||
$i++;
|
||||
$obj['faults'][$i] = $incident;
|
||||
foreach ($incident as $k => $v) {
|
||||
if (!empty($v) && $k != 'device_id' && (stristr($k, 'id') || stristr($k, 'desc') || stristr($k, 'msg')) && substr_count($k, '_') <= 1) {
|
||||
$obj['faults'][$i]['string'] .= $k.' => '.$v.'; ';
|
||||
if (! empty($v) && $k != 'device_id' && (stristr($k, 'id') || stristr($k, 'desc') || stristr($k, 'msg')) && substr_count($k, '_') <= 1) {
|
||||
$obj['faults'][$i]['string'] .= $k . ' => ' . $v . '; ';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -190,28 +190,29 @@ class RunAlerts
|
||||
$obj['state'] = $alert['state'];
|
||||
$obj['alerted'] = $alert['alerted'];
|
||||
$obj['template'] = $template;
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format Elapsed Time
|
||||
* @param integer $secs Seconds elapsed
|
||||
* @param int $secs Seconds elapsed
|
||||
* @return string
|
||||
*/
|
||||
public function timeFormat($secs)
|
||||
{
|
||||
$bit = array(
|
||||
$bit = [
|
||||
'y' => $secs / 31556926 % 12,
|
||||
'w' => $secs / 604800 % 52,
|
||||
'd' => $secs / 86400 % 7,
|
||||
'h' => $secs / 3600 % 24,
|
||||
'm' => $secs / 60 % 60,
|
||||
's' => $secs % 60,
|
||||
);
|
||||
$ret = array();
|
||||
];
|
||||
$ret = [];
|
||||
foreach ($bit as $k => $v) {
|
||||
if ($v > 0) {
|
||||
$ret[] = $v.$k;
|
||||
$ret[] = $v . $k;
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,10 +225,10 @@ class RunAlerts
|
||||
|
||||
public function clearStaleAlerts()
|
||||
{
|
||||
$sql = "SELECT `alerts`.`id` AS `alert_id`, `devices`.`hostname` AS `hostname` FROM `alerts` LEFT JOIN `devices` ON `alerts`.`device_id`=`devices`.`device_id` RIGHT JOIN `alert_rules` ON `alerts`.`rule_id`=`alert_rules`.`id` WHERE `alerts`.`state`!=".AlertState::CLEAR." AND `devices`.`hostname` IS NULL";
|
||||
$sql = "SELECT `alerts`.`id` AS `alert_id`, `devices`.`hostname` AS `hostname` FROM `alerts` LEFT JOIN `devices` ON `alerts`.`device_id`=`devices`.`device_id` RIGHT JOIN `alert_rules` ON `alerts`.`rule_id`=`alert_rules`.`id` WHERE `alerts`.`state`!=" . AlertState::CLEAR . " AND `devices`.`hostname` IS NULL";
|
||||
foreach (dbFetchRows($sql) as $alert) {
|
||||
if (empty($alert['hostname']) && isset($alert['alert_id'])) {
|
||||
dbDelete('alerts', '`id` = ?', array($alert['alert_id']));
|
||||
dbDelete('alerts', '`id` = ?', [$alert['alert_id']]);
|
||||
echo "Stale-alert: #{$alert['alert_id']}" . PHP_EOL;
|
||||
}
|
||||
}
|
||||
@ -235,14 +236,14 @@ class RunAlerts
|
||||
|
||||
/**
|
||||
* Re-Validate Rule-Mappings
|
||||
* @param integer $device_id Device-ID
|
||||
* @param integer $rule Rule-ID
|
||||
* @return boolean
|
||||
* @param int $device_id Device-ID
|
||||
* @param int $rule Rule-ID
|
||||
* @return bool
|
||||
*/
|
||||
public function isRuleValid($device_id, $rule)
|
||||
{
|
||||
global $rulescache;
|
||||
if (empty($rulescache[$device_id]) || !isset($rulescache[$device_id])) {
|
||||
if (empty($rulescache[$device_id]) || ! isset($rulescache[$device_id])) {
|
||||
foreach (AlertUtil::getRules($device_id) as $chk) {
|
||||
$rulescache[$device_id][$chk['id']] = true;
|
||||
}
|
||||
@ -255,11 +256,10 @@ class RunAlerts
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Issue Alert-Object
|
||||
* @param array $alert
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function issueAlert($alert)
|
||||
{
|
||||
@ -268,13 +268,13 @@ class RunAlerts
|
||||
$alert['query'] = AlertDB::genSQL($alert['rule'], $alert['builder']);
|
||||
}
|
||||
$sql = $alert['query'];
|
||||
$qry = dbFetchRows($sql, array($alert['device_id']));
|
||||
$qry = dbFetchRows($sql, [$alert['device_id']]);
|
||||
$alert['details']['contacts'] = AlertUtil::getContacts($qry);
|
||||
}
|
||||
|
||||
$obj = $this->describeAlert($alert);
|
||||
if (is_array($obj)) {
|
||||
echo 'Issuing Alert-UID #'.$alert['id'].'/'.$alert['state'].':' . PHP_EOL;
|
||||
echo 'Issuing Alert-UID #' . $alert['id'] . '/' . $alert['state'] . ':' . PHP_EOL;
|
||||
$this->extTransports($obj);
|
||||
|
||||
echo "\r\n";
|
||||
@ -283,17 +283,15 @@ class RunAlerts
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Issue ACK notification
|
||||
* @return void
|
||||
*/
|
||||
public function runAcks()
|
||||
{
|
||||
|
||||
foreach ($this->loadAlerts('alerts.state = '.AlertState::ACKNOWLEDGED.' && alerts.open = '.AlertState::ACTIVE) as $alert) {
|
||||
foreach ($this->loadAlerts('alerts.state = ' . AlertState::ACKNOWLEDGED . ' && alerts.open = ' . AlertState::ACTIVE) as $alert) {
|
||||
$this->issueAlert($alert);
|
||||
dbUpdate(array('open' => AlertState::CLEAR), 'alerts', 'rule_id = ? && device_id = ?', array($alert['rule_id'], $alert['device_id']));
|
||||
dbUpdate(['open' => AlertState::CLEAR], 'alerts', 'rule_id = ? && device_id = ?', [$alert['rule_id'], $alert['device_id']]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,7 +301,7 @@ class RunAlerts
|
||||
*/
|
||||
public function runFollowUp()
|
||||
{
|
||||
foreach ($this->loadAlerts('alerts.state > '.AlertState::CLEAR.' && alerts.open = 0') as $alert) {
|
||||
foreach ($this->loadAlerts('alerts.state > ' . AlertState::CLEAR . ' && alerts.open = 0') as $alert) {
|
||||
if ($alert['state'] != AlertState::ACKNOWLEDGED || ($alert['info']['until_clear'] === false)) {
|
||||
$rextra = json_decode($alert['extra'], true);
|
||||
if ($rextra['invert']) {
|
||||
@ -313,7 +311,7 @@ class RunAlerts
|
||||
if (empty($alert['query'])) {
|
||||
$alert['query'] = AlertDB::genSQL($alert['rule'], $alert['builder']);
|
||||
}
|
||||
$chk = dbFetchRows($alert['query'], array($alert['device_id']));
|
||||
$chk = dbFetchRows($alert['query'], [$alert['device_id']]);
|
||||
//make sure we can json_encode all the datas later
|
||||
$cnt = count($chk);
|
||||
for ($i = 0; $i < $cnt; $i++) {
|
||||
@ -337,13 +335,13 @@ class RunAlerts
|
||||
|
||||
if ($state > AlertState::CLEAR && $n > 0) {
|
||||
$alert['details']['rule'] = $chk;
|
||||
if (dbInsert(array(
|
||||
if (dbInsert([
|
||||
'state' => $state,
|
||||
'device_id' => $alert['device_id'],
|
||||
'rule_id' => $alert['rule_id'],
|
||||
'details' => gzcompress(json_encode($alert['details']), 9)
|
||||
), 'alert_log')) {
|
||||
dbUpdate(array('state' => $state, 'open' => 1, 'alerted' => 1), 'alerts', 'rule_id = ? && device_id = ?', array($alert['rule_id'], $alert['device_id']));
|
||||
'details' => gzcompress(json_encode($alert['details']), 9),
|
||||
], 'alert_log')) {
|
||||
dbUpdate(['state' => $state, 'open' => 1, 'alerted' => 1], 'alerts', 'rule_id = ? && device_id = ?', [$alert['rule_id'], $alert['device_id']]);
|
||||
}
|
||||
|
||||
echo $ret . ' (' . $o . '/' . $n . ")\r\n";
|
||||
@ -358,10 +356,10 @@ class RunAlerts
|
||||
foreach (dbFetchRows("SELECT alerts.id, alerts.alerted, alerts.device_id, alerts.rule_id, alerts.state, alerts.note, alerts.info FROM alerts WHERE $where") as $alert_status) {
|
||||
$alert = dbFetchRow(
|
||||
'SELECT alert_log.id,alert_log.rule_id,alert_log.device_id,alert_log.state,alert_log.details,alert_log.time_logged,alert_rules.rule,alert_rules.severity,alert_rules.extra,alert_rules.name,alert_rules.query,alert_rules.builder,alert_rules.proc FROM alert_log,alert_rules WHERE alert_log.rule_id = alert_rules.id && alert_log.device_id = ? && alert_log.rule_id = ? && alert_rules.disabled = 0 ORDER BY alert_log.id DESC LIMIT 1',
|
||||
array($alert_status['device_id'], $alert_status['rule_id'])
|
||||
[$alert_status['device_id'], $alert_status['rule_id']]
|
||||
);
|
||||
|
||||
if (empty($alert['rule_id']) || !$this->isRuleValid($alert_status['device_id'], $alert_status['rule_id'])) {
|
||||
if (empty($alert['rule_id']) || ! $this->isRuleValid($alert_status['device_id'], $alert_status['rule_id'])) {
|
||||
echo 'Stale-Rule: #' . $alert_status['rule_id'] . '/' . $alert_status['device_id'] . "\r\n";
|
||||
// Alert-Rule does not exist anymore, let's remove the alert-state.
|
||||
dbDelete('alerts', 'rule_id = ? && device_id = ?', [$alert_status['rule_id'], $alert_status['device_id']]);
|
||||
@ -370,7 +368,7 @@ class RunAlerts
|
||||
$alert['state'] = $alert_status['state'];
|
||||
$alert['alerted'] = $alert_status['alerted'];
|
||||
$alert['note'] = $alert_status['note'];
|
||||
if (!empty($alert['details'])) {
|
||||
if (! empty($alert['details'])) {
|
||||
$alert['details'] = json_decode(gzuncompress($alert['details']), true);
|
||||
}
|
||||
$alert['info'] = json_decode($alert_status['info'], true);
|
||||
@ -387,27 +385,27 @@ class RunAlerts
|
||||
*/
|
||||
public function runAlerts()
|
||||
{
|
||||
foreach ($this->loadAlerts('alerts.state != '.AlertState::ACKNOWLEDGED.' && alerts.open = 1') as $alert) {
|
||||
foreach ($this->loadAlerts('alerts.state != ' . AlertState::ACKNOWLEDGED . ' && alerts.open = 1') as $alert) {
|
||||
$noiss = false;
|
||||
$noacc = false;
|
||||
$updet = false;
|
||||
$rextra = json_decode($alert['extra'], true);
|
||||
if (!isset($rextra['recovery'])) {
|
||||
if (! isset($rextra['recovery'])) {
|
||||
// backwards compatibility check
|
||||
$rextra['recovery'] = true;
|
||||
}
|
||||
|
||||
$chk = dbFetchRow('SELECT alerts.alerted,devices.ignore,devices.disabled FROM alerts,devices WHERE alerts.device_id = ? && devices.device_id = alerts.device_id && alerts.rule_id = ?', array($alert['device_id'], $alert['rule_id']));
|
||||
$chk = dbFetchRow('SELECT alerts.alerted,devices.ignore,devices.disabled FROM alerts,devices WHERE alerts.device_id = ? && devices.device_id = alerts.device_id && alerts.rule_id = ?', [$alert['device_id'], $alert['rule_id']]);
|
||||
|
||||
if ($chk['alerted'] == $alert['state']) {
|
||||
$noiss = true;
|
||||
}
|
||||
|
||||
$tolerence_window = Config::get('alert.tolerance_window');
|
||||
if (!empty($rextra['count']) && empty($rextra['interval'])) {
|
||||
if (! empty($rextra['count']) && empty($rextra['interval'])) {
|
||||
// This check below is for compat-reasons
|
||||
if (!empty($rextra['delay']) && $alert['state'] != AlertState::RECOVERED) {
|
||||
if ((time() - strtotime($alert['time_logged']) + $tolerence_window) < $rextra['delay'] || (!empty($alert['details']['delay']) && (time() - $alert['details']['delay'] + $tolerence_window) < $rextra['delay'])) {
|
||||
if (! empty($rextra['delay']) && $alert['state'] != AlertState::RECOVERED) {
|
||||
if ((time() - strtotime($alert['time_logged']) + $tolerence_window) < $rextra['delay'] || (! empty($alert['details']['delay']) && (time() - $alert['details']['delay'] + $tolerence_window) < $rextra['delay'])) {
|
||||
continue;
|
||||
} else {
|
||||
$alert['details']['delay'] = time();
|
||||
@ -415,7 +413,7 @@ class RunAlerts
|
||||
}
|
||||
}
|
||||
|
||||
if ($alert['state'] == AlertState::ACTIVE && !empty($rextra['count']) && ($rextra['count'] == -1 || $alert['details']['count']++ < $rextra['count'])) {
|
||||
if ($alert['state'] == AlertState::ACTIVE && ! empty($rextra['count']) && ($rextra['count'] == -1 || $alert['details']['count']++ < $rextra['count'])) {
|
||||
if ($alert['details']['count'] < $rextra['count']) {
|
||||
$noacc = true;
|
||||
}
|
||||
@ -425,12 +423,12 @@ class RunAlerts
|
||||
}
|
||||
} else {
|
||||
// This is the new way
|
||||
if (!empty($rextra['delay']) && (time() - strtotime($alert['time_logged']) + $tolerence_window) < $rextra['delay'] && $alert['state'] != AlertState::RECOVERED) {
|
||||
if (! empty($rextra['delay']) && (time() - strtotime($alert['time_logged']) + $tolerence_window) < $rextra['delay'] && $alert['state'] != AlertState::RECOVERED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($rextra['interval'])) {
|
||||
if (!empty($alert['details']['interval']) && (time() - $alert['details']['interval'] + $tolerence_window) < $rextra['interval']) {
|
||||
if (! empty($rextra['interval'])) {
|
||||
if (! empty($alert['details']['interval']) && (time() - $alert['details']['interval'] + $tolerence_window) < $rextra['interval']) {
|
||||
continue;
|
||||
} else {
|
||||
$alert['details']['interval'] = time();
|
||||
@ -438,7 +436,7 @@ class RunAlerts
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array($alert['state'], [AlertState::ACTIVE, AlertState::WORSE, AlertState::BETTER]) && !empty($rextra['count']) && ($rextra['count'] == -1 || $alert['details']['count']++ < $rextra['count'])) {
|
||||
if (in_array($alert['state'], [AlertState::ACTIVE, AlertState::WORSE, AlertState::BETTER]) && ! empty($rextra['count']) && ($rextra['count'] == -1 || $alert['details']['count']++ < $rextra['count'])) {
|
||||
if ($alert['details']['count'] < $rextra['count']) {
|
||||
$noacc = true;
|
||||
}
|
||||
@ -459,11 +457,11 @@ class RunAlerts
|
||||
}
|
||||
|
||||
if ($updet) {
|
||||
dbUpdate(array('details' => gzcompress(json_encode($alert['details']), 9)), 'alert_log', 'id = ?', array($alert['id']));
|
||||
dbUpdate(['details' => gzcompress(json_encode($alert['details']), 9)], 'alert_log', 'id = ?', [$alert['id']]);
|
||||
}
|
||||
|
||||
if (!empty($rextra['mute'])) {
|
||||
echo 'Muted Alert-UID #'.$alert['id']."\r\n";
|
||||
if (! empty($rextra['mute'])) {
|
||||
echo 'Muted Alert-UID #' . $alert['id'] . "\r\n";
|
||||
$noiss = true;
|
||||
}
|
||||
|
||||
@ -477,18 +475,17 @@ class RunAlerts
|
||||
$noiss = true;
|
||||
}
|
||||
|
||||
if (!$noiss) {
|
||||
if (! $noiss) {
|
||||
$this->issueAlert($alert);
|
||||
dbUpdate(array('alerted' => $alert['state']), 'alerts', 'rule_id = ? && device_id = ?', array($alert['rule_id'], $alert['device_id']));
|
||||
dbUpdate(['alerted' => $alert['state']], 'alerts', 'rule_id = ? && device_id = ?', [$alert['rule_id'], $alert['device_id']]);
|
||||
}
|
||||
|
||||
if (!$noacc) {
|
||||
dbUpdate(array('open' => 0), 'alerts', 'rule_id = ? && device_id = ?', array($alert['rule_id'], $alert['device_id']));
|
||||
if (! $noacc) {
|
||||
dbUpdate(['open' => 0], 'alerts', 'rule_id = ? && device_id = ?', [$alert['rule_id'], $alert['device_id']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run external transports
|
||||
* @param array $obj Alert-Array
|
||||
@ -501,12 +498,12 @@ class RunAlerts
|
||||
// If alert transport mapping exists, override the default transports
|
||||
$transport_maps = AlertUtil::getAlertTransports($obj['alert_id']);
|
||||
|
||||
if (!$transport_maps) {
|
||||
if (! $transport_maps) {
|
||||
$transport_maps = AlertUtil::getDefaultAlertTransports();
|
||||
}
|
||||
|
||||
// alerting for default contacts, etc
|
||||
if (Config::get('alert.transports.mail') === true && !empty($obj['contacts'])) {
|
||||
if (Config::get('alert.transports.mail') === true && ! empty($obj['contacts'])) {
|
||||
$transport_maps[] = [
|
||||
'transport_id' => null,
|
||||
'transport_type' => 'mail',
|
||||
@ -515,7 +512,7 @@ class RunAlerts
|
||||
}
|
||||
|
||||
foreach ($transport_maps as $item) {
|
||||
$class = 'LibreNMS\\Alert\\Transport\\'.ucfirst($item['transport_type']);
|
||||
$class = 'LibreNMS\\Alert\\Transport\\' . ucfirst($item['transport_type']);
|
||||
if (class_exists($class)) {
|
||||
//FIXME remove Deprecated transport
|
||||
$transport_title = "Transport {$item['transport_type']}";
|
||||
@ -548,8 +545,8 @@ class RunAlerts
|
||||
{
|
||||
$prefix = [
|
||||
AlertState::RECOVERED => "recovery",
|
||||
AlertState::ACTIVE => $obj['severity']." alert",
|
||||
AlertState::ACKNOWLEDGED => "acknowledgment"
|
||||
AlertState::ACTIVE => $obj['severity'] . " alert",
|
||||
AlertState::ACKNOWLEDGED => "acknowledgment",
|
||||
];
|
||||
$prefix[3] = &$prefix[0];
|
||||
$prefix[4] = &$prefix[0];
|
||||
@ -574,7 +571,6 @@ class RunAlerts
|
||||
echo "ERROR: $result\r\n";
|
||||
Log::event('Could not issue ' . $prefix[$obj['state']] . " for rule '" . $obj['name'] . "' to transport '" . $transport . "' Error: " . $result, $obj['device_id'], 'error', Alert::ERROR);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -585,13 +581,12 @@ class RunAlerts
|
||||
*/
|
||||
public function isParentDown($device)
|
||||
{
|
||||
$parent_count = dbFetchCell("SELECT count(*) from `device_relationships` WHERE `child_device_id` = ?", array($device));
|
||||
if (!$parent_count) {
|
||||
$parent_count = dbFetchCell("SELECT count(*) from `device_relationships` WHERE `child_device_id` = ?", [$device]);
|
||||
if (! $parent_count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$down_parent_count = dbFetchCell("SELECT count(*) from devices as d LEFT JOIN devices_attribs as a ON d.device_id=a.device_id LEFT JOIN device_relationships as r ON d.device_id=r.parent_device_id WHERE d.status=0 AND d.ignore=0 AND d.disabled=0 AND r.child_device_id=? AND (d.status_reason='icmp' OR (a.attrib_type='override_icmp_disable' AND a.attrib_value=true))", array($device));
|
||||
$down_parent_count = dbFetchCell("SELECT count(*) from devices as d LEFT JOIN devices_attribs as a ON d.device_id=a.device_id LEFT JOIN device_relationships as r ON d.device_id=r.parent_device_id WHERE d.status=0 AND d.ignore=0 AND d.disabled=0 AND r.child_device_id=? AND (d.status_reason='icmp' OR (a.attrib_type='override_icmp_disable' AND a.attrib_value=true))", [$device]);
|
||||
if ($down_parent_count == $parent_count) {
|
||||
return true;
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ class Template
|
||||
public $template;
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the template details
|
||||
*
|
||||
* @param null $obj
|
||||
@ -48,9 +47,10 @@ class Template
|
||||
$this->template = AlertTemplate::whereHas('map', function ($query) use ($obj) {
|
||||
$query->where('alert_rule_id', '=', $obj['rule_id']);
|
||||
})->first();
|
||||
if (!$this->template) {
|
||||
if (! $this->template) {
|
||||
$this->template = AlertTemplate::where('name', '=', 'Default Alert Template')->first();
|
||||
}
|
||||
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
@ -65,7 +65,6 @@ class Template
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Parse Blade body
|
||||
*
|
||||
* @param $data
|
||||
@ -82,7 +81,6 @@ class Template
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Parse Blade title
|
||||
*
|
||||
* @param $data
|
||||
@ -99,7 +97,6 @@ class Template
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the default template
|
||||
*
|
||||
* @return string
|
||||
@ -108,7 +105,7 @@ class Template
|
||||
{
|
||||
return '{{ $alert->title }}' . PHP_EOL .
|
||||
'Severity: {{ $alert->severity }}' . PHP_EOL .
|
||||
'@if ($alert->state == '.AlertState::RECOVERED.')Time elapsed: {{ $alert->elapsed }} @endif ' . PHP_EOL .
|
||||
'@if ($alert->state == ' . AlertState::RECOVERED . ')Time elapsed: {{ $alert->elapsed }} @endif ' . PHP_EOL .
|
||||
'Timestamp: {{ $alert->timestamp }}' . PHP_EOL .
|
||||
'Unique-ID: {{ $alert->uid }}' . PHP_EOL .
|
||||
'Rule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif ' . PHP_EOL .
|
||||
|
@ -3,9 +3,9 @@
|
||||
namespace LibreNMS\Alert;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use LibreNMS\Interfaces\Alert\Transport as TransportInterface;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Interfaces\Alert\Transport as TransportInterface;
|
||||
|
||||
abstract class Transport implements TransportInterface
|
||||
{
|
||||
@ -17,7 +17,7 @@ abstract class Transport implements TransportInterface
|
||||
*/
|
||||
public function __construct($transport_id = null)
|
||||
{
|
||||
if (!empty($transport_id)) {
|
||||
if (! empty($transport_id)) {
|
||||
$sql = "SELECT `transport_config` FROM `alert_transports` WHERE `transport_id`=?";
|
||||
$this->config = json_decode(dbFetchCell($sql, [$transport_id]), true);
|
||||
}
|
||||
@ -34,27 +34,28 @@ abstract class Transport implements TransportInterface
|
||||
$options = [];
|
||||
foreach (explode(PHP_EOL, $input) as $option) {
|
||||
if (Str::contains($option, '=')) {
|
||||
list($k,$v) = explode('=', $option, 2);
|
||||
[$k,$v] = explode('=', $option, 2);
|
||||
$options[$k] = trim($v);
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hex color string for a particular state
|
||||
* @param integer $state State code from alert
|
||||
* @param int $state State code from alert
|
||||
* @return string Hex color, default to #337AB7 blue if state unrecognised
|
||||
*/
|
||||
public static function getColorForState($state)
|
||||
{
|
||||
$colors = array(
|
||||
$colors = [
|
||||
AlertState::CLEAR => Config::get('alert_colour.ok'),
|
||||
AlertState::ACTIVE => Config::get('alert_colour.bad'),
|
||||
AlertState::ACKNOWLEDGED => Config::get('alert_colour.acknowledged'),
|
||||
AlertState::WORSE => Config::get('alert_colour.worse'),
|
||||
AlertState::BETTER => Config::get('alert_colour.better'),
|
||||
);
|
||||
];
|
||||
|
||||
return isset($colors[$state]) ? $colors[$state] : '#337AB7';
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version. Please see LICENSE.txt at the top level of
|
||||
* the source code distribution for details. */
|
||||
/**
|
||||
/**
|
||||
* API Transport
|
||||
* @author GitStoph <https://github.com/GitStoph>
|
||||
* @copyright 2019 GitStoph
|
||||
@ -13,11 +13,12 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Alerta extends Transport
|
||||
{
|
||||
@ -28,8 +29,10 @@ class Alerta extends Transport
|
||||
$opts['apikey'] = $this->config['apikey'];
|
||||
$opts['alertstate'] = $this->config['alertstate'];
|
||||
$opts['recoverstate'] = $this->config['recoverstate'];
|
||||
|
||||
return $this->contactAlerta($obj, $opts);
|
||||
}
|
||||
|
||||
public function contactAlerta($obj, $opts)
|
||||
{
|
||||
$host = $opts['url'];
|
||||
@ -55,14 +58,14 @@ class Alerta extends Transport
|
||||
'type' => $obj['type'],
|
||||
'ip' => $obj['ip'],
|
||||
'uptime' => $obj['uptime_long'],
|
||||
'moreInfo' => '<a href='.$deviceurl.'>'.$devicehostname.'</a>',
|
||||
'moreInfo' => '<a href=' . $deviceurl . '>' . $devicehostname . '</a>',
|
||||
],
|
||||
'origin' => $obj['rule'],
|
||||
'type' => $obj['title'],
|
||||
];
|
||||
$alert_message = json_encode($data);
|
||||
set_curl_proxy($curl);
|
||||
$headers = array('Content-Type: application/json', 'Authorization: Key ' . $opts['apikey']);
|
||||
$headers = ['Content-Type: application/json', 'Authorization: Key ' . $opts['apikey']];
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($curl, CURLOPT_URL, $host);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
@ -75,10 +78,13 @@ class Alerta extends Transport
|
||||
var_dump("Params: " . $alert_message);
|
||||
var_dump("Return: " . $ret);
|
||||
var_dump("Headers: " . $headers);
|
||||
|
||||
return 'HTTP Status code ' . $code;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function configTemplate()
|
||||
{
|
||||
return [
|
||||
@ -112,12 +118,12 @@ class Alerta extends Transport
|
||||
'name' => 'recoverstate',
|
||||
'descr' => 'What severity you want Alerta to reflect when rule unmatches/recovers.',
|
||||
'type' => 'text',
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'alerta-url' => 'required|url',
|
||||
'apikey' => 'required|string',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,12 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Alertmanager extends Transport
|
||||
{
|
||||
@ -65,7 +66,7 @@ class Alertmanager extends Transport
|
||||
unset($api['url']);
|
||||
foreach ($api as $label => $value) {
|
||||
$data[0]['labels'][$label] = $value;
|
||||
};
|
||||
}
|
||||
|
||||
$alert_message = json_encode($data);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
|
||||
@ -80,6 +81,7 @@ class Alertmanager extends Transport
|
||||
if ($code != 200) {
|
||||
return 'HTTP Status code ' . $code;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -98,11 +100,11 @@ class Alertmanager extends Transport
|
||||
'name' => 'alertmanager-options',
|
||||
'descr' => 'Alertmanager Options',
|
||||
'type' => 'textarea',
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'alertmanager-url' => 'required|url',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,9 @@
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Api extends Transport
|
||||
{
|
||||
@ -39,6 +39,7 @@ class Api extends Transport
|
||||
$body = $this->config['api-body'];
|
||||
$method = $this->config['api-method'];
|
||||
$auth = [$this->config['api-auth-username'], $this->config['api-auth-password']];
|
||||
|
||||
return $this->contactAPI($obj, $url, $options, $method, $auth, $headers, $body);
|
||||
}
|
||||
|
||||
@ -53,7 +54,7 @@ class Api extends Transport
|
||||
|
||||
//get each line of key-values and process the variables for Headers;
|
||||
foreach (preg_split("/\\r\\n|\\r|\\n/", $headers, -1, PREG_SPLIT_NO_EMPTY) as $current_line) {
|
||||
list($u_key, $u_val) = explode('=', $current_line, 2);
|
||||
[$u_key, $u_val] = explode('=', $current_line, 2);
|
||||
foreach ($obj as $p_key => $p_val) {
|
||||
$u_val = str_replace("{{ $" . $p_key . ' }}', $p_val, $u_val);
|
||||
}
|
||||
@ -62,7 +63,7 @@ class Api extends Transport
|
||||
}
|
||||
//get each line of key-values and process the variables for Options;
|
||||
foreach (preg_split("/\\r\\n|\\r|\\n/", $options, -1, PREG_SPLIT_NO_EMPTY) as $current_line) {
|
||||
list($u_key, $u_val) = explode('=', $current_line, 2);
|
||||
[$u_key, $u_val] = explode('=', $current_line, 2);
|
||||
// Replace the values
|
||||
foreach ($obj as $p_key => $p_val) {
|
||||
$u_val = str_replace("{{ $" . $p_key . ' }}', $p_val, $u_val);
|
||||
@ -73,7 +74,7 @@ class Api extends Transport
|
||||
|
||||
$client = new \GuzzleHttp\Client();
|
||||
$request_opts['proxy'] = get_guzzle_proxy();
|
||||
if (isset($auth) && !empty($auth[0])) {
|
||||
if (isset($auth) && ! empty($auth[0])) {
|
||||
$request_opts['auth'] = $auth;
|
||||
}
|
||||
if (count($request_heads) > 0) {
|
||||
@ -98,9 +99,11 @@ class Api extends Transport
|
||||
var_dump($query);
|
||||
var_dump("Response headers:");
|
||||
var_dump($res->getHeaders());
|
||||
var_dump("Return: ".$res->getReasonPhrase());
|
||||
return 'HTTP Status code '.$code;
|
||||
var_dump("Return: " . $res->getReasonPhrase());
|
||||
|
||||
return 'HTTP Status code ' . $code;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -116,8 +119,8 @@ class Api extends Transport
|
||||
'options' => [
|
||||
'GET' => 'GET',
|
||||
'POST' => 'POST',
|
||||
'PUT' => 'PUT'
|
||||
]
|
||||
'PUT' => 'PUT',
|
||||
],
|
||||
],
|
||||
[
|
||||
'title' => 'API URL',
|
||||
@ -154,12 +157,12 @@ class Api extends Transport
|
||||
'name' => 'api-auth-password',
|
||||
'descr' => 'Auth Password',
|
||||
'type' => 'password',
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'api-method' => 'in:GET,POST,PUT',
|
||||
'api-url' => 'required|url'
|
||||
]
|
||||
'api-url' => 'required|url',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -39,8 +39,8 @@
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Boxcar extends Transport
|
||||
{
|
||||
@ -60,13 +60,13 @@ class Boxcar extends Transport
|
||||
switch ($obj['severity']) {
|
||||
case "critical":
|
||||
$severity = "Critical";
|
||||
if (!empty($api['sound_critical'])) {
|
||||
if (! empty($api['sound_critical'])) {
|
||||
$data['notification[sound]'] = $api['sound_critical'];
|
||||
}
|
||||
break;
|
||||
case "warning":
|
||||
$severity = "Warning";
|
||||
if (!empty($api['sound_warning'])) {
|
||||
if (! empty($api['sound_warning'])) {
|
||||
$data['notification[sound]'] = $api['sound_warning'];
|
||||
}
|
||||
break;
|
||||
@ -74,7 +74,7 @@ class Boxcar extends Transport
|
||||
switch ($obj['state']) {
|
||||
case AlertState::RECOVERED:
|
||||
$title_text = "OK";
|
||||
if (!empty($api['sound_ok'])) {
|
||||
if (! empty($api['sound_ok'])) {
|
||||
$data['notification[sound]'] = $api['sound_ok'];
|
||||
}
|
||||
break;
|
||||
@ -87,7 +87,7 @@ class Boxcar extends Transport
|
||||
}
|
||||
$data['notification[title]'] = $title_text . " - " . $obj['hostname'] . " - " . $obj['name'];
|
||||
$message_text = "Timestamp: " . $obj['timestamp'];
|
||||
if (!empty($obj['faults'])) {
|
||||
if (! empty($obj['faults'])) {
|
||||
$message_text .= "\n\nFaults:\n";
|
||||
foreach ($obj['faults'] as $k => $faults) {
|
||||
$message_text .= "#" . $k . " " . $faults['string'] . "\n";
|
||||
@ -104,6 +104,7 @@ class Boxcar extends Transport
|
||||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
if ($code != 201) {
|
||||
var_dump("Boxcar returned error"); //FIXME: proper debugging
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -125,11 +126,11 @@ class Boxcar extends Transport
|
||||
'name' => 'boxcar-options',
|
||||
'descr' => 'Boxcar Options',
|
||||
'type' => 'textarea',
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'boxcar-token' => 'required',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Canopsis extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$opts['host'] = $this->config['canopsis-host'];
|
||||
$opts['port'] = $this->config['canopsis-port'];
|
||||
$opts['user'] = $this->config['canopsis-user'];
|
||||
$opts['pass'] = $this->config['canopsis-pass'];
|
||||
$opts['vhost'] = $this->config['canopsis-vhost'];
|
||||
}
|
||||
|
||||
return $this->contactCanopsis($obj, $opts);
|
||||
}
|
||||
|
||||
@ -50,7 +52,7 @@ class Canopsis extends Transport
|
||||
default:
|
||||
$state = 0;
|
||||
}
|
||||
$msg_body = array(
|
||||
$msg_body = [
|
||||
"timestamp" => time(),
|
||||
"connector" => "librenms",
|
||||
"connector_name" => "LibreNMS1",
|
||||
@ -60,8 +62,8 @@ class Canopsis extends Transport
|
||||
"resource" => $obj['name'],
|
||||
"state" => $state,
|
||||
"output" => $obj['msg'],
|
||||
"display_name" => "librenms"
|
||||
);
|
||||
"display_name" => "librenms",
|
||||
];
|
||||
$msg_raw = json_encode($msg_body);
|
||||
|
||||
// Build routing key
|
||||
@ -72,12 +74,13 @@ class Canopsis extends Transport
|
||||
}
|
||||
|
||||
// Publish Event
|
||||
$msg = new \PhpAmqpLib\Message\AMQPMessage($msg_raw, array('content_type' => 'application/json', 'delivery_mode' => 2));
|
||||
$msg = new \PhpAmqpLib\Message\AMQPMessage($msg_raw, ['content_type' => 'application/json', 'delivery_mode' => 2]);
|
||||
$ch->basic_publish($msg, $exchange, $msg_rk);
|
||||
|
||||
// Close connection
|
||||
$ch->close();
|
||||
$conn->close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -89,31 +92,31 @@ class Canopsis extends Transport
|
||||
'title' => 'Hostname',
|
||||
'name' => 'canopsis-host',
|
||||
'descr' => 'Canopsis Hostname',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Port Number',
|
||||
'name' => 'canopsis-port',
|
||||
'descr' => 'Canopsis Port Number',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'User',
|
||||
'name' => 'canopsis-user',
|
||||
'descr' => 'Canopsis User',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Password',
|
||||
'name' => 'canopsis-pass',
|
||||
'descr' => 'Canopsis Password',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Vhost',
|
||||
'name' => 'canopsis-vhost',
|
||||
'descr' => 'Canopsis Vhost',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
@ -122,7 +125,7 @@ class Canopsis extends Transport
|
||||
'canopsis-user' => 'required|string',
|
||||
'canopsis-pass' => 'required|string',
|
||||
'canopsis-vhost' => 'required|string',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,11 @@
|
||||
* option) any later version. Please see LICENSE.txt at the top level of
|
||||
* the source code distribution for details.
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Ciscospark extends Transport
|
||||
{
|
||||
@ -25,15 +26,16 @@ class Ciscospark extends Transport
|
||||
$room_id = $this->config['room-id'];
|
||||
$token = $this->config['api-token'];
|
||||
}
|
||||
|
||||
return $this->contactCiscospark($obj, $room_id, $token);
|
||||
}
|
||||
|
||||
public function contactCiscospark($obj, $room_id, $token)
|
||||
{
|
||||
$text = null;
|
||||
$data = array (
|
||||
'roomId' => $room_id
|
||||
);
|
||||
$data = [
|
||||
'roomId' => $room_id,
|
||||
];
|
||||
|
||||
$akey = 'text';
|
||||
if ($this->config['use-markdown'] === 'on') {
|
||||
@ -59,19 +61,21 @@ class Ciscospark extends Transport
|
||||
set_curl_proxy($curl);
|
||||
curl_setopt($curl, CURLOPT_URL, 'https://api.ciscospark.com/v1/messages');
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, [
|
||||
'Content-type' => 'application/json',
|
||||
'Expect:',
|
||||
'Authorization: Bearer ' . $token
|
||||
));
|
||||
'Authorization: Bearer ' . $token,
|
||||
]);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||||
$ret = curl_exec($curl);
|
||||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
|
||||
if ($code != 200) {
|
||||
echo("Cisco Spark returned Error, retry later\r\n");
|
||||
echo "Cisco Spark returned Error, retry later\r\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -97,12 +101,12 @@ class Ciscospark extends Transport
|
||||
'descr' => 'Use Markdown when sending the alert',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'api-token' => 'required|string',
|
||||
'room-id' => 'required|string'
|
||||
]
|
||||
'room-id' => 'required|string',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,10 +21,11 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Clickatell extends Transport
|
||||
{
|
||||
@ -32,6 +33,7 @@ class Clickatell extends Transport
|
||||
{
|
||||
$clickatell_opts['token'] = $this->config['clickatell-token'];
|
||||
$clickatell_opts['to'] = preg_split('/([,\r\n]+)/', $this->config['clickatell-numbers']);
|
||||
|
||||
return $this->contactClickatell($obj, $clickatell_opts);
|
||||
}
|
||||
|
||||
@ -49,6 +51,7 @@ class Clickatell extends Transport
|
||||
if ($code > 200) {
|
||||
return var_dump($ret);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -67,12 +70,12 @@ class Clickatell extends Transport
|
||||
'name' => 'clickatell-numbers',
|
||||
'descr' => 'Enter mobile numbers, can be new line or comma separated',
|
||||
'type' => 'textarea',
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'clickatell-token' => 'required|string',
|
||||
'clickatell-numbers' => 'required|string',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -28,8 +28,8 @@
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Discord extends Transport
|
||||
{
|
||||
@ -38,7 +38,7 @@ class Discord extends Transport
|
||||
'severity' => 'Severity',
|
||||
'hostname' => 'Hostname',
|
||||
'name' => 'Rule Name',
|
||||
'rule' => 'Rule'
|
||||
'rule' => 'Rule',
|
||||
];
|
||||
|
||||
public function deliverAlert($obj, $opts)
|
||||
@ -70,17 +70,17 @@ class Discord extends Transport
|
||||
'description' => $discord_msg,
|
||||
'fields' => $this->createDiscordFields($obj, $discord_opts),
|
||||
'footer' => [
|
||||
'text' => $footer_text
|
||||
]
|
||||
]
|
||||
]
|
||||
'text' => $footer_text,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
if (!empty($discord_opts['options'])) {
|
||||
if (! empty($discord_opts['options'])) {
|
||||
$data = array_merge($data, $discord_opts['options']);
|
||||
}
|
||||
|
||||
$alert_message = json_encode($data);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
|
||||
set_curl_proxy($curl);
|
||||
curl_setopt($curl, CURLOPT_URL, $host);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
@ -93,8 +93,10 @@ class Discord extends Transport
|
||||
var_dump("API '$host' returned Error"); //FIXME: propper debuging
|
||||
var_dump("Params: " . $alert_message); //FIXME: propper debuging
|
||||
var_dump("Return: " . $ret); //FIXME: propper debuging
|
||||
|
||||
return 'HTTP Status code ' . $code;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -104,7 +106,7 @@ class Discord extends Transport
|
||||
|
||||
foreach (self::ALERT_FIELDS_TO_DISCORD_FIELDS as $objKey => $discordKey) {
|
||||
// Skip over keys that do not exist so Discord does not give us a 400.
|
||||
if (!$obj[$objKey]) {
|
||||
if (! $obj[$objKey]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -132,11 +134,11 @@ class Discord extends Transport
|
||||
'name' => 'options',
|
||||
'descr' => 'Enter the config options (format: option=value separated by new lines)',
|
||||
'type' => 'textarea',
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'url' => 'required|url',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,16 +21,18 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Dummy extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
var_dump($obj);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -14,20 +14,21 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Elasticsearch extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$opts['es_host'] = $this->config['es-host'];
|
||||
$opts['es_port'] = $this->config['es-port'];
|
||||
$opts['es_index'] = $this->config['es-pattern'];
|
||||
$opts['es_proxy'] = $this-> config['es-proxy'];
|
||||
$opts['es_proxy'] = $this->config['es-proxy'];
|
||||
}
|
||||
|
||||
return $this->contactElasticsearch($obj, $opts);
|
||||
@ -42,7 +43,7 @@ class Elasticsearch extends Transport
|
||||
$severity = $obj['severity'];
|
||||
$device = device_by_id_cache($obj['device_id']); // for event logging
|
||||
|
||||
if (!empty($opts['es_host'])) {
|
||||
if (! empty($opts['es_host'])) {
|
||||
if (preg_match("/[a-zA-Z]/", $opts['es_host'])) {
|
||||
$es_host = gethostbyname($opts['es_host']);
|
||||
if ($es_host === $opts['es_host']) {
|
||||
@ -55,11 +56,11 @@ class Elasticsearch extends Transport
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($opts['es_port']) && preg_match("/^\d+$/", $opts['es_port'])) {
|
||||
if (! empty($opts['es_port']) && preg_match("/^\d+$/", $opts['es_port'])) {
|
||||
$es_port = $opts['es_port'];
|
||||
}
|
||||
|
||||
if (!empty($opts['es_index'])) {
|
||||
if (! empty($opts['es_index'])) {
|
||||
$index = strftime($opts['es_index']);
|
||||
}
|
||||
|
||||
@ -83,7 +84,7 @@ class Elasticsearch extends Transport
|
||||
break;
|
||||
}
|
||||
|
||||
$data = array(
|
||||
$data = [
|
||||
'@timestamp' => date('c'),
|
||||
"host" => gethostname(),
|
||||
"location" => $obj['location'],
|
||||
@ -101,56 +102,56 @@ class Elasticsearch extends Transport
|
||||
"entity_id" => $obj['device_id'],
|
||||
"entity_name" => $obj['hostname'],
|
||||
"entity_descr" => $obj['sysDescr'],
|
||||
);
|
||||
];
|
||||
|
||||
if (!empty($obj['faults'])) {
|
||||
if (! empty($obj['faults'])) {
|
||||
foreach ($obj['faults'] as $k => $v) {
|
||||
$curl = curl_init();
|
||||
$data['message'] = $v['string'];
|
||||
switch (true) {
|
||||
case (array_key_exists('port_id', $v)):
|
||||
case array_key_exists('port_id', $v):
|
||||
$data['entity_type'] = 'port';
|
||||
$data['entity_tab'] = 'port';
|
||||
$data['entity_id'] = $v['port_id'];
|
||||
$data['entity_name'] = $v['ifName'];
|
||||
$data['entity_descr'] = $v['ifAlias'];
|
||||
break;
|
||||
case (array_key_exists('sensor_id', $v)):
|
||||
case array_key_exists('sensor_id', $v):
|
||||
$data['entity_type'] = $v['sensor_class'];
|
||||
$data['entity_tab'] = 'health';
|
||||
$data['entity_id'] = $v['sensor_id'];
|
||||
$data['entity_name'] = $v['sensor_descr'];
|
||||
$data['entity_descr'] = $v['sensor_type'];
|
||||
break;
|
||||
case (array_key_exists('mempool_id', $v)):
|
||||
case array_key_exists('mempool_id', $v):
|
||||
$data['entity_type'] = 'mempool';
|
||||
$data['entity_tab'] = 'health';
|
||||
$data['entity_id'] = $v['mempool_id'];
|
||||
$data['entity_name'] = $v['mempool_index'];
|
||||
$data['entity_descr'] = $v['mempool_descr'];
|
||||
break;
|
||||
case (array_key_exists('storage_id', $v)):
|
||||
case array_key_exists('storage_id', $v):
|
||||
$data['entity_type'] = 'storage';
|
||||
$data['entity_tab'] = 'health';
|
||||
$data['entity_id'] = $v['storage_id'];
|
||||
$data['entity_name'] = $v['storage_index'];
|
||||
$data['entity_descr'] = $v['storage_descr'];
|
||||
break;
|
||||
case (array_key_exists('processor_id', $v)):
|
||||
case array_key_exists('processor_id', $v):
|
||||
$data['entity_type'] = 'processor';
|
||||
$data['entity_tab'] = 'health';
|
||||
$data['entity_id'] = $v['processor_id'];
|
||||
$data['entity_name'] = $v['processor_type'];
|
||||
$data['entity_descr'] = $v['processor_descr'];
|
||||
break;
|
||||
case (array_key_exists('bgpPeer_id', $v)):
|
||||
case array_key_exists('bgpPeer_id', $v):
|
||||
$data['entity_type'] = 'bgp';
|
||||
$data['entity_tab'] = 'routing';
|
||||
$data['entity_id'] = $v['bgpPeer_id'];
|
||||
$data['entity_name'] = 'local: ' . $v['bgpPeerLocalAddr'] . ' - AS' . $obj['bgpLocalAs'];
|
||||
$data['entity_descr'] = 'remote: ' . $v['bgpPeerIdentifier'] . ' - AS' . $v['bgpPeerRemoteAs'];
|
||||
break;
|
||||
case (array_key_exists('tunnel_id', $v)):
|
||||
case array_key_exists('tunnel_id', $v):
|
||||
$data['entity_type'] = 'ipsec_tunnel';
|
||||
$data['entity_tab'] = 'routing';
|
||||
$data['entity_id'] = $v['tunnel_id'];
|
||||
@ -162,7 +163,7 @@ class Elasticsearch extends Transport
|
||||
break;
|
||||
}
|
||||
$alert_message = json_encode($data);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
|
||||
if ($opts['es_proxy'] === true) {
|
||||
set_curl_proxy($curl);
|
||||
}
|
||||
@ -180,7 +181,7 @@ class Elasticsearch extends Transport
|
||||
} else {
|
||||
$curl = curl_init();
|
||||
$alert_message = json_encode($data);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
|
||||
if ($opts['es_proxy'] === true) {
|
||||
set_curl_proxy($curl);
|
||||
}
|
||||
@ -195,6 +196,7 @@ class Elasticsearch extends Transport
|
||||
return $host . ' returned HTTP Status code ' . $code . ' for ' . $alert_message;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -225,14 +227,14 @@ class Elasticsearch extends Transport
|
||||
'name' => 'es-proxy',
|
||||
'descr' => 'Elasticsearch Proxy',
|
||||
'type' => 'checkbox',
|
||||
'default' => false
|
||||
]
|
||||
'default' => false,
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'es-host' => 'required|string',
|
||||
'es-port' => 'required|string',
|
||||
'es-pattern' => 'required|string'
|
||||
]
|
||||
'es-pattern' => 'required|string',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,20 +21,22 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Gitlab extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$opts['project-id'] = $this->config['gitlab-id'];
|
||||
$opts['key'] = $this->config['gitlab-key'];
|
||||
$opts['host'] = $this->config['gitlab-host'];
|
||||
}
|
||||
|
||||
return $this->contactGitlab($obj, $opts);
|
||||
}
|
||||
|
||||
@ -53,15 +55,15 @@ class Gitlab extends Transport
|
||||
$url = $opts['host'] . "/api/v4/projects/$project_id/issues?title=$title&description=$desc";
|
||||
$curl = curl_init();
|
||||
|
||||
$data = array("title" => $details,
|
||||
"description" => $description
|
||||
);
|
||||
$postdata = array("fields" => $data);
|
||||
$data = ["title" => $details,
|
||||
"description" => $description,
|
||||
];
|
||||
$postdata = ["fields" => $data];
|
||||
$datastring = json_encode($postdata);
|
||||
|
||||
set_curl_proxy($curl);
|
||||
|
||||
$headers = array('Accept: application/json', 'Content-Type: application/json', 'PRIVATE-TOKEN: '.$project_key);
|
||||
$headers = ['Accept: application/json', 'Content-Type: application/json', 'PRIVATE-TOKEN: ' . $project_key];
|
||||
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
@ -75,9 +77,11 @@ class Gitlab extends Transport
|
||||
if ($code == 200) {
|
||||
$gitlabout = json_decode($ret, true);
|
||||
d_echo("Created Gitlab issue " . $gitlabout['key'] . " for " . $device);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
d_echo("Gitlab connection error: " . serialize($ret));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -104,13 +108,13 @@ class Gitlab extends Transport
|
||||
'name' => 'gitlab-key',
|
||||
'descr' => 'Personal Access Token',
|
||||
'type' => 'text',
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'gitlab-host' => 'required|string',
|
||||
'gitlab-id' => 'required|string',
|
||||
'gitlab-key' => 'required|string'
|
||||
]
|
||||
'gitlab-key' => 'required|string',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,10 +21,11 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Hipchat extends Transport
|
||||
{
|
||||
@ -92,9 +93,9 @@ class Hipchat extends Transport
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/x-www-form-urlencoded',
|
||||
));
|
||||
]);
|
||||
$ret = curl_exec($curl);
|
||||
|
||||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
@ -102,6 +103,7 @@ class Hipchat extends Transport
|
||||
var_dump("API '$url' returned Error");
|
||||
var_dump("Params: " . $message);
|
||||
var_dump("Return: " . $ret);
|
||||
|
||||
return 'HTTP Status code ' . $code;
|
||||
}
|
||||
|
||||
@ -140,7 +142,7 @@ class Hipchat extends Transport
|
||||
'validation' => [
|
||||
'hipchat-url' => 'required|url',
|
||||
'hipchat-room-id' => 'required|numeric',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,10 +21,11 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
/**
|
||||
* The Hue API currently is fairly limited for alerts.
|
||||
@ -35,7 +36,7 @@ class Hue extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$opts['user'] = $this->config['hue-user'];
|
||||
$opts['bridge'] = $this->config['hue-host'];
|
||||
$opts['duration'] = $this->config['hue-duration'];
|
||||
@ -55,12 +56,12 @@ class Hue extends Transport
|
||||
$url = $opts['bridge'] . "/api/$hue_user/groups/0/action";
|
||||
$curl = curl_init();
|
||||
$duration = $opts['duration'];
|
||||
$data = array("alert" => $duration);
|
||||
$data = ["alert" => $duration];
|
||||
$datastring = json_encode($data);
|
||||
|
||||
set_curl_proxy($curl);
|
||||
|
||||
$headers = array('Accept: application/json', 'Content-Type: application/json');
|
||||
$headers = ['Accept: application/json', 'Content-Type: application/json'];
|
||||
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
@ -73,9 +74,11 @@ class Hue extends Transport
|
||||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
if ($code == 200) {
|
||||
d_echo("Sent alert to Phillips Hue Bridge " . $opts['host'] . " for " . $device);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
d_echo("Hue bridge connection error: " . serialize($ret));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -104,15 +107,15 @@ class Hue extends Transport
|
||||
'type' => 'select',
|
||||
'options' => [
|
||||
'1 Second' => 'select',
|
||||
'15 Seconds' => 'lselect'
|
||||
]
|
||||
]
|
||||
'15 Seconds' => 'lselect',
|
||||
],
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'hue-host' => 'required|string',
|
||||
'hue-user' => 'required|string',
|
||||
'hue-duration' => 'required|string'
|
||||
]
|
||||
'hue-duration' => 'required|string',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,11 +21,12 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Irc extends Transport
|
||||
{
|
||||
@ -61,11 +62,11 @@ class Irc extends Transport
|
||||
'descr' => 'Enable IRC alerts',
|
||||
'type' => 'checkbox',
|
||||
'default' => true,
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'irc' => 'required'
|
||||
]
|
||||
'irc' => 'required',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,22 +21,24 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Jira extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$opts['username'] = $this->config['jira-username'];
|
||||
$opts['password'] = $this->config['jira-password'];
|
||||
$opts['prjkey'] = $this->config['jira-key'];
|
||||
$opts['issuetype'] = $this->config['jira-type'];
|
||||
$opts['url'] = $this->config['jira-url'];
|
||||
}
|
||||
|
||||
return $this->contactJira($obj, $opts);
|
||||
}
|
||||
|
||||
@ -58,16 +60,16 @@ class Jira extends Transport
|
||||
$url = $opts['url'] . '/rest/api/latest/issue';
|
||||
$curl = curl_init();
|
||||
|
||||
$data = array("project" => array("key" => $prjkey),
|
||||
$data = ["project" => ["key" => $prjkey],
|
||||
"summary" => $details,
|
||||
"description" => $description,
|
||||
"issuetype" => array("name" => $issuetype));
|
||||
$postdata = array("fields" => $data);
|
||||
"issuetype" => ["name" => $issuetype], ];
|
||||
$postdata = ["fields" => $data];
|
||||
$datastring = json_encode($postdata);
|
||||
|
||||
set_curl_proxy($curl);
|
||||
|
||||
$headers = array('Accept: application/json', 'Content-Type: application/json');
|
||||
$headers = ['Accept: application/json', 'Content-Type: application/json'];
|
||||
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
@ -82,9 +84,11 @@ class Jira extends Transport
|
||||
if ($code == 200) {
|
||||
$jiraout = json_decode($ret, true);
|
||||
d_echo("Created jira issue " . $jiraout['key'] . " for " . $device);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
d_echo("Jira connection error: " . serialize($ret));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -97,31 +101,31 @@ class Jira extends Transport
|
||||
'title' => 'URL',
|
||||
'name' => 'jira-url',
|
||||
'descr' => 'Jira URL',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Project Key',
|
||||
'name' => 'jira-key',
|
||||
'descr' => 'Jira Project Key',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Issue Type',
|
||||
'name' => 'jira-type',
|
||||
'descr' => 'Jira Issue Type',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Jira Username',
|
||||
'name' => 'jira-username',
|
||||
'descr' => 'Jira Username',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Jira Password',
|
||||
'name' => 'jira-password',
|
||||
'descr' => 'Jira Password',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
@ -130,7 +134,7 @@ class Jira extends Transport
|
||||
'jira-type' => 'required|string',
|
||||
'jira-username' => 'required|string',
|
||||
'jira-password' => 'required|string',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -9,39 +9,41 @@
|
||||
* option) any later version. Please see LICENSE.txt at the top level of
|
||||
* the source code distribution for details.
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Kayako extends Transport
|
||||
{
|
||||
public function deliverAlert($host, $kayako)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$kayako['url'] = $this->config['kayako-url'];
|
||||
$kayako['key'] = $this->config['kayako-key'];
|
||||
$kayako['secret'] = $this->config['kayako-secret'];
|
||||
$kayako['department'] = $this->config['kayako-department'];
|
||||
}
|
||||
|
||||
return $this->contactKayako($host, $kayako);
|
||||
}
|
||||
|
||||
public function contactKayako($host, $kayako)
|
||||
{
|
||||
$url = $kayako['url']."/Tickets/Ticket";
|
||||
$url = $kayako['url'] . "/Tickets/Ticket";
|
||||
$key = $kayako['key'];
|
||||
$secret = $kayako['secret'];
|
||||
$user = Config::get('email_from');
|
||||
$department = $kayako['department'];
|
||||
$ticket_type= 1;
|
||||
$ticket_type = 1;
|
||||
$ticket_status = 1;
|
||||
$ticket_prio = 1;
|
||||
$salt = mt_rand();
|
||||
$signature = base64_encode(hash_hmac('sha256', $salt, $secret, true));
|
||||
|
||||
$protocol = array(
|
||||
$protocol = [
|
||||
'subject' => ($host['name'] ? $host['name'] . ' on ' . $host['hostname'] : $host['title']),
|
||||
'fullname' => 'LibreNMS Alert',
|
||||
'email' => $user,
|
||||
@ -54,8 +56,8 @@ class Kayako extends Transport
|
||||
'ignoreautoresponder' => true,
|
||||
'apikey' => $key,
|
||||
'salt' => $salt,
|
||||
'signature' => $signature
|
||||
);
|
||||
'signature' => $signature,
|
||||
];
|
||||
$post_data = http_build_query($protocol, '', '&');
|
||||
|
||||
$curl = curl_init();
|
||||
@ -68,6 +70,7 @@ class Kayako extends Transport
|
||||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
if ($code != 200) {
|
||||
var_dump("Kayako returned Error, retry later");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -82,33 +85,33 @@ class Kayako extends Transport
|
||||
'title' => 'Kayako URL',
|
||||
'name' => 'kayako-url',
|
||||
'descr' => 'ServiceDesk API URL',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Kayako API Key',
|
||||
'name' => 'kayako-key',
|
||||
'descr' => 'ServiceDesk API Key',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Kayako API Secret',
|
||||
'name' => 'kayako-secret',
|
||||
'descr' => 'ServiceDesk API Secret Key',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Kayako Department',
|
||||
'name' => 'kayako-department',
|
||||
'descr' => 'Department to post a ticket',
|
||||
'type' => 'text'
|
||||
]
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'kayako-url' => 'required|url',
|
||||
'kayako-key' => 'required|string',
|
||||
'kayako-secret' => 'required|string',
|
||||
'kayako-department' => 'required|string'
|
||||
]
|
||||
'kayako-department' => 'required|string',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -4,16 +4,18 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Linenotify extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
$opts['line-notify-access-token'] = $this->config['line-notify-access-token'];
|
||||
|
||||
return $this->contactLineNotify($obj, $opts);
|
||||
}
|
||||
|
||||
@ -36,6 +38,7 @@ class Linenotify extends Transport
|
||||
if ($code != 200) {
|
||||
return 'HTTP Status code ' . $code;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -47,12 +50,12 @@ class Linenotify extends Transport
|
||||
'title' => 'Token',
|
||||
'name' => 'line-notify-access-token',
|
||||
'descr' => 'LINE Notify Token',
|
||||
'type' => 'text'
|
||||
]
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'line-notify-access-token' => 'required|string',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,11 +21,12 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Mail extends Transport
|
||||
{
|
||||
@ -51,11 +52,11 @@ class Mail extends Transport
|
||||
'name' => 'email',
|
||||
'descr' => 'Email address of contact',
|
||||
'type' => 'text',
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'email' => 'required|email'
|
||||
]
|
||||
'email' => 'required|email',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,9 @@
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Matrix extends Transport
|
||||
{
|
||||
@ -36,6 +36,7 @@ class Matrix extends Transport
|
||||
$room = $this->config['matrix-room'];
|
||||
$authtoken = $this->config['matrix-authtoken'];
|
||||
$message = $this->config['matrix-message'];
|
||||
|
||||
return $this->contactMatrix($obj, $server, $room, $authtoken, $message);
|
||||
}
|
||||
|
||||
@ -46,7 +47,7 @@ class Matrix extends Transport
|
||||
$txnid = rand(1111, 9999) . time();
|
||||
|
||||
$server = preg_replace('/\/$/', '', $server);
|
||||
$host = $server."/_matrix/client/r0/rooms/".urlencode($room)."/send/m.room.message/".$txnid;
|
||||
$host = $server . "/_matrix/client/r0/rooms/" . urlencode($room) . "/send/m.room.message/" . $txnid;
|
||||
|
||||
$request_heads['Authorization'] = "Bearer $authtoken";
|
||||
$request_heads['Content-Type'] = "application/json";
|
||||
@ -56,7 +57,7 @@ class Matrix extends Transport
|
||||
$message = str_replace("{{ $" . $p_key . ' }}', $p_val, $message);
|
||||
}
|
||||
|
||||
$body = array('body'=>$message, 'msgtype'=>'m.text');
|
||||
$body = ['body'=>$message, 'msgtype'=>'m.text'];
|
||||
|
||||
$client = new \GuzzleHttp\Client();
|
||||
$request_opts['proxy'] = get_guzzle_proxy();
|
||||
@ -70,9 +71,11 @@ class Matrix extends Transport
|
||||
var_dump("Params:");
|
||||
var_dump("Response headers:");
|
||||
var_dump($res->getHeaders());
|
||||
var_dump("Return: ".$res->getReasonPhrase());
|
||||
return 'HTTP Status code '.$code;
|
||||
var_dump("Return: " . $res->getReasonPhrase());
|
||||
|
||||
return 'HTTP Status code ' . $code;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -103,13 +106,13 @@ class Matrix extends Transport
|
||||
'name' => 'matrix-message',
|
||||
'descr' => 'Enter the message',
|
||||
'type' => 'textarea',
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'matrix-server' => 'required',
|
||||
'matrix-room' => 'required',
|
||||
'matrix-authtoken' => 'required'
|
||||
]
|
||||
'matrix-authtoken' => 'required',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,10 +21,11 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Mattermost extends Transport
|
||||
{
|
||||
@ -67,7 +68,7 @@ class Mattermost extends Transport
|
||||
|
||||
set_curl_proxy($curl);
|
||||
|
||||
$httpheaders = array('Accept: application/json', 'Content-Type: application/json');
|
||||
$httpheaders = ['Accept: application/json', 'Content-Type: application/json'];
|
||||
$alert_payload = json_encode($data);
|
||||
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $httpheaders);
|
||||
@ -80,9 +81,11 @@ class Mattermost extends Transport
|
||||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
if ($code != 200) {
|
||||
d_echo("Mattermost Connection Error: " . $ret);
|
||||
|
||||
return 'HTTP Status code ' . $code;
|
||||
} else {
|
||||
d_echo("Mattermost message sent for " . $device);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -9,16 +9,17 @@
|
||||
* option) any later version. Please see LICENSE.txt at the top level of
|
||||
* the source code distribution for details.
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Msteams extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$opts['url'] = $this->config['msteam-url'];
|
||||
}
|
||||
|
||||
@ -28,19 +29,19 @@ class Msteams extends Transport
|
||||
public function contactMsteams($obj, $opts)
|
||||
{
|
||||
$url = $opts['url'];
|
||||
$data = array(
|
||||
$data = [
|
||||
'title' => $obj['title'],
|
||||
'themeColor' => self::getColorForState($obj['state']),
|
||||
'text' => strip_tags($obj['msg'], '<strong><em><h1><h2><h3><strike><ul><ol><li><pre><blockquote><a><img><p>')
|
||||
);
|
||||
'text' => strip_tags($obj['msg'], '<strong><em><h1><h2><h3><strike><ul><ol><li><pre><blockquote><a><img><p>'),
|
||||
];
|
||||
$curl = curl_init();
|
||||
set_curl_proxy($curl);
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, [
|
||||
'Content-type' => 'application/json',
|
||||
'Expect:'
|
||||
));
|
||||
'Expect:',
|
||||
]);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
|
||||
if ($this->config['use-json'] === 'on' && $obj['uid'] !== '000') {
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $obj['msg']);
|
||||
@ -49,8 +50,10 @@ class Msteams extends Transport
|
||||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
if ($code != 200) {
|
||||
var_dump("Microsoft Teams returned Error, retry later");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -70,11 +73,11 @@ class Msteams extends Transport
|
||||
'descr' => 'Compose MessageCard with JSON rather than Markdown',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'msteam-url' => 'required|url'
|
||||
]
|
||||
'msteam-url' => 'required|url',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,16 +21,18 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Nagios extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
$opts = $this->config['nagios-fifo'];
|
||||
|
||||
return $this->contactNagios($obj, $opts);
|
||||
}
|
||||
|
||||
@ -60,6 +62,7 @@ class Nagios extends Transport
|
||||
$format .= str_replace("\n", "", nl2br($obj['msg'])) . "\t";
|
||||
$format .= "NULL"; //FIXME: What's the HOSTPERFDATA equivalent for LibreNMS? Oo
|
||||
$format .= "\n";
|
||||
|
||||
return file_put_contents($opts, $format);
|
||||
}
|
||||
|
||||
@ -76,7 +79,7 @@ class Nagios extends Transport
|
||||
],
|
||||
'validation' => [
|
||||
'nagios-fifo' => 'required',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,18 +21,20 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Opsgenie extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$opts['url'] = $this->config['genie-url'];
|
||||
}
|
||||
|
||||
return $this->contactOpsgenie($obj, $opts);
|
||||
}
|
||||
|
||||
@ -46,7 +48,7 @@ class Opsgenie extends Transport
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($obj));
|
||||
|
||||
$ret = curl_exec($curl);
|
||||
@ -54,6 +56,7 @@ class Opsgenie extends Transport
|
||||
|
||||
if ($code != 200) {
|
||||
var_dump("Error when sending post request to OpsGenie. Response code: " . $code . " Response body: " . $ret); //FIXME: proper debugging
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -68,12 +71,12 @@ class Opsgenie extends Transport
|
||||
'title' => 'Webhook URL',
|
||||
'name' => 'genie-url',
|
||||
'descr' => 'OpsGenie Webhook URL',
|
||||
'type' => 'text'
|
||||
]
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'genie-url' => 'required|url'
|
||||
]
|
||||
'genie-url' => 'required|url',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -9,20 +9,22 @@
|
||||
* option) any later version. Please see LICENSE.txt at the top level of
|
||||
* the source code distribution for details.
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Osticket extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$opts['url'] = $this->config['os-url'];
|
||||
$opts['token'] = $this->config['os-token'];
|
||||
}
|
||||
|
||||
return $this->contactOsticket($obj, $opts);
|
||||
}
|
||||
|
||||
@ -36,29 +38,30 @@ class Osticket extends Transport
|
||||
break;
|
||||
}
|
||||
|
||||
$protocol = array(
|
||||
$protocol = [
|
||||
'name' => 'LibreNMS',
|
||||
'email' => $email,
|
||||
'subject' => ($obj['name'] ? $obj['name'] . ' on ' . $obj['hostname'] : $obj['title']),
|
||||
'message' => strip_tags($obj['msg']),
|
||||
'ip' => $_SERVER['REMOTE_ADDR'],
|
||||
'attachments' => array(),
|
||||
);
|
||||
'attachments' => [],
|
||||
];
|
||||
$curl = curl_init();
|
||||
set_curl_proxy($curl);
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, [
|
||||
'Content-type' => 'application/json',
|
||||
'Expect:',
|
||||
'X-API-Key: ' . $token
|
||||
));
|
||||
'X-API-Key: ' . $token,
|
||||
]);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($protocol));
|
||||
$ret = curl_exec($curl);
|
||||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
|
||||
if ($code != 201) {
|
||||
var_dump("osTicket returned Error, retry later");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -73,19 +76,19 @@ class Osticket extends Transport
|
||||
'title' => 'API URL',
|
||||
'name' => 'os-url',
|
||||
'descr' => 'osTicket API URL',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'API Token',
|
||||
'name' => 'os-token',
|
||||
'descr' => 'osTicket API Token',
|
||||
'type' => 'text'
|
||||
]
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'os-url' => 'required|url',
|
||||
'os-token' => 'required|string'
|
||||
]
|
||||
'os-token' => 'required|string',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ namespace LibreNMS\Alert\Transport;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Illuminate\Http\Request;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use Log;
|
||||
use Validator;
|
||||
|
||||
@ -45,6 +45,7 @@ class Pagerduty extends Transport
|
||||
} else {
|
||||
$obj['event_type'] = 'trigger';
|
||||
}
|
||||
|
||||
return $this->contactPagerduty($obj, $this->config);
|
||||
}
|
||||
|
||||
@ -58,7 +59,7 @@ class Pagerduty extends Transport
|
||||
$data = [
|
||||
'routing_key' => $config['service_key'],
|
||||
'event_action' => $obj['event_type'],
|
||||
'dedup_key' => (string)$obj['alert_id'],
|
||||
'dedup_key' => (string) $obj['alert_id'],
|
||||
'payload' => [
|
||||
'custom_details' => strip_tags($obj['msg']) ?: 'Test',
|
||||
'device_groups' => \DeviceCache::get($obj['device_id'])->groups->pluck('name'),
|
||||
@ -94,7 +95,7 @@ class Pagerduty extends Transport
|
||||
'type' => 'oauth',
|
||||
'icon' => 'pagerduty-white.svg',
|
||||
'class' => 'btn-success',
|
||||
'url' => 'https://connect.pagerduty.com/connect?vendor=' . self::$integrationKey . '&callback='
|
||||
'url' => 'https://connect.pagerduty.com/connect?vendor=' . self::$integrationKey . '&callback=',
|
||||
],
|
||||
[
|
||||
'title' => 'Account',
|
||||
@ -110,9 +111,9 @@ class Pagerduty extends Transport
|
||||
'title' => 'Integration Key',
|
||||
'type' => 'text',
|
||||
'name' => 'service_key',
|
||||
]
|
||||
],
|
||||
'validation' => []
|
||||
],
|
||||
'validation' => [],
|
||||
];
|
||||
}
|
||||
|
||||
@ -126,15 +127,16 @@ class Pagerduty extends Transport
|
||||
|
||||
if ($validator->fails()) {
|
||||
Log::error('Pagerduty oauth failed validation.', ['request' => $request->all()]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$config = json_encode($request->only('account', 'service_key', 'service_name'));
|
||||
|
||||
if ($id = $request->get('id')) {
|
||||
return (bool)dbUpdate(['transport_config' => $config], 'alert_transports', 'transport_id=?', [$id]);
|
||||
return (bool) dbUpdate(['transport_config' => $config], 'alert_transports', 'transport_id=?', [$id]);
|
||||
} else {
|
||||
return (bool)dbInsert([
|
||||
return (bool) dbInsert([
|
||||
'transport_name' => $request->get('service_name', 'PagerDuty'),
|
||||
'transport_type' => 'pagerduty',
|
||||
'is_default' => 0,
|
||||
|
@ -21,10 +21,11 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Playsms extends Transport
|
||||
{
|
||||
@ -35,13 +36,14 @@ class Playsms extends Transport
|
||||
$playsms_opts['token'] = $this->config['playsms-token'];
|
||||
$playsms_opts['from'] = $this->config['playsms-from'];
|
||||
$playsms_opts['to'] = preg_split('/([,\r\n]+)/', $this->config['playsms-mobiles']);
|
||||
|
||||
return $this->contactPlaysms($obj, $playsms_opts);
|
||||
}
|
||||
|
||||
public static function contactPlaysms($obj, $opts)
|
||||
{
|
||||
$data = array("u" => $opts['user'], "h" => $opts['token'], "to" => implode(',', $opts['to']), "msg" => $obj['title']);
|
||||
if (!empty($opts['from'])) {
|
||||
$data = ["u" => $opts['user'], "h" => $opts['token'], "to" => implode(',', $opts['to']), "msg" => $obj['title']];
|
||||
if (! empty($opts['from'])) {
|
||||
$data["from"] = $opts['from'];
|
||||
}
|
||||
$url = $opts['url'] . '&op=pv&' . http_build_query($data);
|
||||
@ -56,6 +58,7 @@ class Playsms extends Transport
|
||||
if ($code > 202) {
|
||||
return var_dump($ret);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -99,7 +102,7 @@ class Playsms extends Transport
|
||||
'playsms-user' => 'required|string',
|
||||
'playsms-token' => 'required|string',
|
||||
'playsms-mobiles' => 'required',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,18 +21,20 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Pushbullet extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$opts = $this->config['pushbullet-token'];
|
||||
}
|
||||
|
||||
return $this->contactPushbullet($obj, $opts);
|
||||
}
|
||||
|
||||
@ -40,7 +42,7 @@ class Pushbullet extends Transport
|
||||
{
|
||||
// Note: At this point it might be useful to iterate through $obj['contacts'] and send each of them a note ?
|
||||
|
||||
$data = array("type" => "note", "title" => $obj['title'], "body" => $obj['msg']);
|
||||
$data = ["type" => "note", "title" => $obj['title'], "body" => $obj['msg']];
|
||||
$data = json_encode($data);
|
||||
|
||||
$curl = curl_init('https://api.pushbullet.com/v2/pushes');
|
||||
@ -48,11 +50,11 @@ class Pushbullet extends Transport
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen($data),
|
||||
'Authorization: Bearer ' . $opts,
|
||||
));
|
||||
]);
|
||||
|
||||
$ret = curl_exec($curl);
|
||||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
@ -60,8 +62,10 @@ class Pushbullet extends Transport
|
||||
if ($debug) {
|
||||
var_dump($ret);
|
||||
}
|
||||
|
||||
return 'HTTP Status code ' . $code;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -73,12 +77,12 @@ class Pushbullet extends Transport
|
||||
'title' => 'Access Token',
|
||||
'name' => 'pushbullet-token',
|
||||
'descr' => 'Pushbullet Access Token',
|
||||
'type' => 'text'
|
||||
]
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'pushbullet-token' => 'required|string'
|
||||
]
|
||||
'pushbullet-token' => 'required|string',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -35,10 +35,11 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Pushover extends Transport
|
||||
{
|
||||
@ -52,19 +53,19 @@ class Pushover extends Transport
|
||||
|
||||
public function contactPushover($obj, $api)
|
||||
{
|
||||
$data = array();
|
||||
$data = [];
|
||||
$data['token'] = $api['appkey'];
|
||||
$data['user'] = $api['userkey'];
|
||||
switch ($obj['severity']) {
|
||||
case "critical":
|
||||
$data['priority'] = 1;
|
||||
if (!empty($api['options']['sound_critical'])) {
|
||||
if (! empty($api['options']['sound_critical'])) {
|
||||
$data['sound'] = $api['options']['sound_critical'];
|
||||
}
|
||||
break;
|
||||
case "warning":
|
||||
$data['priority'] = 1;
|
||||
if (!empty($api['options']['sound_warning'])) {
|
||||
if (! empty($api['options']['sound_warning'])) {
|
||||
$data['sound'] = $api['options']['sound_warning'];
|
||||
}
|
||||
break;
|
||||
@ -72,7 +73,7 @@ class Pushover extends Transport
|
||||
switch ($obj['state']) {
|
||||
case AlertState::RECOVERED:
|
||||
$data['priority'] = 0;
|
||||
if (!empty($api['options']['sound_ok'])) {
|
||||
if (! empty($api['options']['sound_ok'])) {
|
||||
$data['sound'] = $api['options']['sound_ok'];
|
||||
}
|
||||
break;
|
||||
@ -92,8 +93,10 @@ class Pushover extends Transport
|
||||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
if ($code != 200) {
|
||||
var_dump("Pushover returned error"); //FIXME: proper debugging
|
||||
|
||||
return 'HTTP Status code ' . $code;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -123,7 +126,7 @@ class Pushover extends Transport
|
||||
'validation' => [
|
||||
'appkey' => 'required',
|
||||
'userkey' => 'required',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,10 +21,11 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Rocket extends Transport
|
||||
{
|
||||
@ -42,22 +43,22 @@ class Rocket extends Transport
|
||||
$curl = curl_init();
|
||||
$rocket_msg = strip_tags($obj['msg']);
|
||||
$color = self::getColorForState($obj['state']);
|
||||
$data = array(
|
||||
'attachments' => array(
|
||||
0 => array(
|
||||
$data = [
|
||||
'attachments' => [
|
||||
0 => [
|
||||
'fallback' => $rocket_msg,
|
||||
'color' => $color,
|
||||
'title' => $obj['title'],
|
||||
'text' => $rocket_msg,
|
||||
)
|
||||
),
|
||||
],
|
||||
],
|
||||
'channel' => $api['channel'],
|
||||
'username' => $api['username'],
|
||||
'icon_url' => $api['icon_url'],
|
||||
'icon_emoji' => $api['icon_emoji'],
|
||||
);
|
||||
];
|
||||
$alert_message = json_encode($data);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
|
||||
set_curl_proxy($curl);
|
||||
curl_setopt($curl, CURLOPT_URL, $host);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
@ -70,8 +71,10 @@ class Rocket extends Transport
|
||||
var_dump("API '$host' returned Error"); //FIXME: propper debuging
|
||||
var_dump("Params: " . $alert_message); //FIXME: propper debuging
|
||||
var_dump("Return: " . $ret); //FIXME: propper debuging
|
||||
|
||||
return 'HTTP Status code ' . $code;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -90,11 +93,11 @@ class Rocket extends Transport
|
||||
'name' => 'rocket-options',
|
||||
'descr' => 'Rocket.chat Options',
|
||||
'type' => 'textarea',
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'rocket-url' => 'required|url',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -20,15 +20,15 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Config;
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Sensu extends Transport
|
||||
{
|
||||
@ -38,19 +38,19 @@ class Sensu extends Transport
|
||||
const CRITICAL = 2;
|
||||
const UNKNOWN = 3;
|
||||
|
||||
private static $status = array(
|
||||
private static $status = [
|
||||
'ok' => Sensu::OK,
|
||||
'warning' => Sensu::WARNING,
|
||||
'critical' => Sensu::CRITICAL
|
||||
);
|
||||
'critical' => Sensu::CRITICAL,
|
||||
];
|
||||
|
||||
private static $severity = array(
|
||||
private static $severity = [
|
||||
'recovered' => AlertState::RECOVERED,
|
||||
'alert' => AlertState::ACTIVE,
|
||||
'acknowledged' => AlertState::ACKNOWLEDGED,
|
||||
'worse' => AlertState::WORSE,
|
||||
'better' => AlertState::BETTER,
|
||||
);
|
||||
];
|
||||
|
||||
private static $client = null;
|
||||
|
||||
@ -127,7 +127,7 @@ class Sensu extends Transport
|
||||
'system' => [
|
||||
'hostname' => $obj['hostname'],
|
||||
'os' => $obj['os'],
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
@ -237,15 +237,15 @@ class Sensu extends Transport
|
||||
'options' => [
|
||||
'hostname' => 'hostname',
|
||||
'sysName' => 'sysName',
|
||||
'shortname' => 'shortname'
|
||||
'shortname' => 'shortname',
|
||||
],
|
||||
'default' => 'hostname'
|
||||
'default' => 'hostname',
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'sensu-url' => 'url',
|
||||
'sensu-source-key' => 'required|in:hostname,sysName,shortname',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,10 +21,11 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Slack extends Transport
|
||||
{
|
||||
@ -55,7 +56,7 @@ class Slack extends Transport
|
||||
],
|
||||
'channel' => $api['channel'],
|
||||
'username' => $api['username'],
|
||||
'icon_emoji' => ':' .$api['icon_emoji'].':',
|
||||
'icon_emoji' => ':' . $api['icon_emoji'] . ':',
|
||||
];
|
||||
$alert_message = json_encode($data);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
|
||||
@ -71,8 +72,10 @@ class Slack extends Transport
|
||||
var_dump("API '$host' returned Error"); //FIXME: propper debuging
|
||||
var_dump("Params: " . $alert_message); //FIXME: propper debuging
|
||||
var_dump("Return: " . $ret); //FIXME: propper debuging
|
||||
|
||||
return 'HTTP Status code ' . $code;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -91,11 +94,11 @@ class Slack extends Transport
|
||||
'name' => 'slack-options',
|
||||
'descr' => 'Slack Options',
|
||||
'type' => 'textarea',
|
||||
]
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'slack-url' => 'required|url',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,11 +21,12 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use Illuminate\Support\Str;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Smseagle extends Transport
|
||||
{
|
||||
@ -35,6 +36,7 @@ class Smseagle extends Transport
|
||||
$smseagle_opts['user'] = $this->config['smseagle-user'];
|
||||
$smseagle_opts['token'] = $this->config['smseagle-pass'];
|
||||
$smseagle_opts['to'] = preg_split('/([,\r\n]+)/', $this->config['smseagle-mobiles']);
|
||||
|
||||
return $this->contactSmseagle($obj, $smseagle_opts);
|
||||
}
|
||||
|
||||
@ -96,7 +98,7 @@ class Smseagle extends Transport
|
||||
'smseagle-user' => 'required|string',
|
||||
'smseagle-pass' => 'required|string',
|
||||
'smseagle-mobiles' => 'required',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -21,10 +21,11 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Smsfeedback extends Transport
|
||||
{
|
||||
@ -34,6 +35,7 @@ class Smsfeedback extends Transport
|
||||
$smsfeedback_opts['token'] = $this->config['smsfeedback-pass'];
|
||||
$smsfeedback_opts['sender'] = $this->config['smsfeedback-sender'];
|
||||
$smsfeedback_opts['to'] = $this->config['smsfeedback-mobiles'];
|
||||
|
||||
return $this->contactsmsfeedback($obj, $smsfeedback_opts);
|
||||
}
|
||||
|
||||
@ -93,7 +95,7 @@ class Smsfeedback extends Transport
|
||||
'smsfeedback-pass' => 'required|string',
|
||||
'smsfeedback-mobiles' => 'required',
|
||||
'smsfeedback-sender' => 'required|string',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -14,19 +14,21 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Splunk extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$opts['splunk_host'] = $this->config['Splunk-host'];
|
||||
$opts['splunk_port'] = $this->config['Splunk-port'];
|
||||
}
|
||||
|
||||
return $this->contactSplunk($obj, $opts);
|
||||
}
|
||||
|
||||
@ -37,23 +39,25 @@ class Splunk extends Transport
|
||||
$severity = 6; // Default severity is 6 (Informational)
|
||||
$device = device_by_id_cache($obj['device_id']); // for event logging
|
||||
|
||||
if (!empty($opts['splunk_host'])) {
|
||||
if (! empty($opts['splunk_host'])) {
|
||||
if (preg_match("/[a-zA-Z]/", $opts['splunk_host'])) {
|
||||
$splunk_host = gethostbyname($opts['splunk_host']);
|
||||
if ($splunk_host === $opts['splunk_host']) {
|
||||
log_event("Alphanumeric hostname found but does not resolve to an IP.", $device, 'poller', 5);
|
||||
|
||||
return false;
|
||||
}
|
||||
} elseif (filter_var($opts['splunk_host'], FILTER_VALIDATE_IP)) {
|
||||
$splunk_host = $opts['splunk_host'];
|
||||
} else {
|
||||
log_event("Splunk host is not a valid IP: " . $opts['splunk_host'], $device, 'poller', 5);
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
log_event("Splunk host is empty.", $device, 'poller');
|
||||
}
|
||||
if (!empty($opts['splunk_port']) && preg_match("/^\d+$/", $opts['splunk_port'])) {
|
||||
if (! empty($opts['splunk_port']) && preg_match("/^\d+$/", $opts['splunk_port'])) {
|
||||
$splunk_port = $opts['splunk_port'];
|
||||
} else {
|
||||
log_event("Splunk port is not an integer.", $device, 'poller', 5);
|
||||
@ -77,7 +81,7 @@ class Splunk extends Transport
|
||||
break;
|
||||
}
|
||||
|
||||
$ignore = array("template", "contacts", "rule", "string", "debug", "faults", "builder", "transport", "alert", "msg", "transport_name");
|
||||
$ignore = ["template", "contacts", "rule", "string", "debug", "faults", "builder", "transport", "alert", "msg", "transport_name"];
|
||||
$splunk_prefix = '<' . $severity . '> ';
|
||||
foreach ($obj as $key => $val) {
|
||||
if (in_array($key, $ignore)) {
|
||||
@ -87,7 +91,7 @@ class Splunk extends Transport
|
||||
$splunk_prefix .= $key . '="' . $val . '", ';
|
||||
}
|
||||
|
||||
$ignore = array("attribs", "vrf_lite_cisco", "community", "authlevel", "authname", "authpass", "authalgo", "cryptopass", "cryptoalgo", "snmpver", "port");
|
||||
$ignore = ["attribs", "vrf_lite_cisco", "community", "authlevel", "authname", "authpass", "authalgo", "cryptopass", "cryptoalgo", "snmpver", "port"];
|
||||
foreach ($device as $key => $val) {
|
||||
if (in_array($key, $ignore)) {
|
||||
continue;
|
||||
@ -99,9 +103,10 @@ class Splunk extends Transport
|
||||
|
||||
if (($socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) === false) {
|
||||
log_event("socket_create() failed: reason: " . socket_strerror(socket_last_error()), $device, 'poller', 5);
|
||||
|
||||
return false;
|
||||
} else {
|
||||
if (!empty($obj['faults'])) {
|
||||
if (! empty($obj['faults'])) {
|
||||
foreach ($obj['faults'] as $k => $v) {
|
||||
$splunk_msg = $splunk_prefix . ' - ' . $v['string'];
|
||||
socket_sendto($socket, $splunk_msg, strlen($splunk_msg), 0, $splunk_host, $splunk_port);
|
||||
@ -112,6 +117,7 @@ class Splunk extends Transport
|
||||
}
|
||||
socket_close($socket);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -123,19 +129,19 @@ class Splunk extends Transport
|
||||
'title' => 'Host',
|
||||
'name' => 'Splunk-host',
|
||||
'descr' => 'Splunk Host',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'UDP Port',
|
||||
'name' => 'Splunk-port',
|
||||
'descr' => 'Splunk Port',
|
||||
'type' => 'text'
|
||||
]
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'Splunk-host' => 'required|string',
|
||||
'Splunk-port' => 'required|numeric'
|
||||
]
|
||||
'Splunk-port' => 'required|numeric',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -14,20 +14,22 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Syslog extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$opts['syslog_host'] = $this->config['syslog-host'];
|
||||
$opts['syslog_port'] = $this->config['syslog-port'];
|
||||
$opts['syslog_facility'] = $this->config['syslog-facility'];
|
||||
}
|
||||
|
||||
return $this->contactSyslog($obj, $opts);
|
||||
}
|
||||
|
||||
@ -41,28 +43,30 @@ class Syslog extends Transport
|
||||
$sev_txt = "OK";
|
||||
$device = device_by_id_cache($obj['device_id']); // for event logging
|
||||
|
||||
if (!empty($opts['syslog_facility']) && preg_match("/^\d+$/", $opts['syslog_facility'])) {
|
||||
$facility = (int)$opts['syslog_facility'] * 8;
|
||||
if (! empty($opts['syslog_facility']) && preg_match("/^\d+$/", $opts['syslog_facility'])) {
|
||||
$facility = (int) $opts['syslog_facility'] * 8;
|
||||
} else {
|
||||
log_event("Syslog facility is not an integer: " . $opts['syslog_facility'], $device, 'poller', 5);
|
||||
}
|
||||
if (!empty($opts['syslog_host'])) {
|
||||
if (! empty($opts['syslog_host'])) {
|
||||
if (preg_match("/[a-zA-Z]/", $opts['syslog_host'])) {
|
||||
$syslog_host = gethostbyname($opts['syslog_host']);
|
||||
if ($syslog_host === $opts['syslog_host']) {
|
||||
log_event("Alphanumeric hostname found but does not resolve to an IP.", $device, 'poller', 5);
|
||||
|
||||
return false;
|
||||
}
|
||||
} elseif (filter_var($opts['syslog_host'], FILTER_VALIDATE_IP)) {
|
||||
$syslog_host = $opts['syslog_host'];
|
||||
} else {
|
||||
log_event("Syslog host is not a valid IP: " . $opts['syslog_host'], $device, 'poller', 5);
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
log_event("Syslog host is empty.", $device, 'poller');
|
||||
}
|
||||
if (!empty($opts['syslog_port']) && preg_match("/^\d+$/", $opts['syslog_port'])) {
|
||||
if (! empty($opts['syslog_port']) && preg_match("/^\d+$/", $opts['syslog_port'])) {
|
||||
$syslog_port = $opts['syslog_port'];
|
||||
} else {
|
||||
log_event("Syslog port is not an integer.", $device, 'poller', 5);
|
||||
@ -112,9 +116,10 @@ class Syslog extends Transport
|
||||
|
||||
if (($socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) === false) {
|
||||
log_event("socket_create() failed: reason: " . socket_strerror(socket_last_error()), $device, 'poller', 5);
|
||||
|
||||
return false;
|
||||
} else {
|
||||
if (!empty($obj['faults'])) {
|
||||
if (! empty($obj['faults'])) {
|
||||
foreach ($obj['faults'] as $k => $v) {
|
||||
$syslog_msg = $syslog_prefix . ' - ' . $v['string'];
|
||||
socket_sendto($socket, $syslog_msg, strlen($syslog_msg), 0, $syslog_host, $syslog_port);
|
||||
@ -125,6 +130,7 @@ class Syslog extends Transport
|
||||
}
|
||||
socket_close($socket);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -136,26 +142,26 @@ class Syslog extends Transport
|
||||
'title' => 'Host',
|
||||
'name' => 'syslog-host',
|
||||
'descr' => 'Syslog Host',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Port',
|
||||
'name' => 'syslog-port',
|
||||
'descr' => 'Syslog Port',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Facility',
|
||||
'name' => 'syslog-facility',
|
||||
'descr' => 'Syslog Facility',
|
||||
'type' => 'text'
|
||||
]
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'syslog-host' => 'required|string',
|
||||
'syslog-port' => 'required|numeric',
|
||||
'syslog-facility' => 'required|string'
|
||||
]
|
||||
'syslog-facility' => 'required|string',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* transport-telegram.inc.php
|
||||
*
|
||||
* LibreNMS Telegram alerting transport
|
||||
*
|
||||
* 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 2017 Neil Lathwood
|
||||
* @author Neil Lathwood <neil@lathwood.co.uk>
|
||||
*/
|
||||
* transport-telegram.inc.php
|
||||
*
|
||||
* LibreNMS Telegram alerting transport
|
||||
*
|
||||
* 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 2017 Neil Lathwood
|
||||
* @author Neil Lathwood <neil@lathwood.co.uk>
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Telegram extends Transport
|
||||
{
|
||||
@ -34,6 +35,7 @@ class Telegram extends Transport
|
||||
$telegram_opts['chat_id'] = $this->config['telegram-chat-id'];
|
||||
$telegram_opts['token'] = $this->config['telegram-token'];
|
||||
$telegram_opts['format'] = $this->config['telegram-format'];
|
||||
|
||||
return $this->contactTelegram($obj, $telegram_opts);
|
||||
}
|
||||
|
||||
@ -42,9 +44,9 @@ class Telegram extends Transport
|
||||
$curl = curl_init();
|
||||
set_curl_proxy($curl);
|
||||
$text = urlencode($obj['msg']);
|
||||
$format="";
|
||||
$format = "";
|
||||
if ($data['format']) {
|
||||
$format="&parse_mode=" . $data['format'];
|
||||
$format = "&parse_mode=" . $data['format'];
|
||||
if ($data['format'] == 'Markdown') {
|
||||
$text = urlencode(preg_replace("/([a-z0-9]+)_([a-z0-9]+)/", "$1\_$2", $obj['msg']));
|
||||
}
|
||||
@ -57,8 +59,10 @@ class Telegram extends Transport
|
||||
var_dump("API '$host' returned Error"); //FIXME: propper debuging
|
||||
var_dump("Params: " . $api); //FIXME: propper debuging
|
||||
var_dump("Return: " . $ret); //FIXME: propper debuging
|
||||
|
||||
return 'HTTP Status code ' . $code;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -86,15 +90,15 @@ class Telegram extends Transport
|
||||
'options' => [
|
||||
'' => '',
|
||||
'Markdown' => 'Markdown',
|
||||
'HTML' => 'HTML'
|
||||
]
|
||||
]
|
||||
'HTML' => 'HTML',
|
||||
],
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'telegram-chat-id' => 'required|string',
|
||||
'telegram-token' => 'required|string',
|
||||
'telegram-format' => 'string',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -13,10 +13,11 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Twilio extends Transport
|
||||
{
|
||||
@ -26,6 +27,7 @@ class Twilio extends Transport
|
||||
$twilio_opts['token'] = $this->config['twilio-token'];
|
||||
$twilio_opts['sender'] = $this->config['twilio-sender'];
|
||||
$twilio_opts['to'] = $this->config['twilio-to'];
|
||||
|
||||
return $this->contacttwilio($obj, $twilio_opts);
|
||||
}
|
||||
|
||||
@ -56,7 +58,7 @@ class Twilio extends Transport
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($curl, CURLOPT_USERPWD, $params["sid"]. ":" . $params["token"]);
|
||||
curl_setopt($curl, CURLOPT_USERPWD, $params["sid"] . ":" . $params["token"]);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
|
||||
|
||||
curl_exec($curl);
|
||||
@ -100,7 +102,7 @@ class Twilio extends Transport
|
||||
'twilio-token' => 'required|string',
|
||||
'twilio-to' => 'required',
|
||||
'twilio-sender' => 'required',
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -22,18 +22,20 @@
|
||||
* @package LibreNMS
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Enum\AlertState;
|
||||
use LibreNMS\Alert\Transport;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class Victorops extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
if (!empty($this->config)) {
|
||||
if (! empty($this->config)) {
|
||||
$opts['url'] = $this->config['victorops-url'];
|
||||
}
|
||||
|
||||
return $this->contactVictorops($obj, $opts);
|
||||
}
|
||||
|
||||
@ -41,13 +43,13 @@ class Victorops extends Transport
|
||||
{
|
||||
$url = $opts['url'];
|
||||
|
||||
$protocol = array(
|
||||
$protocol = [
|
||||
'entity_id' => strval($obj['id'] ? $obj['id'] : $obj['uid']),
|
||||
'state_start_time' => strtotime($obj['timestamp']),
|
||||
'entity_display_name' => $obj['title'],
|
||||
'state_message' => $obj['msg'],
|
||||
'monitoring_tool' => 'librenms',
|
||||
);
|
||||
];
|
||||
if ($obj['state'] == AlertState::RECOVERED) {
|
||||
$protocol['message_type'] = 'recovery';
|
||||
} elseif ($obj['state'] == AlertState::ACKNOWLEDGED) {
|
||||
@ -64,14 +66,16 @@ class Victorops extends Transport
|
||||
set_curl_proxy($curl);
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type' => 'application/json'));
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-type' => 'application/json']);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($protocol));
|
||||
$ret = curl_exec($curl);
|
||||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
if ($code != 200) {
|
||||
var_dump("VictorOps returned Error, retry later"); //FIXME: propper debuging
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -83,12 +87,12 @@ class Victorops extends Transport
|
||||
'title' => 'Post URL',
|
||||
'name' => 'victorops-url',
|
||||
'descr' => 'Victorops Post URL',
|
||||
'type' => 'text'
|
||||
]
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
'validation' => [
|
||||
'victorops-url' => 'required|string'
|
||||
]
|
||||
'victorops-url' => 'required|string',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -92,11 +92,11 @@ class QueryBuilderFilter implements \JsonSerializable
|
||||
$db_schema = $this->schema->getSchema();
|
||||
$valid_tables = array_diff(array_keys($this->schema->getAllRelationshipPaths()), self::$table_blacklist);
|
||||
|
||||
foreach ((array)$db_schema as $table => $data) {
|
||||
foreach ((array) $db_schema as $table => $data) {
|
||||
$columns = array_column($data['Columns'], 'Type', 'Field');
|
||||
|
||||
// only allow tables with a direct association to device_id
|
||||
if (!in_array($table, $valid_tables)) {
|
||||
if (! in_array($table, $valid_tables)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -143,7 +143,6 @@ class QueryBuilderFilter implements \JsonSerializable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function getColumnType($type)
|
||||
{
|
||||
if (Str::startsWith($type, ['varchar', 'text', 'double', 'float'])) {
|
||||
@ -172,6 +171,7 @@ class QueryBuilderFilter implements \JsonSerializable
|
||||
{
|
||||
$filter = $this->filter;
|
||||
asort($filter);
|
||||
|
||||
return array_values($filter);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ class QueryBuilderFluentParser extends QueryBuilderParser
|
||||
*/
|
||||
public function toQuery()
|
||||
{
|
||||
if (empty($this->builder) || !array_key_exists('condition', $this->builder)) {
|
||||
if (empty($this->builder) || ! array_key_exists('condition', $this->builder)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ class QueryBuilderFluentParser extends QueryBuilderParser
|
||||
*/
|
||||
protected function parseGroupToQuery($query, $rule, $parent_condition = null)
|
||||
{
|
||||
return $query->where(function ($query) use ($rule, $parent_condition) {
|
||||
return $query->where(function ($query) use ($rule) {
|
||||
foreach ($rule['rules'] as $group_rule) {
|
||||
if (array_key_exists('condition', $group_rule)) {
|
||||
$this->parseGroupToQuery($query, $group_rule, $rule['condition']);
|
||||
@ -79,7 +79,7 @@ class QueryBuilderFluentParser extends QueryBuilderParser
|
||||
*/
|
||||
protected function parseRuleToQuery($query, $rule, $condition)
|
||||
{
|
||||
list($field, $op, $value) = $this->expandRule($rule);
|
||||
[$field, $op, $value] = $this->expandRule($rule);
|
||||
|
||||
switch ($op) {
|
||||
case 'equal':
|
||||
@ -140,7 +140,7 @@ class QueryBuilderFluentParser extends QueryBuilderParser
|
||||
$op = $rule['operator'];
|
||||
|
||||
$value = $rule['value'];
|
||||
if (!is_array($value) && Str::startsWith($value, '`') && Str::endsWith($value, '`')) {
|
||||
if (! is_array($value) && Str::startsWith($value, '`') && Str::endsWith($value, '`')) {
|
||||
$value = DB::raw($this->expandMacro(trim($value, '`')));
|
||||
}
|
||||
|
||||
@ -153,12 +153,12 @@ class QueryBuilderFluentParser extends QueryBuilderParser
|
||||
*/
|
||||
protected function joinTables($query)
|
||||
{
|
||||
if (!isset($this->builder['joins'])) {
|
||||
if (! isset($this->builder['joins'])) {
|
||||
$this->generateJoins();
|
||||
}
|
||||
|
||||
foreach ($this->builder['joins'] as $join) {
|
||||
list($rightTable, $left, $right) = $join;
|
||||
[$rightTable, $left, $right] = $join;
|
||||
$query->leftJoin($rightTable, $left, $right);
|
||||
}
|
||||
|
||||
@ -175,10 +175,10 @@ class QueryBuilderFluentParser extends QueryBuilderParser
|
||||
{
|
||||
$joins = [];
|
||||
foreach ($this->generateGlue() as $glue) {
|
||||
list($left, $right) = explode(' = ', $glue, 2);
|
||||
[$left, $right] = explode(' = ', $glue, 2);
|
||||
if (Str::contains($right, '.')) { // last line is devices.device_id = ? for alerting... ignore it
|
||||
list($leftTable, $leftKey) = explode('.', $left);
|
||||
list($rightTable, $rightKey) = explode('.', $right);
|
||||
[$leftTable, $leftKey] = explode('.', $left);
|
||||
[$rightTable, $rightKey] = explode('.', $right);
|
||||
$target_table = ($rightTable != 'devices' ? $rightTable : $leftTable); // don't try to join devices
|
||||
|
||||
$joins[] = [$target_table, $left, $right];
|
||||
|
@ -97,7 +97,7 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
*/
|
||||
public function getTables()
|
||||
{
|
||||
if (!isset($this->tables)) {
|
||||
if (! isset($this->tables)) {
|
||||
$this->tables = $this->findTablesRecursive($this->builder);
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
if (array_key_exists('rules', $rule)) {
|
||||
$tables = array_merge($this->findTablesRecursive($rule), $tables);
|
||||
} elseif (Str::contains($rule['field'], '.')) {
|
||||
list($table, $column) = explode('.', $rule['field']);
|
||||
[$table, $column] = explode('.', $rule['field']);
|
||||
|
||||
if ($table == 'macros') {
|
||||
$tables = array_merge($this->expandMacro($rule['field'], true), $tables);
|
||||
@ -148,7 +148,7 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
*/
|
||||
public static function fromJson($json)
|
||||
{
|
||||
if (!is_array($json)) {
|
||||
if (! is_array($json)) {
|
||||
$json = json_decode($json, true) ?: [];
|
||||
}
|
||||
|
||||
@ -174,13 +174,13 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
continue; // likely the ending && or ||
|
||||
}
|
||||
|
||||
@list($rule_text, $rule_operator) = $chunk;
|
||||
if (!isset($condition)) {
|
||||
@[$rule_text, $rule_operator] = $chunk;
|
||||
if (! isset($condition)) {
|
||||
// only allow one condition. Since old rules had no grouping, this should hold logically
|
||||
$condition = ($rule_operator == '||' ? 'OR' : 'AND');
|
||||
}
|
||||
|
||||
@list($field, $op, $value) = preg_split('/ *([!=<>~]{1,2}) */', trim($rule_text), 2, PREG_SPLIT_DELIM_CAPTURE);
|
||||
@[$field, $op, $value] = preg_split('/ *([!=<>~]{1,2}) */', trim($rule_text), 2, PREG_SPLIT_DELIM_CAPTURE);
|
||||
$field = ltrim($field, '%');
|
||||
|
||||
// for rules missing values just use '= 1'
|
||||
@ -235,7 +235,7 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
*/
|
||||
public function toSql($expand = true)
|
||||
{
|
||||
if (empty($this->builder) || !array_key_exists('condition', $this->builder)) {
|
||||
if (empty($this->builder) || ! array_key_exists('condition', $this->builder)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
$wrap = false;
|
||||
|
||||
if ($expand) {
|
||||
$sql = 'SELECT * FROM ' .implode(',', $this->getTables());
|
||||
$sql = 'SELECT * FROM ' . implode(',', $this->getTables());
|
||||
$sql .= ' WHERE (' . implode(' AND ', $this->generateGlue()) . ') AND ';
|
||||
|
||||
// only wrap in ( ) if the condition is OR and there is more than one rule
|
||||
@ -308,7 +308,7 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
$value = preg_replace_callback('/\?/', function ($matches) use (&$values) {
|
||||
return array_shift($values);
|
||||
}, self::$values[$builder_op]);
|
||||
} elseif (!is_numeric($value)) {
|
||||
} elseif (! is_numeric($value)) {
|
||||
// wrap quotes around non-numeric values
|
||||
$value = "\"$value\"";
|
||||
}
|
||||
@ -330,7 +330,7 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
*/
|
||||
protected function expandMacro($subject, $tables_only = false, $depth_limit = 20)
|
||||
{
|
||||
if (!Str::contains($subject, 'macros.')) {
|
||||
if (! Str::contains($subject, 'macros.')) {
|
||||
return $subject;
|
||||
}
|
||||
|
||||
@ -350,6 +350,7 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
|
||||
if ($tables_only) {
|
||||
preg_match_all('/%([^%.]+)\./', $subject, $matches);
|
||||
|
||||
return array_unique($matches[1]);
|
||||
}
|
||||
|
||||
@ -357,14 +358,13 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
$subject = preg_replace('/%([^%.]+)\./', '$1.', $subject);
|
||||
|
||||
// wrap entire macro result in parenthesis if needed
|
||||
if (!(Str::startsWith($subject, '(') && Str::endsWith($subject, ')'))) {
|
||||
if (! (Str::startsWith($subject, '(') && Str::endsWith($subject, ')'))) {
|
||||
$subject = "($subject)";
|
||||
}
|
||||
|
||||
return $subject;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate glue and first part of sql query for this rule
|
||||
*
|
||||
@ -383,7 +383,7 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
$path = $this->schema->findRelationshipPath($table, $target);
|
||||
if ($path) {
|
||||
foreach (array_pairs($path) as $pair) {
|
||||
list($left, $right) = $pair;
|
||||
[$left, $right] = $pair;
|
||||
$glue[] = $this->getGlue($left, $right);
|
||||
}
|
||||
}
|
||||
@ -412,6 +412,7 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
|
||||
if (count($shared_keys) === 1) {
|
||||
$shared_key = reset($shared_keys);
|
||||
|
||||
return "$parent.$shared_key = $child.$shared_key";
|
||||
}
|
||||
|
||||
@ -419,12 +420,12 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
$flipped = empty($parent_key);
|
||||
if ($flipped) {
|
||||
// if the "parent" table doesn't have a primary key, flip them
|
||||
list($parent, $child) = [$child, $parent];
|
||||
[$parent, $child] = [$child, $parent];
|
||||
$parent_key = $this->schema->getPrimaryKey($parent);
|
||||
}
|
||||
$child_key = $parent_key; // assume the column names match
|
||||
|
||||
if (!$this->schema->columnExists($child, $child_key)) {
|
||||
if (! $this->schema->columnExists($child, $child_key)) {
|
||||
// if they don't match, guess the column name from the parent
|
||||
if (Str::endsWith($parent, 'xes')) {
|
||||
$child_key = substr($parent, 0, -2) . '_id';
|
||||
@ -432,7 +433,7 @@ class QueryBuilderParser implements \JsonSerializable
|
||||
$child_key = preg_replace('/s$/', '_id', $parent);
|
||||
}
|
||||
|
||||
if (!$this->schema->columnExists($child, $child_key)) {
|
||||
if (! $this->schema->columnExists($child, $child_key)) {
|
||||
$child_key = $this->schema->getPrimaryKey($child);
|
||||
\Log::warning("QueryBuilderParser: Warning, guessing glue from $child.$child_key to $parent.$parent_key");
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ class ADAuthorizationAuthorizer extends MysqlAuthorizer
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (!function_exists('ldap_connect')) {
|
||||
if (! function_exists('ldap_connect')) {
|
||||
throw new LdapMissingException();
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ class ADAuthorizationAuthorizer extends MysqlAuthorizer
|
||||
if (Config::has('auth_ad_check_certificates') &&
|
||||
Config::get('auth_ad_check_certificates') == 0) {
|
||||
putenv('LDAPTLS_REQCERT=never');
|
||||
};
|
||||
}
|
||||
|
||||
// Set up connection to LDAP server
|
||||
$this->ldap_connection = @ldap_connect(Config::get('auth_ad_url'));
|
||||
@ -75,7 +75,7 @@ class ADAuthorizationAuthorizer extends MysqlAuthorizer
|
||||
$this->ldap_connection,
|
||||
Config::get('auth_ad_base_dn'),
|
||||
$this->userFilter($username),
|
||||
array('samaccountname')
|
||||
['samaccountname']
|
||||
);
|
||||
$entries = ldap_get_entries($this->ldap_connection, $search);
|
||||
|
||||
@ -85,13 +85,13 @@ class ADAuthorizationAuthorizer extends MysqlAuthorizer
|
||||
* want to speed up.
|
||||
*/
|
||||
$this->authLdapSessionCacheSet('user_exists', 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public function getUserlevel($username)
|
||||
{
|
||||
$userlevel = $this->authLdapSessionCacheGet('userlevel');
|
||||
@ -106,7 +106,7 @@ class ADAuthorizationAuthorizer extends MysqlAuthorizer
|
||||
$this->ldap_connection,
|
||||
Config::get('auth_ad_base_dn'),
|
||||
$this->userFilter($username),
|
||||
array('memberOf')
|
||||
['memberOf']
|
||||
);
|
||||
$entries = ldap_get_entries($this->ldap_connection, $search);
|
||||
|
||||
@ -120,10 +120,10 @@ class ADAuthorizationAuthorizer extends MysqlAuthorizer
|
||||
}
|
||||
|
||||
$this->authLdapSessionCacheSet('userlevel', $userlevel);
|
||||
|
||||
return $userlevel;
|
||||
}
|
||||
|
||||
|
||||
public function getUserid($username)
|
||||
{
|
||||
$user_id = $this->authLdapSessionCacheGet('userid');
|
||||
@ -133,7 +133,7 @@ class ADAuthorizationAuthorizer extends MysqlAuthorizer
|
||||
$user_id = -1;
|
||||
}
|
||||
|
||||
$attributes = array('objectsid');
|
||||
$attributes = ['objectsid'];
|
||||
$search = ldap_search(
|
||||
$this->ldap_connection,
|
||||
Config::get('auth_ad_base_dn'),
|
||||
@ -147,6 +147,7 @@ class ADAuthorizationAuthorizer extends MysqlAuthorizer
|
||||
}
|
||||
|
||||
$this->authLdapSessionCacheSet('userid', $user_id);
|
||||
|
||||
return $user_id;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
// easier to rewrite for Active Directory than to bash it into existing LDAP implementation
|
||||
|
||||
// disable certificate checking before connect if required
|
||||
|
||||
namespace LibreNMS\Authentication;
|
||||
|
||||
use LibreNMS\Config;
|
||||
@ -24,12 +25,12 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
|
||||
if ($this->ldap_connection) {
|
||||
// bind with sAMAccountName instead of full LDAP DN
|
||||
if (!empty($credentials['username']) && !empty($credentials['password']) && ldap_bind($this->ldap_connection, $credentials['username'] . '@' . Config::get('auth_ad_domain'), $credentials['password'])) {
|
||||
if (! empty($credentials['username']) && ! empty($credentials['password']) && ldap_bind($this->ldap_connection, $credentials['username'] . '@' . Config::get('auth_ad_domain'), $credentials['password'])) {
|
||||
$this->is_bound = true;
|
||||
// group membership in one of the configured groups is required
|
||||
if (Config::get('auth_ad_require_groupmembership', true)) {
|
||||
// cycle through defined groups, test for memberOf-ship
|
||||
foreach (Config::get('auth_ad_groups', array()) as $group => $level) {
|
||||
foreach (Config::get('auth_ad_groups', []) as $group => $level) {
|
||||
if ($this->userInGroup($credentials['username'], $group)) {
|
||||
return true;
|
||||
}
|
||||
@ -52,7 +53,7 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
throw new AuthenticationException('A password is required');
|
||||
} elseif (Config::get('auth_ad_debug', false)) {
|
||||
ldap_get_option($this->ldap_connection, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extended_error);
|
||||
throw new AuthenticationException(ldap_error($this->ldap_connection).'<br />'.$extended_error);
|
||||
throw new AuthenticationException(ldap_error($this->ldap_connection) . '<br />' . $extended_error);
|
||||
}
|
||||
|
||||
throw new AuthenticationException(ldap_error($this->ldap_connection));
|
||||
@ -70,7 +71,7 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
$connection,
|
||||
Config::get('auth_ad_base_dn'),
|
||||
$search_filter,
|
||||
array("cn")
|
||||
["cn"]
|
||||
);
|
||||
$result = ldap_get_entries($connection, $search);
|
||||
|
||||
@ -97,11 +98,11 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
// add 'LDAP_MATCHING_RULE_IN_CHAIN to the user filter to search for $username in nested $group_dn
|
||||
// limiting to "DN" for shorter array
|
||||
"(&" . $this->userFilter($username) . "(memberOf:1.2.840.113556.1.4.1941:=$group_dn))",
|
||||
array("DN")
|
||||
["DN"]
|
||||
);
|
||||
$entries = ldap_get_entries($connection, $search);
|
||||
|
||||
return ($entries["count"] > 0);
|
||||
return $entries["count"] > 0;
|
||||
}
|
||||
|
||||
public function userExists($username, $throw_exception = false)
|
||||
@ -112,11 +113,10 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
$connection,
|
||||
Config::get('auth_ad_base_dn'),
|
||||
$this->userFilter($username),
|
||||
array('samaccountname')
|
||||
['samaccountname']
|
||||
);
|
||||
$entries = ldap_get_entries($connection, $search);
|
||||
|
||||
|
||||
if ($entries['count']) {
|
||||
return 1;
|
||||
}
|
||||
@ -124,18 +124,17 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public function getUserlevel($username)
|
||||
{
|
||||
$userlevel = 0;
|
||||
if (!Config::get('auth_ad_require_groupmembership', true)) {
|
||||
if (! Config::get('auth_ad_require_groupmembership', true)) {
|
||||
if (Config::get('auth_ad_global_read', false)) {
|
||||
$userlevel = 5;
|
||||
}
|
||||
}
|
||||
|
||||
// cycle through defined groups, test for memberOf-ship
|
||||
foreach (Config::get('auth_ad_groups', array()) as $group => $level) {
|
||||
foreach (Config::get('auth_ad_groups', []) as $group => $level) {
|
||||
try {
|
||||
if ($this->userInGroup($username, $group)) {
|
||||
$userlevel = max($userlevel, $level['level']);
|
||||
@ -147,12 +146,11 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
return $userlevel;
|
||||
}
|
||||
|
||||
|
||||
public function getUserid($username)
|
||||
{
|
||||
$connection = $this->getConnection();
|
||||
|
||||
$attributes = array('objectsid');
|
||||
$attributes = ['objectsid'];
|
||||
$search = ldap_search(
|
||||
$connection,
|
||||
Config::get('auth_ad_base_dn'),
|
||||
@ -168,7 +166,6 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bind to AD with the bind user if available, otherwise anonymous bind
|
||||
*/
|
||||
@ -189,14 +186,14 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
return;
|
||||
}
|
||||
|
||||
if (!function_exists('ldap_connect')) {
|
||||
if (! function_exists('ldap_connect')) {
|
||||
throw new LdapMissingException();
|
||||
}
|
||||
|
||||
if (Config::has('auth_ad_check_certificates') &&
|
||||
!Config::get('auth_ad_check_certificates')) {
|
||||
! Config::get('auth_ad_check_certificates')) {
|
||||
putenv('LDAPTLS_REQCERT=never');
|
||||
};
|
||||
}
|
||||
|
||||
if (Config::has('auth_ad_check_certificates') && Config::get('auth_ad_debug')) {
|
||||
ldap_set_option(null, LDAP_OPT_DEBUG_LEVEL, 7);
|
||||
@ -211,7 +208,7 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
|
||||
public function bind($credentials = [])
|
||||
{
|
||||
if (!$this->ldap_connection) {
|
||||
if (! $this->ldap_connection) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
@ -240,6 +237,7 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
protected function getConnection()
|
||||
{
|
||||
$this->init(); // make sure connected and bound
|
||||
|
||||
return $this->ldap_connection;
|
||||
}
|
||||
}
|
||||
|
@ -48,13 +48,15 @@ trait ActiveDirectoryCommon
|
||||
}
|
||||
$revLevel = hexdec(substr($sidHex, 0, 2));
|
||||
$authIdent = hexdec(substr($sidHex, 4, 12));
|
||||
return 'S-'.$revLevel.'-'.$authIdent.'-'.implode('-', $subAuths);
|
||||
|
||||
return 'S-' . $revLevel . '-' . $authIdent . '-' . implode('-', $subAuths);
|
||||
}
|
||||
|
||||
protected function getCn($dn)
|
||||
{
|
||||
$dn = str_replace('\\,', '~C0mmA~', $dn);
|
||||
preg_match('/[^,]*/', $dn, $matches, PREG_OFFSET_CAPTURE, 3);
|
||||
|
||||
return str_replace('~C0mmA~', ',', $matches[0][0]);
|
||||
}
|
||||
|
||||
@ -124,7 +126,7 @@ trait ActiveDirectoryCommon
|
||||
|
||||
public function getGroupList()
|
||||
{
|
||||
$ldap_groups = array();
|
||||
$ldap_groups = [];
|
||||
|
||||
// show all Active Directory Users by default
|
||||
$default_group = 'Users';
|
||||
@ -135,7 +137,7 @@ trait ActiveDirectoryCommon
|
||||
}
|
||||
}
|
||||
|
||||
if (!Config::has('auth_ad_groups') && !Config::has('auth_ad_group')) {
|
||||
if (! Config::has('auth_ad_groups') && ! Config::has('auth_ad_group')) {
|
||||
$ldap_groups[] = $this->getDn($default_group);
|
||||
}
|
||||
|
||||
@ -150,15 +152,15 @@ trait ActiveDirectoryCommon
|
||||
{
|
||||
$connection = $this->getConnection();
|
||||
|
||||
$userlist = array();
|
||||
$userlist = [];
|
||||
$ldap_groups = $this->getGroupList();
|
||||
|
||||
foreach ($ldap_groups as $ldap_group) {
|
||||
$search_filter = "(&(memberOf:1.2.840.113556.1.4.1941:=$ldap_group)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))";
|
||||
if (Config::get('auth_ad_user_filter')) {
|
||||
$search_filter = "(&" . Config::get('auth_ad_user_filter') . $search_filter .")";
|
||||
$search_filter = "(&" . Config::get('auth_ad_user_filter') . $search_filter . ")";
|
||||
}
|
||||
$attributes = array('samaccountname', 'displayname', 'objectsid', 'mail');
|
||||
$attributes = ['samaccountname', 'displayname', 'objectsid', 'mail'];
|
||||
$search = ldap_search($connection, Config::get('auth_ad_base_dn'), $search_filter, $attributes);
|
||||
$results = ldap_get_entries($connection, $search);
|
||||
|
||||
@ -182,7 +184,7 @@ trait ActiveDirectoryCommon
|
||||
*/
|
||||
protected function userFromAd($entry)
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
'user_id' => $this->getUseridFromSid($this->sidFromLdap($entry['objectsid'][0])),
|
||||
'username' => $entry['samaccountname'][0],
|
||||
'realname' => $entry['displayname'][0],
|
||||
@ -190,7 +192,7 @@ trait ActiveDirectoryCommon
|
||||
'descr' => '',
|
||||
'level' => $this->getUserlevel($entry['samaccountname'][0]),
|
||||
'can_modify_passwd' => 0,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
public function getUser($user_id)
|
||||
@ -199,7 +201,7 @@ trait ActiveDirectoryCommon
|
||||
$domain_sid = $this->getDomainSid();
|
||||
|
||||
$search_filter = "(&(objectcategory=person)(objectclass=user)(objectsid=$domain_sid-$user_id))";
|
||||
$attributes = array('samaccountname', 'displayname', 'objectsid', 'mail');
|
||||
$attributes = ['samaccountname', 'displayname', 'objectsid', 'mail'];
|
||||
$search = ldap_search($connection, Config::get('auth_ad_base_dn'), $search_filter, $attributes);
|
||||
$entry = ldap_get_entries($connection, $search);
|
||||
|
||||
@ -207,7 +209,7 @@ trait ActiveDirectoryCommon
|
||||
return $this->userFromAd($entry[0]);
|
||||
}
|
||||
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function getDomainSid()
|
||||
@ -221,9 +223,10 @@ trait ActiveDirectoryCommon
|
||||
$connection,
|
||||
$dn_candidate,
|
||||
'(objectClass=*)',
|
||||
array('objectsid')
|
||||
['objectsid']
|
||||
);
|
||||
$entry = ldap_get_entries($connection, $search);
|
||||
|
||||
return substr($this->sidFromLdap($entry[0]['objectsid'][0]), 0, 41);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
* @copyright 2017 Tony Murray
|
||||
* @author Tony Murray <murraytony@gmail.com>
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Authentication;
|
||||
|
||||
use LibreNMS\Interfaces\Authentication\Authorizer;
|
||||
|
@ -34,7 +34,6 @@ class HttpAuthAuthorizer extends MysqlAuthorizer
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function getUserlevel($username)
|
||||
{
|
||||
$user_level = parent::getUserlevel($username);
|
||||
@ -50,7 +49,6 @@ class HttpAuthAuthorizer extends MysqlAuthorizer
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public function getUserid($username)
|
||||
{
|
||||
$user_id = parent::getUserid($username);
|
||||
|
@ -53,7 +53,7 @@ class LdapAuthorizationAuthorizer extends AuthorizerBase
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (!function_exists('ldap_connect')) {
|
||||
if (! function_exists('ldap_connect')) {
|
||||
throw new LdapMissingException();
|
||||
}
|
||||
|
||||
@ -105,6 +105,7 @@ class LdapAuthorizationAuthorizer extends AuthorizerBase
|
||||
* want to speed up.
|
||||
*/
|
||||
$this->authLdapSessionCacheSet('user_exists', 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -116,7 +117,6 @@ class LdapAuthorizationAuthorizer extends AuthorizerBase
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public function getUserlevel($username)
|
||||
{
|
||||
$userlevel = $this->authLdapSessionCacheGet('userlevel');
|
||||
@ -127,7 +127,7 @@ class LdapAuthorizationAuthorizer extends AuthorizerBase
|
||||
}
|
||||
|
||||
// Find all defined groups $username is in
|
||||
$filter = '(&(|(cn=' . join(')(cn=', array_keys(Config::get('auth_ldap_groups'))) . '))(' . Config::get('auth_ldap_groupmemberattr') .'=' . $this->getMembername($username) . '))';
|
||||
$filter = '(&(|(cn=' . join(')(cn=', array_keys(Config::get('auth_ldap_groups'))) . '))(' . Config::get('auth_ldap_groupmemberattr') . '=' . $this->getMembername($username) . '))';
|
||||
$search = ldap_search($this->ldap_connection, Config::get('auth_ldap_groupbase'), $filter);
|
||||
$entries = ldap_get_entries($this->ldap_connection, $search);
|
||||
|
||||
@ -141,11 +141,10 @@ class LdapAuthorizationAuthorizer extends AuthorizerBase
|
||||
}
|
||||
|
||||
$this->authLdapSessionCacheSet('userlevel', $userlevel);
|
||||
|
||||
return $userlevel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getUserid($username)
|
||||
{
|
||||
$user_id = $this->authLdapSessionCacheGet('userid');
|
||||
@ -161,7 +160,7 @@ class LdapAuthorizationAuthorizer extends AuthorizerBase
|
||||
$entries = ldap_get_entries($this->ldap_connection, $search);
|
||||
|
||||
if ($entries['count']) {
|
||||
$user_id = (int)$entries[0]['uidnumber'][0];
|
||||
$user_id = (int) $entries[0]['uidnumber'][0];
|
||||
}
|
||||
|
||||
if ($user_id === -1) {
|
||||
@ -174,13 +173,13 @@ class LdapAuthorizationAuthorizer extends AuthorizerBase
|
||||
}
|
||||
|
||||
$this->authLdapSessionCacheSet('userid', $user_id);
|
||||
|
||||
return $user_id;
|
||||
}
|
||||
|
||||
|
||||
public function getUserlist()
|
||||
{
|
||||
$userlist = array ();
|
||||
$userlist = [];
|
||||
|
||||
$filter = '(' . Config::get('auth_ldap_prefix') . '*)';
|
||||
|
||||
@ -202,12 +201,12 @@ class LdapAuthorizationAuthorizer extends AuthorizerBase
|
||||
$this->getMembername($username)
|
||||
);
|
||||
if (! Config::has('auth_ldap_group') || $ldap_comparison === true) {
|
||||
$userlist[] = array(
|
||||
$userlist[] = [
|
||||
'username' => $username,
|
||||
'realname' => $realname,
|
||||
'user_id' => $user_id,
|
||||
'email' => $email,
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -216,19 +215,19 @@ class LdapAuthorizationAuthorizer extends AuthorizerBase
|
||||
return $userlist;
|
||||
}
|
||||
|
||||
|
||||
public function getUser($user_id)
|
||||
{
|
||||
foreach ($this->getUserlist() as $user) {
|
||||
if ((int)$user['user_id'] === (int)$user_id) {
|
||||
if ((int) $user['user_id'] === (int) $user_id) {
|
||||
$user['level'] = $this->getUserlevel($user['username']);
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
protected function getMembername($username)
|
||||
{
|
||||
if (Config::get('auth_ldap_groupmembertype') == 'fulldn') {
|
||||
@ -247,7 +246,7 @@ class LdapAuthorizationAuthorizer extends AuthorizerBase
|
||||
|
||||
public function getGroupList()
|
||||
{
|
||||
$ldap_groups = array();
|
||||
$ldap_groups = [];
|
||||
$default_group = 'cn=groupname,ou=groups,dc=example,dc=com';
|
||||
if (Config::has('auth_ldap_group')) {
|
||||
if (Config::get('auth_ldap_group') !== $default_group) {
|
||||
@ -256,7 +255,7 @@ class LdapAuthorizationAuthorizer extends AuthorizerBase
|
||||
}
|
||||
|
||||
foreach (Config::get('auth_ldap_groups') as $key => $value) {
|
||||
$dn = "cn=$key,".Config::get('auth_ldap_groupbase');
|
||||
$dn = "cn=$key," . Config::get('auth_ldap_groupbase');
|
||||
$ldap_groups[] = $dn;
|
||||
}
|
||||
|
||||
|
@ -15,14 +15,14 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
{
|
||||
$connection = $this->getLdapConnection(true);
|
||||
|
||||
if (!empty($credentials['username'])) {
|
||||
if (! empty($credentials['username'])) {
|
||||
$username = $credentials['username'];
|
||||
$this->userloginname = $username;
|
||||
if (Config::get('auth_ldap_wildcard_ou', false)) {
|
||||
$this->setAuthLdapSuffixOu($username);
|
||||
}
|
||||
|
||||
if (!empty($credentials['password']) && ldap_bind($connection, $this->getFullDn($username), $credentials['password'])) {
|
||||
if (! empty($credentials['password']) && ldap_bind($connection, $this->getFullDn($username), $credentials['password'])) {
|
||||
// ldap_bind has done a bind with the user credentials. If binduser is configured, rebind with the auth_ldap_binduser
|
||||
// normal user has restricted right to search in ldap. auth_ldap_binduser has full search rights
|
||||
if ((Config::has('auth_ldap_binduser') || Config::has('auth_ldap_binddn')) && Config::has('auth_ldap_bindpassword')) {
|
||||
@ -88,7 +88,6 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public function getUserlevel($username)
|
||||
{
|
||||
$userlevel = 0;
|
||||
@ -128,7 +127,6 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
return $userlevel;
|
||||
}
|
||||
|
||||
|
||||
public function getUserid($username)
|
||||
{
|
||||
try {
|
||||
@ -140,6 +138,7 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
|
||||
if ($entries['count']) {
|
||||
$uid_attr = strtolower(Config::get('auth_ldap_uid_attribute', 'uidnumber'));
|
||||
|
||||
return $entries[0][$uid_attr][0];
|
||||
}
|
||||
} catch (AuthenticationException $e) {
|
||||
@ -159,6 +158,7 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
$ldap_groups = $this->getGroupList();
|
||||
if (empty($ldap_groups)) {
|
||||
d_echo('No groups defined. Cannot search for users.');
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
@ -220,12 +220,13 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
$entries = ldap_get_entries($connection, $search);
|
||||
foreach ($entries as $entry) {
|
||||
$user = $this->ldapToUser($entry);
|
||||
if ((int)$user['user_id'] !== (int)$user_id) {
|
||||
if ((int) $user['user_id'] !== (int) $user_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -243,6 +244,7 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
$filter = '(' . Config::get('auth_ldap_attr.uid') . '=' . $username . ')';
|
||||
$search = ldap_search($connection, Config::get('auth_ldap_groupbase'), $filter);
|
||||
$entries = ldap_get_entries($connection, $search);
|
||||
|
||||
return $entries[0]['dn'];
|
||||
} catch (AuthenticationException $e) {
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
@ -252,10 +254,9 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
return $username;
|
||||
}
|
||||
|
||||
|
||||
public function getGroupList()
|
||||
{
|
||||
$ldap_groups = array();
|
||||
$ldap_groups = [];
|
||||
|
||||
$default_group = 'cn=groupname,ou=groups,dc=example,dc=com'; // in the documentation
|
||||
if (Config::get('auth_ldap_group', $default_group) !== $default_group) {
|
||||
@ -263,7 +264,7 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
}
|
||||
|
||||
foreach (Config::get('auth_ldap_groups') as $key => $value) {
|
||||
$ldap_groups[] = "cn=$key,".Config::get('auth_ldap_groupbase');
|
||||
$ldap_groups[] = "cn=$key," . Config::get('auth_ldap_groupbase');
|
||||
}
|
||||
|
||||
return $ldap_groups;
|
||||
@ -300,9 +301,11 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
$user_ou = $matches[1];
|
||||
$new_auth_ldap_suffix = preg_replace("/,ou=[^,]+,/", ",ou=" . $user_ou . ",", Config::get('auth_ldap_suffix'));
|
||||
Config::set('auth_ldap_suffix', $new_auth_ldap_suffix);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -316,7 +319,6 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
*/
|
||||
protected function getLdapConnection($skip_bind = false)
|
||||
{
|
||||
|
||||
if ($this->ldap_connection) {
|
||||
return $this->ldap_connection; // bind already attempted
|
||||
}
|
||||
@ -337,10 +339,11 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
private function ldapToUser($entry)
|
||||
{
|
||||
$uid_attr = strtolower(Config::get('auth_ldap_uid_attribute', 'uidnumber'));
|
||||
|
||||
return [
|
||||
'username' => $entry['uid'][0],
|
||||
'realname' => $entry['cn'][0],
|
||||
'user_id' => (int)$entry[$uid_attr][0],
|
||||
'user_id' => (int) $entry[$uid_attr][0],
|
||||
'email' => $entry[Config::get('auth_ldap_emailattr', 'mail')][0],
|
||||
'level' => $this->getUserlevel($entry['uid'][0]),
|
||||
];
|
||||
@ -352,20 +355,20 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
return;
|
||||
}
|
||||
|
||||
if (!function_exists('ldap_connect')) {
|
||||
if (! function_exists('ldap_connect')) {
|
||||
throw new LdapMissingException();
|
||||
}
|
||||
|
||||
$this->ldap_connection = @ldap_connect(Config::get('auth_ldap_server'), Config::get('auth_ldap_port', 389));
|
||||
|
||||
if (!$this->ldap_connection) {
|
||||
if (! $this->ldap_connection) {
|
||||
throw new AuthenticationException('Unable to connect to ldap server');
|
||||
}
|
||||
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_PROTOCOL_VERSION, Config::get('auth_ldap_version', 3));
|
||||
|
||||
$use_tls = Config::get('auth_ldap_starttls');
|
||||
if ($use_tls == 'optional'||$use_tls == 'require') {
|
||||
if ($use_tls == 'optional' || $use_tls == 'require') {
|
||||
$tls_success = ldap_start_tls($this->ldap_connection);
|
||||
if ($use_tls == 'require' && $tls_success === false) {
|
||||
$error = ldap_error($this->ldap_connection);
|
||||
@ -391,7 +394,7 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
}
|
||||
$username = Config::get('auth_ldap_binddn');
|
||||
$password = Config::get('auth_ldap_bindpassword');
|
||||
} elseif (!empty($credentials['username'])) {
|
||||
} elseif (! empty($credentials['username'])) {
|
||||
$username = $this->getFullDn($credentials['username']);
|
||||
}
|
||||
|
||||
|
@ -36,12 +36,12 @@ trait LdapSessionCache
|
||||
$ttl = Config::get('auth_ldap_cache_ttl', 300);
|
||||
|
||||
// no session, don't cache
|
||||
if (!class_exists('Session')) {
|
||||
if (! class_exists('Session')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// auth_ldap cache present in this session?
|
||||
if (!Session::has('auth_ldap')) {
|
||||
if (! Session::has('auth_ldap')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -60,7 +60,6 @@ trait LdapSessionCache
|
||||
return $cache[$attr]['value'];
|
||||
}
|
||||
|
||||
|
||||
protected function authLdapSessionCacheSet($attr, $value)
|
||||
{
|
||||
if (class_exists('Session')) {
|
||||
|
@ -9,7 +9,7 @@ use LibreNMS\Interfaces\Authentication\Authorizer;
|
||||
class LegacyAuth
|
||||
{
|
||||
protected static $_instance;
|
||||
private static $configToClassMap = array(
|
||||
private static $configToClassMap = [
|
||||
'mysql' => 'LibreNMS\Authentication\MysqlAuthorizer',
|
||||
'active_directory' => 'LibreNMS\Authentication\ActiveDirectoryAuthorizer',
|
||||
'ldap' => 'LibreNMS\Authentication\LdapAuthorizer',
|
||||
@ -18,7 +18,7 @@ class LegacyAuth
|
||||
'ad-authorization' => 'LibreNMS\Authentication\ADAuthorizationAuthorizer',
|
||||
'ldap-authorization' => 'LibreNMS\Authentication\LdapAuthorizationAuthorizer',
|
||||
'sso' => 'LibreNMS\Authentication\SSOAuthorizer',
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* Gets the authorizer based on the config
|
||||
@ -27,10 +27,11 @@ class LegacyAuth
|
||||
*/
|
||||
public static function get()
|
||||
{
|
||||
if (!static::$_instance) {
|
||||
if (! static::$_instance) {
|
||||
$class = self::getClass();
|
||||
static::$_instance = new $class;
|
||||
}
|
||||
|
||||
return static::$_instance;
|
||||
}
|
||||
|
||||
@ -56,7 +57,7 @@ class LegacyAuth
|
||||
$type = self::getType();
|
||||
}
|
||||
|
||||
if (!isset(self::$configToClassMap[$type])) {
|
||||
if (! isset(self::$configToClassMap[$type])) {
|
||||
throw new \RuntimeException($type . ' not found as auth_mechanism');
|
||||
}
|
||||
|
||||
@ -71,6 +72,7 @@ class LegacyAuth
|
||||
public static function reset()
|
||||
{
|
||||
static::$_instance = null;
|
||||
|
||||
return static::get();
|
||||
}
|
||||
}
|
||||
|
@ -32,12 +32,14 @@ class MysqlAuthorizer extends AuthorizerBase
|
||||
// md5
|
||||
if (md5($password) === $hash) {
|
||||
$this->changePassword($username, $password);
|
||||
|
||||
return true;
|
||||
}
|
||||
} elseif (Str::startsWith($hash, '$1$')) {
|
||||
// old md5 crypt
|
||||
if (crypt($password, $hash) == $hash) {
|
||||
$this->changePassword($username, $password);
|
||||
|
||||
return true;
|
||||
}
|
||||
} elseif (Str::startsWith($hash, '$P$')) {
|
||||
@ -45,6 +47,7 @@ class MysqlAuthorizer extends AuthorizerBase
|
||||
$hasher = new PasswordHash();
|
||||
if ($hasher->CheckPassword($password, $hash)) {
|
||||
$this->changePassword($username, $password);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -63,9 +66,9 @@ class MysqlAuthorizer extends AuthorizerBase
|
||||
* user is explicitly prohibited to do so.
|
||||
*/
|
||||
|
||||
if (!static::$CAN_UPDATE_PASSWORDS) {
|
||||
if (! static::$CAN_UPDATE_PASSWORDS) {
|
||||
return 0;
|
||||
} elseif (empty($username) || !$this->userExists($username)) {
|
||||
} elseif (empty($username) || ! $this->userExists($username)) {
|
||||
return 1;
|
||||
} else {
|
||||
return User::thisAuth()->where('username', $username)->value('can_modify_passwd');
|
||||
@ -75,7 +78,7 @@ class MysqlAuthorizer extends AuthorizerBase
|
||||
public function changePassword($username, $password)
|
||||
{
|
||||
// check if updating passwords is allowed (mostly for classes that extend this)
|
||||
if (!static::$CAN_UPDATE_PASSWORDS) {
|
||||
if (! static::$CAN_UPDATE_PASSWORDS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -84,6 +87,7 @@ class MysqlAuthorizer extends AuthorizerBase
|
||||
|
||||
if ($user) {
|
||||
$user->setPassword($password);
|
||||
|
||||
return $user->save();
|
||||
}
|
||||
|
||||
@ -96,16 +100,16 @@ class MysqlAuthorizer extends AuthorizerBase
|
||||
|
||||
// no nulls
|
||||
$user_array = array_filter($user_array, function ($field) {
|
||||
return !is_null($field);
|
||||
return ! is_null($field);
|
||||
});
|
||||
|
||||
$new_user = User::thisAuth()->firstOrNew(['username' => $username], $user_array);
|
||||
|
||||
// only update new users
|
||||
if (!$new_user->user_id) {
|
||||
if (! $new_user->user_id) {
|
||||
$new_user->auth_type = LegacyAuth::getType();
|
||||
$new_user->setPassword($password);
|
||||
$new_user->email = (string)$new_user->email;
|
||||
$new_user->email = (string) $new_user->email;
|
||||
|
||||
$new_user->save();
|
||||
$user_id = $new_user->user_id;
|
||||
@ -161,6 +165,7 @@ class MysqlAuthorizer extends AuthorizerBase
|
||||
if ($user) {
|
||||
return $user->toArray();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -169,8 +174,8 @@ class MysqlAuthorizer extends AuthorizerBase
|
||||
$user = User::find($user_id);
|
||||
|
||||
$user->realname = $realname;
|
||||
$user->level = (int)$level;
|
||||
$user->can_modify_passwd = (int)$can_modify_passwd;
|
||||
$user->level = (int) $level;
|
||||
$user->can_modify_passwd = (int) $can_modify_passwd;
|
||||
$user->email = $email;
|
||||
|
||||
$user->save();
|
||||
|
@ -12,7 +12,7 @@ class RadiusAuthorizer extends MysqlAuthorizer
|
||||
protected static $CAN_UPDATE_USER = 1;
|
||||
protected static $CAN_UPDATE_PASSWORDS = 0;
|
||||
|
||||
/** @var Radius $radius */
|
||||
/** @var Radius */
|
||||
protected $radius;
|
||||
|
||||
public function __construct()
|
||||
@ -35,6 +35,7 @@ class RadiusAuthorizer extends MysqlAuthorizer
|
||||
$password = $credentials['password'] ?? null;
|
||||
if ($this->radius->accessRequest($credentials['username'], $password) === true) {
|
||||
$this->addUser($credentials['username'], $password, Config::get('radius.default_level', 1));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -33,9 +33,7 @@ use LibreNMS\Util\IP;
|
||||
|
||||
/**
|
||||
* Some functionality in this mechanism is inspired by confluence_http_authenticator (@chauth) and graylog-plugin-auth-sso (@Graylog)
|
||||
*
|
||||
*/
|
||||
|
||||
class SSOAuthorizer extends MysqlAuthorizer
|
||||
{
|
||||
protected static $HAS_AUTH_USERMANAGEMENT = 1;
|
||||
@ -58,7 +56,7 @@ class SSOAuthorizer extends MysqlAuthorizer
|
||||
$level = $this->authSSOCalculateLevel();
|
||||
|
||||
// User has already been approved by the authenicator so if automatic user create/update is enabled, do it
|
||||
if (Config::get('sso.create_users') && !$this->userExists($credentials['username'])) {
|
||||
if (Config::get('sso.create_users') && ! $this->userExists($credentials['username'])) {
|
||||
$this->addUser($credentials['username'], null, $level, $email, $realname, $can_modify_passwd, $description ? $description : 'SSO User');
|
||||
} elseif (Config::get('sso.update_users') && $this->userExists($credentials['username'])) {
|
||||
$this->updateUser($this->getUserid($credentials['username']), $realname, $level, $can_modify_passwd, $email);
|
||||
@ -151,7 +149,7 @@ class SSOAuthorizer extends MysqlAuthorizer
|
||||
* Calculate the privilege level to assign to a user based on the configuration and attributes supplied by the external authenticator.
|
||||
* Returns an integer if the permission is found, or raises an AuthenticationException if the configuration is not valid.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function authSSOCalculateLevel()
|
||||
{
|
||||
@ -185,14 +183,14 @@ class SSOAuthorizer extends MysqlAuthorizer
|
||||
/**
|
||||
* Map a user to a permission level based on a table mapping, 0 if no matching group is found.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function authSSOParseGroups()
|
||||
{
|
||||
// Parse a delimited group list
|
||||
$groups = explode(Config::get('sso.group_delimiter', ';'), $this->authSSOGetAttr(Config::get('sso.group_attr')));
|
||||
|
||||
$valid_groups = array();
|
||||
$valid_groups = [];
|
||||
|
||||
// Only consider groups that match the filter expression - this is an optimisation for sites with thousands of groups
|
||||
if (Config::get('sso.group_filter')) {
|
||||
|
@ -87,7 +87,7 @@ class TwoFactor
|
||||
"4" => 28,
|
||||
"5" => 29,
|
||||
"6" => 30,
|
||||
"7" => 31
|
||||
"7" => 31,
|
||||
];
|
||||
|
||||
/**
|
||||
@ -121,6 +121,7 @@ class TwoFactor
|
||||
while (++$x < sizeof($bin)) {
|
||||
$ret .= self::$base32_enc[base_convert(str_pad($bin[$x], 5, '0'), 2, 10)];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
@ -129,8 +130,8 @@ class TwoFactor
|
||||
*
|
||||
* @param string $key Secret Key
|
||||
* @param int $otp OTP supplied by user
|
||||
* @param int|boolean $counter Counter, if false timestamp is used
|
||||
* @return boolean|int
|
||||
* @param int|bool $counter Counter, if false timestamp is used
|
||||
* @return bool|int
|
||||
*/
|
||||
public static function verifyHOTP($key, $otp, $counter = false)
|
||||
{
|
||||
@ -151,7 +152,7 @@ class TwoFactor
|
||||
}
|
||||
while (++$initcount <= $endcount) {
|
||||
if (self::oathHOTP($key, $initcount) == $otp) {
|
||||
if (!$totp) {
|
||||
if (! $totp) {
|
||||
return $initcount;
|
||||
} else {
|
||||
return true;
|
||||
@ -159,13 +160,14 @@ class TwoFactor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate HOTP (RFC 4226)
|
||||
* @param string $key Secret Key
|
||||
* @param int|boolean $counter Optional Counter, Defaults to Timestamp
|
||||
* @param int|bool $counter Optional Counter, Defaults to Timestamp
|
||||
* @return int
|
||||
*/
|
||||
private static function oathHOTP($key, $counter = false)
|
||||
@ -193,6 +195,7 @@ class TwoFactor
|
||||
((ord($hash[$offset + 1]) & 0xff) << 16) |
|
||||
((ord($hash[$offset + 2]) & 0xff) << 8) |
|
||||
(ord($hash[$offset + 3]) & 0xff)) % pow(10, self::OTP_SIZE);
|
||||
|
||||
return str_pad($truncated, self::OTP_SIZE, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ class Device
|
||||
*
|
||||
* @return \App\Models\Device
|
||||
*/
|
||||
public function getPrimary() : \App\Models\Device
|
||||
public function getPrimary(): \App\Models\Device
|
||||
{
|
||||
return $this->get($this->primary);
|
||||
}
|
||||
@ -57,9 +57,9 @@ class Device
|
||||
* @param int $device_id
|
||||
* @return \App\Models\Device
|
||||
*/
|
||||
public function get(?int $device_id) : \App\Models\Device
|
||||
public function get(?int $device_id): \App\Models\Device
|
||||
{
|
||||
if (!is_null($device_id) && !array_key_exists($device_id, $this->devices)) {
|
||||
if (! is_null($device_id) && ! array_key_exists($device_id, $this->devices)) {
|
||||
return $this->load($device_id);
|
||||
}
|
||||
|
||||
@ -72,11 +72,11 @@ class Device
|
||||
* @param string $hostname
|
||||
* @return \App\Models\Device
|
||||
*/
|
||||
public function getByHostname($hostname) : \App\Models\Device
|
||||
public function getByHostname($hostname): \App\Models\Device
|
||||
{
|
||||
$device_id = collect($this->devices)->pluck('device_id', 'hostname')->get($hostname);
|
||||
|
||||
if (!$device_id) {
|
||||
if (! $device_id) {
|
||||
return $this->load($hostname, 'hostname');
|
||||
}
|
||||
|
||||
@ -89,9 +89,10 @@ class Device
|
||||
* @param int $device_id
|
||||
* @return \App\Models\Device
|
||||
*/
|
||||
public function refresh(?int $device_id) : \App\Models\Device
|
||||
public function refresh(?int $device_id): \App\Models\Device
|
||||
{
|
||||
unset($this->devices[$device_id]);
|
||||
|
||||
return $this->get($device_id);
|
||||
}
|
||||
|
||||
@ -107,11 +108,12 @@ class Device
|
||||
{
|
||||
$device = \App\Models\Device::query()->where($field, $value)->first();
|
||||
|
||||
if (!$device) {
|
||||
if (! $device) {
|
||||
return new \App\Models\Device;
|
||||
}
|
||||
|
||||
$this->devices[$device->device_id] = $device;
|
||||
|
||||
return $device;
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ class Component
|
||||
$row = dbFetchRow($SQL, [$TYPE]);
|
||||
}
|
||||
|
||||
if (!isset($row)) {
|
||||
if (! isset($row)) {
|
||||
// We didn't find any component types
|
||||
return false;
|
||||
} else {
|
||||
@ -80,7 +80,7 @@ class Component
|
||||
->with('prefs');
|
||||
|
||||
// Device_id is shorthand for filter C.device_id = $device_id.
|
||||
if (!is_null($device_id)) {
|
||||
if (! is_null($device_id)) {
|
||||
$options['filter']['device_id'] = ['=', $device_id];
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ class Component
|
||||
$sql_param = [];
|
||||
$add = 0;
|
||||
|
||||
if (!is_null($device)) {
|
||||
if (! is_null($device)) {
|
||||
// Add a device filter to the SQL query.
|
||||
$sql_query .= " `device_id` = ?";
|
||||
$sql_param[] = $device;
|
||||
@ -151,6 +151,7 @@ class Component
|
||||
}
|
||||
|
||||
d_echo("Component Count by Status: " . print_r($count, true) . "\n");
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
@ -159,6 +160,7 @@ class Component
|
||||
if (($component_id == null) || ($start == null) || ($end == null)) {
|
||||
// Error...
|
||||
d_echo("Required arguments are missing. Component ID: " . $component_id . ", Start: " . $start . ", End: " . $end . "\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -181,6 +183,7 @@ class Component
|
||||
$return['data'] = dbFetchRows($sql_query, $sql_param);
|
||||
|
||||
d_echo("Status Log Data: " . print_r($return, true) . "\n");
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
@ -243,7 +246,7 @@ class Component
|
||||
|
||||
// update preferences
|
||||
$prefs = collect($updated[$component->id])->filter(function ($value, $attr) {
|
||||
return !array_key_exists($attr, $this->reserved);
|
||||
return ! array_key_exists($attr, $this->reserved);
|
||||
});
|
||||
|
||||
$invalid = $component->prefs->keyBy('id');
|
||||
@ -282,13 +285,14 @@ class Component
|
||||
*/
|
||||
public function getFirstComponentID($component_array, $device_id = null)
|
||||
{
|
||||
if (!is_null($device_id) && isset($component_array[$device_id])) {
|
||||
if (! is_null($device_id) && isset($component_array[$device_id])) {
|
||||
$component_array = $component_array[$device_id];
|
||||
}
|
||||
|
||||
foreach ($component_array as $id => $array) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ class ComposerHelper
|
||||
{
|
||||
public static function postRootPackageInstall(Event $event)
|
||||
{
|
||||
if (!file_exists('.env')) {
|
||||
if (! file_exists('.env')) {
|
||||
self::setPermissions();
|
||||
self::populateEnv();
|
||||
}
|
||||
@ -41,7 +41,7 @@ class ComposerHelper
|
||||
|
||||
public static function postInstall(Event $event)
|
||||
{
|
||||
if (!file_exists('.env')) {
|
||||
if (! file_exists('.env')) {
|
||||
self::setPermissions();
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ class ComposerHelper
|
||||
|
||||
public static function preUpdate(Event $event)
|
||||
{
|
||||
if (!getenv('FORCE')) {
|
||||
if (! getenv('FORCE')) {
|
||||
echo "Running composer update is not advisable. Please run composer install to update instead.\n";
|
||||
echo "If know what you are doing and want to write a new composer.lock file set FORCE=1.\n";
|
||||
echo "If you don't know what to do, run: composer install\n";
|
||||
@ -62,18 +62,17 @@ class ComposerHelper
|
||||
{
|
||||
$vendor_dir = $event->getComposer()->getConfig()->get('vendor-dir');
|
||||
|
||||
if (!is_file("$vendor_dir/autoload.php")) {
|
||||
if (! is_file("$vendor_dir/autoload.php")) {
|
||||
// checkout vendor from 1.36
|
||||
$cmds = [
|
||||
"git checkout 609676a9f8d72da081c61f82967e1d16defc0c4e -- $vendor_dir",
|
||||
"git reset HEAD $vendor_dir" // don't add vendor directory to the index
|
||||
"git reset HEAD $vendor_dir", // don't add vendor directory to the index
|
||||
];
|
||||
|
||||
self::exec($cmds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initially populate .env file
|
||||
*/
|
||||
@ -129,7 +128,7 @@ class ComposerHelper
|
||||
*/
|
||||
private static function exec($cmds)
|
||||
{
|
||||
$cmd = "set -v\n" . implode(PHP_EOL, (array)$cmds);
|
||||
$cmd = "set -v\n" . implode(PHP_EOL, (array) $cmds);
|
||||
passthru($cmd);
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ class Config
|
||||
public static function load()
|
||||
{
|
||||
// don't reload the config if it is already loaded, reload() should be used for that
|
||||
if (!is_null(self::$config)) {
|
||||
if (! is_null(self::$config)) {
|
||||
return self::$config;
|
||||
}
|
||||
|
||||
@ -71,6 +71,7 @@ class Config
|
||||
public static function reload()
|
||||
{
|
||||
self::$config = null;
|
||||
|
||||
return self::load();
|
||||
}
|
||||
|
||||
@ -112,7 +113,6 @@ class Config
|
||||
@include base_path('config.php');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a config value, if non existent null (or default if set) will be returned
|
||||
*
|
||||
@ -126,7 +126,7 @@ class Config
|
||||
return self::$config[$key];
|
||||
}
|
||||
|
||||
if (!Str::contains($key, '.')) {
|
||||
if (! Str::contains($key, '.')) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
@ -204,24 +204,24 @@ class Config
|
||||
* @param array $default optional array to return if the setting is not set
|
||||
* @return array
|
||||
*/
|
||||
public static function getCombined($os, $key, $default = array())
|
||||
public static function getCombined($os, $key, $default = [])
|
||||
{
|
||||
if (!self::has($key)) {
|
||||
if (! self::has($key)) {
|
||||
return self::getOsSetting($os, $key, $default);
|
||||
}
|
||||
|
||||
if (!isset(self::$config['os'][$os][$key])) {
|
||||
if (!Str::contains($key, '.')) {
|
||||
if (! isset(self::$config['os'][$os][$key])) {
|
||||
if (! Str::contains($key, '.')) {
|
||||
return self::get($key, $default);
|
||||
}
|
||||
if (!self::has("os.$os.$key")) {
|
||||
if (! self::has("os.$os.$key")) {
|
||||
return self::get($key, $default);
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique(array_merge(
|
||||
(array)self::get($key, $default),
|
||||
(array)self::getOsSetting($os, $key, $default)
|
||||
(array) self::get($key, $default),
|
||||
(array) self::getOsSetting($os, $key, $default)
|
||||
));
|
||||
}
|
||||
|
||||
@ -254,6 +254,7 @@ class Config
|
||||
|
||||
// delete any children (there should not be any unless it is legacy)
|
||||
\App\Models\Config::query()->where('config_name', 'like', "$key.%")->delete();
|
||||
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
if (class_exists(Log::class)) {
|
||||
@ -263,6 +264,7 @@ class Config
|
||||
if ($debug) {
|
||||
echo $e;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -296,7 +298,7 @@ class Config
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Str::contains($key, '.')) {
|
||||
if (! Str::contains($key, '.')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -328,7 +330,7 @@ class Config
|
||||
*/
|
||||
private static function loadDB()
|
||||
{
|
||||
if (!Eloquent::isConnected()) {
|
||||
if (! Eloquent::isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -389,17 +391,16 @@ class Config
|
||||
|
||||
// graph color copying
|
||||
Arr::set(self::$config, 'graph_colours.mega', array_merge(
|
||||
(array)Arr::get(self::$config, 'graph_colours.psychedelic', []),
|
||||
(array)Arr::get(self::$config, 'graph_colours.manycolours', []),
|
||||
(array)Arr::get(self::$config, 'graph_colours.default', []),
|
||||
(array)Arr::get(self::$config, 'graph_colours.mixed', [])
|
||||
(array) Arr::get(self::$config, 'graph_colours.psychedelic', []),
|
||||
(array) Arr::get(self::$config, 'graph_colours.manycolours', []),
|
||||
(array) Arr::get(self::$config, 'graph_colours.default', []),
|
||||
(array) Arr::get(self::$config, 'graph_colours.mixed', [])
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the config after it has been loaded.
|
||||
* Make sure certain variables have been set properly and
|
||||
*
|
||||
*/
|
||||
private static function processConfig()
|
||||
{
|
||||
@ -410,7 +411,7 @@ class Config
|
||||
|
||||
self::set('base_url', Str::finish(self::get('base_url'), '/'));
|
||||
|
||||
if (!self::get('email_from')) {
|
||||
if (! self::get('email_from')) {
|
||||
self::set('email_from', '"' . self::get('project_name') . '" <' . self::get('email_user') . '@' . php_uname('n') . '>');
|
||||
}
|
||||
|
||||
@ -436,8 +437,8 @@ class Config
|
||||
|
||||
$persist = Eloquent::isConnected();
|
||||
// make sure we have full path to binaries in case PATH isn't set
|
||||
foreach (array('fping', 'fping6', 'snmpgetnext', 'rrdtool', 'traceroute', 'traceroute6') as $bin) {
|
||||
if (!is_executable(self::get($bin))) {
|
||||
foreach (['fping', 'fping6', 'snmpgetnext', 'rrdtool', 'traceroute', 'traceroute6'] as $bin) {
|
||||
if (! is_executable(self::get($bin))) {
|
||||
if ($persist) {
|
||||
self::persist($bin, self::locateBinary($bin));
|
||||
} else {
|
||||
@ -461,7 +462,7 @@ class Config
|
||||
*/
|
||||
private static function setDefault($key, $value, $format_values = [])
|
||||
{
|
||||
if (!self::has($key)) {
|
||||
if (! self::has($key)) {
|
||||
if (is_string($value)) {
|
||||
$format_values = array_map('self::get', $format_values);
|
||||
self::set($key, vsprintf($value, $format_values));
|
||||
@ -496,7 +497,7 @@ class Config
|
||||
*/
|
||||
public static function locateBinary($binary)
|
||||
{
|
||||
if (!Str::contains($binary, '/')) {
|
||||
if (! Str::contains($binary, '/')) {
|
||||
$output = `whereis -b $binary`;
|
||||
$list = trim(substr($output, strpos($output, ':') + 1));
|
||||
$targets = explode(' ', $list);
|
||||
@ -506,6 +507,7 @@ class Config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $binary;
|
||||
}
|
||||
|
||||
|
@ -40,12 +40,12 @@ class Eloquent
|
||||
public static function boot()
|
||||
{
|
||||
// boot Eloquent outside of Laravel
|
||||
if (!Laravel::isBooted() && is_null(self::$capsule)) {
|
||||
if (! Laravel::isBooted() && is_null(self::$capsule)) {
|
||||
$install_dir = realpath(__DIR__ . '/../../');
|
||||
|
||||
Dotenv::create($install_dir)->load();
|
||||
|
||||
$db_config = include($install_dir . '/config/database.php');
|
||||
$db_config = include $install_dir . '/config/database.php';
|
||||
$settings = $db_config['connections'][$db_config['default']];
|
||||
|
||||
self::$capsule = new Capsule;
|
||||
@ -92,7 +92,7 @@ class Eloquent
|
||||
try {
|
||||
$conn = self::DB($name);
|
||||
if ($conn) {
|
||||
return !is_null($conn->getPdo());
|
||||
return ! is_null($conn->getPdo());
|
||||
}
|
||||
} catch (\PDOException $e) {
|
||||
return false;
|
||||
@ -124,6 +124,7 @@ class Eloquent
|
||||
public static function getDriver()
|
||||
{
|
||||
$connection = config('database.default');
|
||||
|
||||
return config("database.connections.{$connection}.driver");
|
||||
}
|
||||
|
||||
@ -141,7 +142,7 @@ class Eloquent
|
||||
"collation" => "utf8_unicode_ci",
|
||||
"prefix" => "",
|
||||
"strict" => true,
|
||||
"engine" => null
|
||||
"engine" => null,
|
||||
]);
|
||||
\Config::set('database.default', $name);
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ namespace LibreNMS\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\Util\Version;
|
||||
use Schema as LaravelSchema;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use \Schema as LaravelSchema;
|
||||
|
||||
class Schema
|
||||
{
|
||||
@ -75,6 +75,7 @@ class Schema
|
||||
->map(function ($migration_file) {
|
||||
return basename($migration_file, '.php');
|
||||
});
|
||||
|
||||
return $migrations;
|
||||
}
|
||||
|
||||
@ -102,7 +103,7 @@ class Schema
|
||||
|
||||
public function getSchema()
|
||||
{
|
||||
if (!isset($this->schema)) {
|
||||
if (! isset($this->schema)) {
|
||||
$file = Config::get('install_dir') . '/misc/db_schema.yaml';
|
||||
$this->schema = Yaml::parse(file_get_contents($file));
|
||||
}
|
||||
@ -129,6 +130,7 @@ class Schema
|
||||
public function getColumns($table)
|
||||
{
|
||||
$schema = $this->getSchema();
|
||||
|
||||
return array_column($schema[$table]['Columns'], 'Field');
|
||||
}
|
||||
|
||||
@ -163,7 +165,7 @@ class Schema
|
||||
|
||||
$cache = [
|
||||
'version' => $db_version,
|
||||
$base => $paths
|
||||
$base => $paths,
|
||||
];
|
||||
|
||||
if (is_writable($cache_file)) {
|
||||
@ -202,7 +204,7 @@ class Schema
|
||||
$relationships = $this->getTableRelationships();
|
||||
|
||||
d_echo("Starting Tables: " . json_encode($tables) . PHP_EOL);
|
||||
if (!empty($history)) {
|
||||
if (! empty($history)) {
|
||||
$tables = array_diff($tables, $history);
|
||||
d_echo("Filtered Tables: " . json_encode($tables) . PHP_EOL);
|
||||
}
|
||||
@ -211,15 +213,17 @@ class Schema
|
||||
// check for direct relationships
|
||||
if (in_array($table, $relationships[$target])) {
|
||||
d_echo("Direct relationship found $target -> $table\n");
|
||||
|
||||
return [$table, $target];
|
||||
}
|
||||
|
||||
$table_relations = $relationships[$table] ?? [];
|
||||
d_echo("Searching $table: " . json_encode($table_relations) . PHP_EOL);
|
||||
|
||||
if (!empty($table_relations)) {
|
||||
if (! empty($table_relations)) {
|
||||
if (in_array($target, $relationships[$table])) {
|
||||
d_echo("Found in $table\n");
|
||||
|
||||
return [$target, $table]; // found it
|
||||
} else {
|
||||
$recurse = $this->findPathRecursive($relationships[$table], $target, array_merge($history, $tables));
|
||||
@ -245,7 +249,7 @@ class Schema
|
||||
|
||||
public function getTableRelationships()
|
||||
{
|
||||
if (!isset($this->relationships)) {
|
||||
if (! isset($this->relationships)) {
|
||||
$schema = $this->getSchema();
|
||||
|
||||
$relations = array_column(array_map(function ($table, $data) {
|
||||
@ -284,7 +288,7 @@ class Schema
|
||||
// try to guess assuming key_id = keys table
|
||||
$guessed_table = substr($key, 0, -3);
|
||||
|
||||
if (!Str::endsWith($guessed_table, 's')) {
|
||||
if (! Str::endsWith($guessed_table, 's')) {
|
||||
if (Str::endsWith($guessed_table, 'x')) {
|
||||
$guessed_table .= 'es';
|
||||
} else {
|
||||
|
@ -56,6 +56,7 @@ class Measurement
|
||||
public function end()
|
||||
{
|
||||
$this->duration = microtime(true) - $this->start;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ class MeasurementCollection extends Collection
|
||||
{
|
||||
$type = $measurement->getType();
|
||||
|
||||
if (!$this->has($type)) {
|
||||
if (! $this->has($type)) {
|
||||
$this->put($type, new MeasurementSummary($type));
|
||||
}
|
||||
|
||||
@ -69,6 +69,7 @@ class MeasurementCollection extends Collection
|
||||
{
|
||||
return $this->reduce(function ($sum, $measurement) use ($function) {
|
||||
$sum += $measurement->$function();
|
||||
|
||||
return $sum;
|
||||
}, 0);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ abstract class BaseDatastore implements DatastoreContract
|
||||
/**
|
||||
* Checks if the datastore wants rrdtags to be sent when issuing put()
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function wantsRrdTags()
|
||||
{
|
||||
|
@ -107,7 +107,7 @@ class Datastore
|
||||
// data_update($device, 'mymeasurement', $tags, 1234);
|
||||
// AND
|
||||
// data_update($device, 'mymeasurement', $tags, array('mymeasurement' => 1234));
|
||||
if (!is_array($fields)) {
|
||||
if (! is_array($fields)) {
|
||||
$fields = [$measurement => $fields];
|
||||
}
|
||||
|
||||
@ -136,6 +136,7 @@ class Datastore
|
||||
}
|
||||
$result[$k] = $v;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -153,6 +154,7 @@ class Datastore
|
||||
{
|
||||
return array_reduce($this->stores, function ($result, DatastoreContract $store) {
|
||||
$result[$store->getName()] = $store->getStats();
|
||||
|
||||
return $result;
|
||||
}, []);
|
||||
}
|
||||
|
@ -84,8 +84,9 @@ class Graphite extends BaseDatastore
|
||||
*/
|
||||
public function put($device, $measurement, $tags, $fields)
|
||||
{
|
||||
if (!$this->connection) {
|
||||
if (! $this->connection) {
|
||||
d_echo("Graphite Error: not connected\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ use Log;
|
||||
|
||||
class InfluxDB extends BaseDatastore
|
||||
{
|
||||
/** @var \InfluxDB\Database $connection */
|
||||
/** @var \InfluxDB\Database */
|
||||
private $connection;
|
||||
|
||||
public function __construct(\InfluxDB\Database $influx)
|
||||
@ -44,7 +44,7 @@ class InfluxDB extends BaseDatastore
|
||||
|
||||
// if the database doesn't exist, create it.
|
||||
try {
|
||||
if (!$influx->exists()) {
|
||||
if (! $influx->exists()) {
|
||||
$influx->create();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
@ -100,6 +100,7 @@ class InfluxDB extends BaseDatastore
|
||||
|
||||
if (empty($tmp_fields)) {
|
||||
Log::warning('All fields empty, skipping update', ['orig_fields' => $fields]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -116,7 +117,7 @@ class InfluxDB extends BaseDatastore
|
||||
null, // the measurement value
|
||||
$tmp_tags,
|
||||
$tmp_fields // optional additional fields
|
||||
)
|
||||
),
|
||||
];
|
||||
|
||||
$this->connection->writePoints($points);
|
||||
@ -179,7 +180,7 @@ class InfluxDB extends BaseDatastore
|
||||
/**
|
||||
* Checks if the datastore wants rrdtags to be sent when issuing put()
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function wantsRrdTags()
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ use Log;
|
||||
|
||||
class OpenTSDB extends BaseDatastore
|
||||
{
|
||||
/** @var \Socket\Raw\Socket $connection */
|
||||
/** @var \Socket\Raw\Socket */
|
||||
protected $connection;
|
||||
|
||||
public function __construct(\Socket\Raw\Factory $socketFactory)
|
||||
@ -76,19 +76,20 @@ class OpenTSDB extends BaseDatastore
|
||||
*/
|
||||
public function put($device, $measurement, $tags, $fields)
|
||||
{
|
||||
if (!$this->connection) {
|
||||
if (! $this->connection) {
|
||||
Log::error("OpenTSDB Error: not connected\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$flag = Config::get('opentsdb.co');
|
||||
$timestamp = Carbon::now()->timestamp;
|
||||
$tmp_tags = "hostname=".$device['hostname'];
|
||||
$tmp_tags = "hostname=" . $device['hostname'];
|
||||
|
||||
foreach ($tags as $k => $v) {
|
||||
$v = str_replace(array(' ',',','='), '_', $v);
|
||||
if (!empty($v)) {
|
||||
$tmp_tags = $tmp_tags ." ". $k ."=".$v;
|
||||
$v = str_replace([' ', ',', '='], '_', $v);
|
||||
if (! empty($v)) {
|
||||
$tmp_tags = $tmp_tags . " " . $k . "=" . $v;
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,10 +97,10 @@ class OpenTSDB extends BaseDatastore
|
||||
foreach ($fields as $k => $v) {
|
||||
$measurement = $k;
|
||||
if ($flag == true) {
|
||||
$measurement = $measurement.".".$device['co'];
|
||||
$measurement = $measurement . "." . $device['co'];
|
||||
}
|
||||
|
||||
$this->putData('port.'.$measurement, $timestamp, $v, $tmp_tags);
|
||||
$this->putData('port.' . $measurement, $timestamp, $v, $tmp_tags);
|
||||
}
|
||||
} else {
|
||||
if ($flag == true) {
|
||||
@ -136,7 +137,7 @@ class OpenTSDB extends BaseDatastore
|
||||
/**
|
||||
* Checks if the datastore wants rrdtags to be sent when issuing put()
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function wantsRrdTags()
|
||||
{
|
||||
|
@ -27,10 +27,10 @@
|
||||
namespace LibreNMS\Data\Store;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Illuminate\Support\Str;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\Data\Measure\Measurement;
|
||||
use Log;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Prometheus extends BaseDatastore
|
||||
{
|
||||
@ -72,7 +72,7 @@ class Prometheus extends BaseDatastore
|
||||
{
|
||||
$stat = Measurement::start('put');
|
||||
// skip if needed
|
||||
if (!$this->enabled) {
|
||||
if (! $this->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ class Prometheus extends BaseDatastore
|
||||
|
||||
foreach ($tags as $t => $v) {
|
||||
if ($v !== null) {
|
||||
$promtags .= (Str::contains($v, "/") ? "/$t@base64/". base64_encode($v) : "/$t/$v");
|
||||
$promtags .= (Str::contains($v, "/") ? "/$t@base64/" . base64_encode($v) : "/$t/$v");
|
||||
}
|
||||
}
|
||||
$options = $this->getDefaultOptions();
|
||||
@ -127,7 +127,7 @@ class Prometheus extends BaseDatastore
|
||||
/**
|
||||
* Checks if the datastore wants rrdtags to be sent when issuing put()
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function wantsRrdTags()
|
||||
{
|
||||
|
@ -36,9 +36,9 @@ class Rrd extends BaseDatastore
|
||||
{
|
||||
private $disabled = false;
|
||||
|
||||
/** @var Proc $sync_process */
|
||||
/** @var Proc */
|
||||
private $sync_process;
|
||||
/** @var Proc $async_process */
|
||||
/** @var Proc */
|
||||
private $async_process;
|
||||
private $rrd_dir;
|
||||
private $version;
|
||||
@ -92,11 +92,11 @@ class Rrd extends BaseDatastore
|
||||
|
||||
$cwd = Config::get('rrd_dir');
|
||||
|
||||
if (!$this->isSyncRunning()) {
|
||||
if (! $this->isSyncRunning()) {
|
||||
$this->sync_process = new Proc($command, $descriptor_spec, $cwd);
|
||||
}
|
||||
|
||||
if ($dual_process && !$this->isAsyncRunning()) {
|
||||
if ($dual_process && ! $this->isAsyncRunning()) {
|
||||
$this->async_process = new Proc($command, $descriptor_spec, $cwd);
|
||||
$this->async_process->setSynchronous(false);
|
||||
}
|
||||
@ -104,7 +104,6 @@ class Rrd extends BaseDatastore
|
||||
return $this->isSyncRunning() && ($dual_process ? $this->isAsyncRunning() : true);
|
||||
}
|
||||
|
||||
|
||||
public function isSyncRunning()
|
||||
{
|
||||
return isset($this->sync_process) && $this->sync_process->isRunning();
|
||||
@ -147,7 +146,7 @@ class Rrd extends BaseDatastore
|
||||
{
|
||||
$rrd_name = isset($tags['rrd_name']) ? $tags['rrd_name'] : $measurement;
|
||||
$step = isset($tags['rrd_step']) ? $tags['rrd_step'] : $this->step;
|
||||
if (!empty($tags['rrd_oldname'])) {
|
||||
if (! empty($tags['rrd_oldname'])) {
|
||||
self::renameFile($device, $tags['rrd_oldname'], $rrd_name);
|
||||
}
|
||||
|
||||
@ -164,13 +163,14 @@ class Rrd extends BaseDatastore
|
||||
// filter out data not in the definition
|
||||
$fields = array_filter($fields, function ($key) use ($rrd_def) {
|
||||
$valid = $rrd_def->isValidDataset($key);
|
||||
if (!$valid) {
|
||||
if (! $valid) {
|
||||
Log::warning("RRD warning: unused data sent $key");
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
|
||||
if (!$this->checkRrdExists($rrd)) {
|
||||
if (! $this->checkRrdExists($rrd)) {
|
||||
$newdef = "--step $step $rrd_def $this->rra";
|
||||
$this->command('create', $rrd, $newdef);
|
||||
}
|
||||
@ -196,7 +196,7 @@ class Rrd extends BaseDatastore
|
||||
if (is_array($data)) {
|
||||
$values[] = 'N';
|
||||
foreach ($data as $v) {
|
||||
if (!is_numeric($v)) {
|
||||
if (! is_numeric($v)) {
|
||||
$v = 'U';
|
||||
}
|
||||
|
||||
@ -204,18 +204,21 @@ class Rrd extends BaseDatastore
|
||||
}
|
||||
|
||||
$data = implode(':', $values);
|
||||
|
||||
return $this->command('update', $filename, $data);
|
||||
} else {
|
||||
return 'Bad options passed to rrdtool_update';
|
||||
}
|
||||
} // rrdtool_update
|
||||
}
|
||||
|
||||
// rrdtool_update
|
||||
|
||||
/**
|
||||
* Modify an rrd file's max value and trim the peaks as defined by rrdtool
|
||||
*
|
||||
* @param string $type only 'port' is supported at this time
|
||||
* @param string $filename the path to the rrd file
|
||||
* @param integer $max the new max value
|
||||
* @param int $max the new max value
|
||||
* @return bool
|
||||
*/
|
||||
public function tune($type, $filename, $max)
|
||||
@ -241,15 +244,18 @@ class Rrd extends BaseDatastore
|
||||
'INBROADCASTPKTS',
|
||||
'OUTBROADCASTPKTS',
|
||||
'INMULTICASTPKTS',
|
||||
'OUTMULTICASTPKTS'
|
||||
'OUTMULTICASTPKTS',
|
||||
];
|
||||
}
|
||||
if (count($fields) > 0) {
|
||||
$options = "--maximum " . implode(":$max --maximum ", $fields) . ":$max";
|
||||
$this->command('tune', $filename, $options);
|
||||
}
|
||||
|
||||
return true;
|
||||
} // rrdtool_tune
|
||||
}
|
||||
|
||||
// rrdtool_tune
|
||||
|
||||
/**
|
||||
* Generates a filename for a proxmox cluster rrd
|
||||
@ -263,7 +269,7 @@ class Rrd extends BaseDatastore
|
||||
{
|
||||
$pmxcdir = join('/', [$this->rrd_dir, 'proxmox', self::safeName($pmxcluster)]);
|
||||
// this is not needed for remote rrdcached
|
||||
if (!is_dir($pmxcdir)) {
|
||||
if (! is_dir($pmxcdir)) {
|
||||
mkdir($pmxcdir, 0775, true);
|
||||
}
|
||||
|
||||
@ -294,12 +300,14 @@ class Rrd extends BaseDatastore
|
||||
{
|
||||
$oldrrd = self::name($device['hostname'], $oldname);
|
||||
$newrrd = self::name($device['hostname'], $newname);
|
||||
if (is_file($oldrrd) && !is_file($newrrd)) {
|
||||
if (is_file($oldrrd) && ! is_file($newrrd)) {
|
||||
if (rename($oldrrd, $newrrd)) {
|
||||
log_event("Renamed $oldrrd to $newrrd", $device, "poller", 1);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
log_event("Failed to rename $oldrrd to $newrrd", $device, "poller", 5);
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
@ -319,6 +327,7 @@ class Rrd extends BaseDatastore
|
||||
public function name($host, $extra, $extension = ".rrd")
|
||||
{
|
||||
$filename = self::safeName(is_array($extra) ? implode("-", $extra) : $extra);
|
||||
|
||||
return implode("/", [$this->dirFromHost($host), $filename . $extension]);
|
||||
}
|
||||
|
||||
@ -331,6 +340,7 @@ class Rrd extends BaseDatastore
|
||||
public function dirFromHost($host)
|
||||
{
|
||||
$host = str_replace(':', '_', trim($host, '[]'));
|
||||
|
||||
return implode("/", [$this->rrd_dir, $host]);
|
||||
}
|
||||
|
||||
@ -353,6 +363,7 @@ class Rrd extends BaseDatastore
|
||||
$cmd = self::buildCommand($command, $filename, $options);
|
||||
} catch (FileExistsException $e) {
|
||||
Log::debug("RRD[%g$filename already exists%n]", ['color' => true]);
|
||||
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
@ -360,10 +371,11 @@ class Rrd extends BaseDatastore
|
||||
|
||||
// do not write rrd files, but allow read-only commands
|
||||
$ro_commands = ['graph', 'graphv', 'dump', 'fetch', 'first', 'last', 'lastupdate', 'info', 'xport'];
|
||||
if ($this->disabled && !in_array($command, $ro_commands)) {
|
||||
if (!Config::get('hide_rrd_disabled')) {
|
||||
if ($this->disabled && ! in_array($command, $ro_commands)) {
|
||||
if (! Config::get('hide_rrd_disabled')) {
|
||||
Log::debug('[%rRRD Disabled%n]', ['color' => true]);
|
||||
}
|
||||
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
@ -385,6 +397,7 @@ class Rrd extends BaseDatastore
|
||||
}
|
||||
|
||||
$this->recordStatistic($stat->end());
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
@ -415,8 +428,8 @@ class Rrd extends BaseDatastore
|
||||
|
||||
// no remote for create < 1.5.5 and tune < 1.5
|
||||
if ($this->rrdcached &&
|
||||
!($command == 'create' && version_compare($this->version, '1.5.5', '<')) &&
|
||||
!($command == 'tune' && $this->rrdcached && version_compare($this->version, '1.5', '<'))
|
||||
! ($command == 'create' && version_compare($this->version, '1.5.5', '<')) &&
|
||||
! ($command == 'tune' && $this->rrdcached && version_compare($this->version, '1.5', '<'))
|
||||
) {
|
||||
// only relative paths if using rrdcached
|
||||
$filename = str_replace([$this->rrd_dir . '/', $this->rrd_dir], '', $filename);
|
||||
@ -440,7 +453,8 @@ class Rrd extends BaseDatastore
|
||||
if ($this->rrdcached && version_compare($this->version, '1.5', '>=')) {
|
||||
$chk = $this->command('last', $filename, '');
|
||||
$filename = str_replace([$this->rrd_dir . '/', $this->rrd_dir], '', $filename);
|
||||
return !Str::contains(implode($chk), "$filename': No such file or directory");
|
||||
|
||||
return ! Str::contains(implode($chk), "$filename': No such file or directory");
|
||||
} else {
|
||||
return is_file($filename);
|
||||
}
|
||||
@ -455,6 +469,7 @@ class Rrd extends BaseDatastore
|
||||
{
|
||||
if (empty($hostname)) {
|
||||
Log::error("Could not purge rrd $prefix, empty hostname");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -469,7 +484,7 @@ class Rrd extends BaseDatastore
|
||||
*
|
||||
* @param string $graph_file
|
||||
* @param string $options
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function graph($graph_file, $options)
|
||||
{
|
||||
@ -499,7 +514,7 @@ class Rrd extends BaseDatastore
|
||||
*/
|
||||
public static function safeName($name)
|
||||
{
|
||||
return (string)preg_replace('/[^a-zA-Z0-9,._\-]/', '_', $name);
|
||||
return (string) preg_replace('/[^a-zA-Z0-9,._\-]/', '_', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -510,7 +525,7 @@ class Rrd extends BaseDatastore
|
||||
*/
|
||||
public static function safeDescr($descr)
|
||||
{
|
||||
return (string)preg_replace('/[^a-zA-Z0-9,._\-\/\ ]/', ' ', $descr);
|
||||
return (string) preg_replace('/[^a-zA-Z0-9,._\-\/\ ]/', ' ', $descr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
namespace LibreNMS\Device;
|
||||
|
||||
use \App\Models\DeviceOutage;
|
||||
use App\Models\DeviceOutage;
|
||||
|
||||
class Availability
|
||||
{
|
||||
@ -39,24 +39,28 @@ class Availability
|
||||
public static function day($device, $precision = 3)
|
||||
{
|
||||
$duration = 86400;
|
||||
|
||||
return self::availability($device, $duration, $precision);
|
||||
}
|
||||
|
||||
public static function week($device, $precision = 3)
|
||||
{
|
||||
$duration = 604800;
|
||||
|
||||
return self::availability($device, $duration, $precision);
|
||||
}
|
||||
|
||||
public static function month($device, $precision = 3)
|
||||
{
|
||||
$duration = 2592000;
|
||||
|
||||
return self::availability($device, $duration, $precision);
|
||||
}
|
||||
|
||||
public static function year($device, $precision = 3)
|
||||
{
|
||||
$duration = 31536000;
|
||||
|
||||
return self::availability($device, $duration, $precision);
|
||||
}
|
||||
|
||||
@ -70,25 +74,26 @@ class Availability
|
||||
*/
|
||||
protected static function outageSummary($found_outages, $duration, $now = null)
|
||||
{
|
||||
if (!is_numeric($now)) {
|
||||
if (! is_numeric($now)) {
|
||||
$now = time();
|
||||
}
|
||||
|
||||
# sum up time period of all outages
|
||||
// sum up time period of all outages
|
||||
$outage_sum = 0;
|
||||
foreach ($found_outages as $outage) {
|
||||
# if device is still down, outage goes till $now
|
||||
// if device is still down, outage goes till $now
|
||||
$up_again = $outage->up_again ?: $now;
|
||||
|
||||
if ($outage->going_down >= ($now - $duration)) {
|
||||
# outage complete in duration period
|
||||
// outage complete in duration period
|
||||
$going_down = $outage->going_down;
|
||||
} else {
|
||||
# outage partial in duration period, so consider only relevant part
|
||||
// outage partial in duration period, so consider only relevant part
|
||||
$going_down = $now - $duration;
|
||||
}
|
||||
$outage_sum += ($up_again - $going_down);
|
||||
}
|
||||
|
||||
return $outage_sum;
|
||||
}
|
||||
|
||||
@ -104,7 +109,7 @@ class Availability
|
||||
*/
|
||||
public static function availability($device, $duration, $precision = 3, $now = null)
|
||||
{
|
||||
if (!is_numeric($now)) {
|
||||
if (! is_numeric($now)) {
|
||||
$now = time();
|
||||
}
|
||||
|
||||
@ -114,8 +119,8 @@ class Availability
|
||||
|
||||
$found_outages = $query->get();
|
||||
|
||||
# no recorded outages found, so use current uptime
|
||||
if (!count($found_outages)) {
|
||||
// no recorded outages found, so use current uptime
|
||||
if (! count($found_outages)) {
|
||||
return 100 * 1;
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ class Processor extends Model implements DiscoveryModule, PollerModule, Discover
|
||||
$proc = new static();
|
||||
$proc->processor_type = $type;
|
||||
$proc->device_id = $device_id;
|
||||
$proc->processor_index = (string)$index;
|
||||
$proc->processor_index = (string) $index;
|
||||
$proc->processor_descr = $description;
|
||||
$proc->processor_precision = $precision;
|
||||
$proc->processor_usage = $current_usage;
|
||||
@ -98,8 +98,7 @@ class Processor extends Model implements DiscoveryModule, PollerModule, Discover
|
||||
}
|
||||
$proc->processor_oid = '.' . ltrim($oid, '.');
|
||||
|
||||
|
||||
if (!is_null($warn_percent)) {
|
||||
if (! is_null($warn_percent)) {
|
||||
$proc->processor_perc_warn = $warn_percent;
|
||||
}
|
||||
|
||||
@ -107,7 +106,7 @@ class Processor extends Model implements DiscoveryModule, PollerModule, Discover
|
||||
if (is_null($proc->processor_usage)) {
|
||||
$data = snmp_get(device_by_id_cache($proc->device_id), $proc->processor_oid, '-Ovq');
|
||||
$proc->valid = ($data !== false);
|
||||
if (!$proc->valid) {
|
||||
if (! $proc->valid) {
|
||||
return $proc;
|
||||
}
|
||||
$proc->processor_usage = static::processData($data, $proc->processor_precision);
|
||||
@ -160,14 +159,14 @@ class Processor extends Model implements DiscoveryModule, PollerModule, Discover
|
||||
);
|
||||
}
|
||||
|
||||
dbDeleteOrphans(static::$table, array('devices.device_id'));
|
||||
dbDeleteOrphans(static::$table, ['devices.device_id']);
|
||||
|
||||
echo PHP_EOL;
|
||||
}
|
||||
|
||||
public static function poll(OS $os)
|
||||
{
|
||||
$processors = dbFetchRows('SELECT * FROM processors WHERE device_id=?', array($os->getDeviceId()));
|
||||
$processors = dbFetchRows('SELECT * FROM processors WHERE device_id=?', [$os->getDeviceId()]);
|
||||
|
||||
if ($os instanceof ProcessorPolling) {
|
||||
$data = $os->pollProcessors($processors);
|
||||
@ -183,18 +182,17 @@ class Processor extends Model implements DiscoveryModule, PollerModule, Discover
|
||||
/** @var string $processor_type */
|
||||
/** @var int $processor_index */
|
||||
/** @var int $processor_usage */
|
||||
|
||||
if (array_key_exists($processor_id, $data)) {
|
||||
$usage = round($data[$processor_id], 2);
|
||||
echo "$usage%\n";
|
||||
|
||||
$rrd_name = array('processor', $processor_type, $processor_index);
|
||||
$rrd_name = ['processor', $processor_type, $processor_index];
|
||||
$fields = compact('usage');
|
||||
$tags = compact('processor_type', 'processor_index', 'rrd_name', 'rrd_def');
|
||||
data_update($os->getDeviceArray(), 'processors', $tags, $fields);
|
||||
|
||||
if ($usage != $processor_usage) {
|
||||
dbUpdate(array('processor_usage' => $usage), 'processors', '`processor_id` = ?', array($processor_id));
|
||||
dbUpdate(['processor_usage' => $usage], 'processors', '`processor_id` = ?', [$processor_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -203,13 +201,13 @@ class Processor extends Model implements DiscoveryModule, PollerModule, Discover
|
||||
private static function pollProcessors(OS $os, $processors)
|
||||
{
|
||||
if (empty($processors)) {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
$oids = array_column($processors, 'processor_oid');
|
||||
|
||||
// don't fetch too many at a time TODO build into snmp_get_multi_oid?
|
||||
$snmp_data = array();
|
||||
$snmp_data = [];
|
||||
foreach (array_chunk($oids, get_device_oid_limit($os->getDeviceArray())) as $oid_chunk) {
|
||||
$multi_data = snmp_get_multi_oid($os->getDeviceArray(), $oid_chunk);
|
||||
$snmp_data = array_merge($snmp_data, $multi_data);
|
||||
@ -217,7 +215,7 @@ class Processor extends Model implements DiscoveryModule, PollerModule, Discover
|
||||
|
||||
d_echo($snmp_data);
|
||||
|
||||
$results = array();
|
||||
$results = [];
|
||||
foreach ($processors as $processor) {
|
||||
if (isset($snmp_data[$processor['processor_oid']])) {
|
||||
$value = static::processData(
|
||||
@ -254,13 +252,13 @@ class Processor extends Model implements DiscoveryModule, PollerModule, Discover
|
||||
$device = $os->getDeviceArray();
|
||||
if (empty($device['dynamic_discovery']['modules']['processors'])) {
|
||||
d_echo("No YAML Discovery data.\n");
|
||||
return array();
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
return YamlDiscovery::discover($os, get_class(), $device['dynamic_discovery']['modules']['processors']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Is this sensor valid?
|
||||
* If not, it should not be added to or in the database
|
||||
@ -278,21 +276,21 @@ class Processor extends Model implements DiscoveryModule, PollerModule, Discover
|
||||
* @param array $exclude exclude columns
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($exclude = array())
|
||||
public function toArray($exclude = [])
|
||||
{
|
||||
$array = array(
|
||||
$array = [
|
||||
'processor_id' => $this->processor_id,
|
||||
'entPhysicalIndex' => (int)$this->entPhysicalIndex,
|
||||
'hrDeviceIndex' => (int)$this->hrDeviceIndex,
|
||||
'entPhysicalIndex' => (int) $this->entPhysicalIndex,
|
||||
'hrDeviceIndex' => (int) $this->hrDeviceIndex,
|
||||
'device_id' => $this->device_id,
|
||||
'processor_oid' => $this->processor_oid,
|
||||
'processor_index' => $this->processor_index,
|
||||
'processor_type' => $this->processor_type,
|
||||
'processor_usage' => $this->processor_usage,
|
||||
'processor_descr' => $this->processor_descr,
|
||||
'processor_precision' => (int)$this->processor_precision,
|
||||
'processor_perc_warn' => (int)$this->processor_perc_warn,
|
||||
);
|
||||
'processor_precision' => (int) $this->processor_precision,
|
||||
'processor_perc_warn' => (int) $this->processor_perc_warn,
|
||||
];
|
||||
|
||||
return array_diff_key($array, array_flip($exclude));
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
) {
|
||||
$this->type = $type;
|
||||
$this->device_id = $device_id;
|
||||
$this->oids = (array)$oids;
|
||||
$this->oids = (array) $oids;
|
||||
$this->subtype = $subtype;
|
||||
$this->index = $index;
|
||||
$this->description = $description;
|
||||
@ -123,7 +123,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
// validity not checked yet
|
||||
if (is_null($this->current)) {
|
||||
$sensor['sensor_oids'] = $this->oids;
|
||||
$sensors = array($sensor);
|
||||
$sensors = [$sensor];
|
||||
|
||||
$prefetch = self::fetchSnmpData(device_by_id_cache($device_id), $sensors);
|
||||
$data = static::processSensorData($sensors, $prefetch);
|
||||
@ -159,7 +159,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
if (empty($update)) {
|
||||
echo '.';
|
||||
} else {
|
||||
dbUpdate($this->escapeNull($update), $this->getTable(), '`sensor_id`=?', array($this->sensor_id));
|
||||
dbUpdate($this->escapeNull($update), $this->getTable(), '`sensor_id`=?', [$this->sensor_id]);
|
||||
echo 'U';
|
||||
}
|
||||
} else {
|
||||
@ -187,16 +187,17 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
if (isset($this->sensor_id)) {
|
||||
return dbFetchRow(
|
||||
"SELECT `$table` FROM ? WHERE `sensor_id`=?",
|
||||
array($this->sensor_id)
|
||||
[$this->sensor_id]
|
||||
);
|
||||
}
|
||||
|
||||
$sensor = dbFetchRow(
|
||||
"SELECT * FROM `$table` " .
|
||||
"WHERE `device_id`=? AND `sensor_class`=? AND `sensor_type`=? AND `sensor_index`=?",
|
||||
array($this->device_id, $this->type, $this->subtype, $this->index)
|
||||
[$this->device_id, $this->type, $this->subtype, $this->index]
|
||||
);
|
||||
$this->sensor_id = $sensor['sensor_id'];
|
||||
|
||||
return $sensor;
|
||||
}
|
||||
|
||||
@ -217,7 +218,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
*/
|
||||
protected function toArray()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
'sensor_class' => $this->type,
|
||||
'device_id' => $this->device_id,
|
||||
'sensor_oids' => json_encode($this->oids),
|
||||
@ -234,7 +235,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
'sensor_current' => $this->current,
|
||||
'entPhysicalIndex' => $this->entPhysicalIndex,
|
||||
'entPhysicalIndex_measured' => $this->entPhysicalMeasured,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -247,7 +248,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
private function escapeNull($array)
|
||||
{
|
||||
return array_map(function ($value) {
|
||||
return is_null($value) ? array('NULL') : $value;
|
||||
return is_null($value) ? ['NULL'] : $value;
|
||||
}, $array);
|
||||
}
|
||||
|
||||
@ -274,7 +275,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
$params = [$os->getDeviceId()];
|
||||
|
||||
$submodules = Config::get('poller_submodules.wireless', []);
|
||||
if (!empty($submodules)) {
|
||||
if (! empty($submodules)) {
|
||||
$query .= " AND `sensor_class` IN " . dbGenPlaceholders(count($submodules));
|
||||
$params = array_merge($params, $submodules);
|
||||
}
|
||||
@ -285,15 +286,16 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
function ($carry, $sensor) {
|
||||
$sensor['sensor_oids'] = json_decode($sensor['sensor_oids']);
|
||||
$carry[$sensor['sensor_class']][] = $sensor;
|
||||
|
||||
return $carry;
|
||||
},
|
||||
array()
|
||||
[]
|
||||
);
|
||||
|
||||
foreach ($sensors as $type => $type_sensors) {
|
||||
// check for custom polling
|
||||
$typeInterface = static::getPollingInterface($type);
|
||||
if (!interface_exists($typeInterface)) {
|
||||
if (! interface_exists($typeInterface)) {
|
||||
echo "ERROR: Polling Interface doesn't exist! $typeInterface\n";
|
||||
}
|
||||
|
||||
@ -322,7 +324,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
* @param array $sensors
|
||||
* @param array $prefetch
|
||||
*/
|
||||
protected static function pollSensorType($os, $type, $sensors, $prefetch = array())
|
||||
protected static function pollSensorType($os, $type, $sensors, $prefetch = [])
|
||||
{
|
||||
echo "$type:\n";
|
||||
|
||||
@ -353,7 +355,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
{
|
||||
$oids = self::getOidsFromSensors($sensors, get_device_oid_limit($device));
|
||||
|
||||
$snmp_data = array();
|
||||
$snmp_data = [];
|
||||
foreach ($oids as $oid_chunk) {
|
||||
$multi_data = snmp_get_multi_oid($device, $oid_chunk, '-OUQnt');
|
||||
$snmp_data = array_merge($snmp_data, $multi_data);
|
||||
@ -372,7 +374,6 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
return $snmp_data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the snmp data for the specified sensors
|
||||
* Returns an array sensor_id => value
|
||||
@ -384,7 +385,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
*/
|
||||
protected static function processSensorData($sensors, $prefetch)
|
||||
{
|
||||
$sensor_data = array();
|
||||
$sensor_data = [];
|
||||
foreach ($sensors as $sensor) {
|
||||
// pull out the data for this sensor
|
||||
$requested_oids = array_flip($sensor['sensor_oids']);
|
||||
@ -422,7 +423,6 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
return $sensor_data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of unique oids from an array of sensors and break it into chunks.
|
||||
*
|
||||
@ -435,7 +435,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
// Sort the incoming oids and sensors
|
||||
$oids = array_reduce($sensors, function ($carry, $sensor) {
|
||||
return array_merge($carry, $sensor['sensor_oids']);
|
||||
}, array());
|
||||
}, []);
|
||||
|
||||
// only unique oids and chunk
|
||||
$oids = array_chunk(array_keys(array_flip($oids)), $chunk);
|
||||
@ -446,7 +446,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
protected static function discoverType(OS $os, $type)
|
||||
{
|
||||
$typeInterface = static::getDiscoveryInterface($type);
|
||||
if (!interface_exists($typeInterface)) {
|
||||
if (! interface_exists($typeInterface)) {
|
||||
echo "ERROR: Discovery Interface doesn't exist! $typeInterface\n";
|
||||
}
|
||||
|
||||
@ -455,12 +455,12 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
echo "$type: ";
|
||||
$function = static::getDiscoveryMethod($type);
|
||||
$sensors = $os->$function();
|
||||
if (!is_array($sensors)) {
|
||||
if (! is_array($sensors)) {
|
||||
c_echo("%RERROR:%n $function did not return an array! Skipping discovery.");
|
||||
$sensors = array();
|
||||
$sensors = [];
|
||||
}
|
||||
} else {
|
||||
$sensors = array(); // delete non existent sensors
|
||||
$sensors = []; // delete non existent sensors
|
||||
}
|
||||
|
||||
self::checkForDuplicateSensors($sensors);
|
||||
@ -474,7 +474,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
|
||||
private static function checkForDuplicateSensors($sensors)
|
||||
{
|
||||
$duplicate_check = array();
|
||||
$duplicate_check = [];
|
||||
$dup = false;
|
||||
|
||||
foreach ($sensors as $sensor) {
|
||||
@ -544,7 +544,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
final public static function sync($device_id, $type, array $sensors)
|
||||
{
|
||||
// save and collect valid ids
|
||||
$valid_sensor_ids = array();
|
||||
$valid_sensor_ids = [];
|
||||
foreach ($sensors as $sensor) {
|
||||
/** @var $this $sensor */
|
||||
if ($sensor->isValid()) {
|
||||
@ -566,10 +566,10 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
private static function clean($device_id, $type, $sensor_ids)
|
||||
{
|
||||
$table = static::$table;
|
||||
$params = array($device_id, $type);
|
||||
$params = [$device_id, $type];
|
||||
$where = '`device_id`=? AND `sensor_class`=?';
|
||||
|
||||
if (!empty($sensor_ids)) {
|
||||
if (! empty($sensor_ids)) {
|
||||
$where .= ' AND `sensor_id` NOT IN ' . dbGenPlaceholders(count($sensor_ids));
|
||||
$params = array_merge($params, $sensor_ids);
|
||||
}
|
||||
@ -582,7 +582,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
$message .= " Deleted: $type {$sensor['sensor_type']} {$sensor['sensor_index']} {$sensor['sensor_descr']}";
|
||||
log_event($message, $device_id, static::$table, 3, $sensor['sensor_id']);
|
||||
}
|
||||
if (!empty($delete)) {
|
||||
if (! empty($delete)) {
|
||||
dbDelete($table, $where, $params);
|
||||
}
|
||||
}
|
||||
@ -601,7 +601,7 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
*/
|
||||
public static function getTypes($valid = false, $device_id = null)
|
||||
{
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -621,35 +621,35 @@ class Sensor implements DiscoveryModule, PollerModule
|
||||
echo " {$sensor['sensor_descr']}: $sensor_value " . __(static::$translation_prefix . '.' . $sensor['sensor_class'] . '.unit') . PHP_EOL;
|
||||
|
||||
// update rrd and database
|
||||
$rrd_name = array(
|
||||
$rrd_name = [
|
||||
static::$data_name,
|
||||
$sensor['sensor_class'],
|
||||
$sensor['sensor_type'],
|
||||
$sensor['sensor_index']
|
||||
);
|
||||
$sensor['sensor_index'],
|
||||
];
|
||||
$rrd_type = isset($types[$sensor['sensor_class']]['type']) ? strtoupper($types[$sensor['sensor_class']]['type']) : 'GAUGE';
|
||||
$rrd_def = RrdDefinition::make()->addDataset('sensor', $rrd_type);
|
||||
|
||||
$fields = array(
|
||||
$fields = [
|
||||
'sensor' => isset($sensor_value) ? $sensor_value : 'U',
|
||||
);
|
||||
];
|
||||
|
||||
$tags = array(
|
||||
$tags = [
|
||||
'sensor_class' => $sensor['sensor_class'],
|
||||
'sensor_type' => $sensor['sensor_type'],
|
||||
'sensor_descr' => $sensor['sensor_descr'],
|
||||
'sensor_index' => $sensor['sensor_index'],
|
||||
'rrd_name' => $rrd_name,
|
||||
'rrd_def' => $rrd_def
|
||||
);
|
||||
'rrd_def' => $rrd_def,
|
||||
];
|
||||
data_update($os->getDeviceArray(), static::$data_name, $tags, $fields);
|
||||
|
||||
$update = array(
|
||||
$update = [
|
||||
'sensor_prev' => $sensor['sensor_current'],
|
||||
'sensor_current' => $sensor_value,
|
||||
'lastupdate' => array('NOW()'),
|
||||
);
|
||||
dbUpdate($update, static::$table, "`sensor_id` = ?", array($sensor['sensor_id']));
|
||||
'lastupdate' => ['NOW()'],
|
||||
];
|
||||
dbUpdate($update, static::$table, "`sensor_id` = ?", [$sensor['sensor_id']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,6 +102,7 @@ class WirelessSensor extends Sensor
|
||||
{
|
||||
$sensor = parent::toArray();
|
||||
$sensor['access_point_id'] = $this->access_point_ip;
|
||||
|
||||
return $sensor;
|
||||
}
|
||||
|
||||
@ -204,7 +205,7 @@ class WirelessSensor extends Sensor
|
||||
|
||||
if ($valid) {
|
||||
$sql = 'SELECT `sensor_class` FROM `wireless_sensors`';
|
||||
$params = array();
|
||||
$params = [];
|
||||
if (isset($device_id)) {
|
||||
$sql .= ' WHERE `device_id`=?';
|
||||
$params[] = $device_id;
|
||||
@ -212,6 +213,7 @@ class WirelessSensor extends Sensor
|
||||
$sql .= ' GROUP BY `sensor_class`';
|
||||
|
||||
$sensors = dbFetchColumn($sql, $params);
|
||||
|
||||
return array_intersect_key($types, array_flip($sensors));
|
||||
}
|
||||
|
||||
@ -246,7 +248,7 @@ class WirelessSensor extends Sensor
|
||||
*/
|
||||
public static function channelToFrequency($channel)
|
||||
{
|
||||
$channels = array(
|
||||
$channels = [
|
||||
1 => 2412,
|
||||
2 => 2417,
|
||||
3 => 2422,
|
||||
@ -289,7 +291,7 @@ class WirelessSensor extends Sensor
|
||||
157 => 5785,
|
||||
161 => 5805,
|
||||
165 => 5825,
|
||||
);
|
||||
];
|
||||
|
||||
return $channels[$channel];
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ class YamlDiscovery
|
||||
public static function discover(OS $os, $class, $yaml_data)
|
||||
{
|
||||
$pre_cache = $os->preCache();
|
||||
$items = array();
|
||||
$items = [];
|
||||
|
||||
// convert to class name for static call below
|
||||
if (is_object($class)) {
|
||||
@ -56,7 +56,7 @@ class YamlDiscovery
|
||||
continue;
|
||||
}
|
||||
|
||||
$group_options = isset($first_yaml['options']) ? $first_yaml['options'] : array();
|
||||
$group_options = isset($first_yaml['options']) ? $first_yaml['options'] : [];
|
||||
|
||||
// find the data array, we could already be at for simple modules
|
||||
if (isset($data['data'])) {
|
||||
@ -66,7 +66,7 @@ class YamlDiscovery
|
||||
}
|
||||
|
||||
foreach ($first_yaml as $data) {
|
||||
$raw_data = (array)$pre_cache[$data['oid']];
|
||||
$raw_data = (array) $pre_cache[$data['oid']];
|
||||
|
||||
d_echo("Data {$data['oid']}: ");
|
||||
d_echo($raw_data);
|
||||
@ -74,9 +74,9 @@ class YamlDiscovery
|
||||
$count = 0;
|
||||
foreach ($raw_data as $index => $snmp_data) {
|
||||
$count++;
|
||||
$current_data = array();
|
||||
$current_data = [];
|
||||
|
||||
if (!isset($data['value'])) {
|
||||
if (! isset($data['value'])) {
|
||||
$data['value'] = $data['oid'];
|
||||
}
|
||||
|
||||
@ -104,10 +104,10 @@ class YamlDiscovery
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
|
||||
public static function replaceValues($name, $index, $count, $data, $pre_cache)
|
||||
{
|
||||
$value = static::getValueFromData($name, $index, $data, $pre_cache);
|
||||
@ -135,8 +135,10 @@ class YamlDiscovery
|
||||
$replace = static::getValueFromData($matches[1], $index, $data, $pre_cache, null);
|
||||
if (is_null($replace)) {
|
||||
d_echo('Warning: No variable available to replace ' . $matches[1] . ".\n");
|
||||
|
||||
return ''; // remove the unavailable variable
|
||||
}
|
||||
|
||||
return $replace;
|
||||
}, $value);
|
||||
}
|
||||
@ -144,7 +146,6 @@ class YamlDiscovery
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function for dynamic discovery to search for data from pre_cached snmp data
|
||||
*
|
||||
@ -193,7 +194,7 @@ class YamlDiscovery
|
||||
public static function preCache(OS $os)
|
||||
{
|
||||
// Pre-cache data for later use
|
||||
$pre_cache = array();
|
||||
$pre_cache = [];
|
||||
$device = $os->getDeviceArray();
|
||||
|
||||
$pre_cache_file = 'includes/discovery/sensors/pre-cache/' . $device['os'] . '.inc.php';
|
||||
@ -209,7 +210,7 @@ class YamlDiscovery
|
||||
return $pre_cache;
|
||||
}
|
||||
|
||||
if (!empty($device['dynamic_discovery']['modules'])) {
|
||||
if (! empty($device['dynamic_discovery']['modules'])) {
|
||||
echo "Caching data: ";
|
||||
foreach ($device['dynamic_discovery']['modules'] as $module => $discovery_data) {
|
||||
echo "$module ";
|
||||
@ -222,8 +223,8 @@ class YamlDiscovery
|
||||
}
|
||||
|
||||
foreach ($data_array as $data) {
|
||||
foreach ((array)$data['oid'] as $oid) {
|
||||
if (!array_key_exists($oid, $pre_cache)) {
|
||||
foreach ((array) $data['oid'] as $oid) {
|
||||
if (! array_key_exists($oid, $pre_cache)) {
|
||||
if (isset($data['snmp_flags'])) {
|
||||
$snmp_flag = Arr::wrap($data['snmp_flags']);
|
||||
} else {
|
||||
@ -253,9 +254,9 @@ class YamlDiscovery
|
||||
* @param array $item_snmp_data The pre-cache data array
|
||||
* @return bool
|
||||
*/
|
||||
public static function canSkipItem($value, $index, $yaml_item_data, $group_options, $pre_cache = array())
|
||||
public static function canSkipItem($value, $index, $yaml_item_data, $group_options, $pre_cache = [])
|
||||
{
|
||||
$skip_values = array_replace((array)$group_options['skip_values'], (array)$yaml_item_data['skip_values']);
|
||||
$skip_values = array_replace((array) $group_options['skip_values'], (array) $yaml_item_data['skip_values']);
|
||||
|
||||
foreach ($skip_values as $skip_value) {
|
||||
if (is_array($skip_value) && $pre_cache) {
|
||||
@ -275,14 +276,14 @@ class YamlDiscovery
|
||||
}
|
||||
}
|
||||
|
||||
$skip_value_lt = array_replace((array)$group_options['skip_value_lt'], (array)$yaml_item_data['skip_value_lt']);
|
||||
$skip_value_lt = array_replace((array) $group_options['skip_value_lt'], (array) $yaml_item_data['skip_value_lt']);
|
||||
foreach ($skip_value_lt as $skip_value) {
|
||||
if ($value < $skip_value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$skip_value_gt = array_replace((array)$group_options['skip_value_gt'], (array)$yaml_item_data['skip_value_gt']);
|
||||
$skip_value_gt = array_replace((array) $group_options['skip_value_gt'], (array) $yaml_item_data['skip_value_gt']);
|
||||
foreach ($skip_value_gt as $skip_value) {
|
||||
if ($value > $skip_value) {
|
||||
return true;
|
||||
|
@ -27,5 +27,4 @@ namespace LibreNMS\Exceptions;
|
||||
|
||||
class FileExistsException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -27,5 +27,4 @@ namespace LibreNMS\Exceptions;
|
||||
|
||||
class FileNotFoundException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -109,10 +109,10 @@ class FilePermissionsException extends \Exception implements UpgradeableExceptio
|
||||
];
|
||||
|
||||
$mk_dirs = array_filter($mkdirs, function ($file) {
|
||||
return !file_exists($file);
|
||||
return ! file_exists($file);
|
||||
});
|
||||
|
||||
if (!empty($mk_dirs)) {
|
||||
if (! empty($mk_dirs)) {
|
||||
$commands[] = 'sudo mkdir -p ' . implode(' ', $mk_dirs);
|
||||
}
|
||||
|
||||
@ -123,19 +123,19 @@ class FilePermissionsException extends \Exception implements UpgradeableExceptio
|
||||
|
||||
// check if webserver is in the librenms group
|
||||
$current_groups = explode(' ', trim(exec('groups')));
|
||||
if (!in_array($group, $current_groups)) {
|
||||
if (! in_array($group, $current_groups)) {
|
||||
$current_user = trim(exec('whoami'));
|
||||
$commands[] = "usermod -a -G $group $current_user";
|
||||
}
|
||||
|
||||
// check for invalid log setting
|
||||
if (!is_file($log_file) || !is_writable($log_file)) {
|
||||
if (! is_file($log_file) || ! is_writable($log_file)) {
|
||||
// override for proper error output
|
||||
$dirs = [$log_file];
|
||||
$install_dir = $log_file;
|
||||
$commands = [
|
||||
'<h3>Cannot write to log file: "' . $log_file . '"</h3>',
|
||||
'Make sure it exists and is writable, or change your LOG_DIR setting.'
|
||||
'Make sure it exists and is writable, or change your LOG_DIR setting.',
|
||||
];
|
||||
}
|
||||
|
||||
@ -145,6 +145,7 @@ class FilePermissionsException extends \Exception implements UpgradeableExceptio
|
||||
$commands[] = "semanage fcontext -a -t httpd_sys_rw_content_t '$dir(/.*)?'";
|
||||
}
|
||||
$commands[] = "restorecon -RFv $install_dir";
|
||||
|
||||
return $commands;
|
||||
}
|
||||
}
|
||||
|
@ -27,5 +27,4 @@ namespace LibreNMS\Exceptions;
|
||||
|
||||
class HostExistsException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -27,5 +27,4 @@ namespace LibreNMS\Exceptions;
|
||||
|
||||
class HostIpExistsException extends HostExistsException
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ namespace LibreNMS\Exceptions;
|
||||
|
||||
class HostUnreachableException extends \Exception
|
||||
{
|
||||
protected $reasons = array();
|
||||
protected $reasons = [];
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
@ -35,6 +35,7 @@ class HostUnreachableException extends \Exception
|
||||
foreach ($this->reasons as $reason) {
|
||||
$string .= " $reason\n";
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
|
@ -27,5 +27,4 @@ namespace LibreNMS\Exceptions;
|
||||
|
||||
class HostUnreachablePingException extends HostUnreachableException
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -27,5 +27,4 @@ namespace LibreNMS\Exceptions;
|
||||
|
||||
class HostUnreachableSnmpException extends HostUnreachableException
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -27,5 +27,4 @@ namespace LibreNMS\Exceptions;
|
||||
|
||||
class InvalidPortAssocModeException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -27,5 +27,4 @@ namespace LibreNMS\Exceptions;
|
||||
|
||||
class InvalidRrdTypeException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -4,5 +4,4 @@ namespace LibreNMS\Exceptions;
|
||||
|
||||
class JsonAppException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -4,5 +4,4 @@ namespace LibreNMS\Exceptions;
|
||||
|
||||
class JsonAppPollingFailedException extends JsonAppException
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
* @author Tony Murray <murraytony@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
namespace LibreNMS\Exceptions;
|
||||
|
||||
class LockException extends \Exception
|
||||
|
@ -25,8 +25,8 @@
|
||||
|
||||
namespace LibreNMS\Exceptions;
|
||||
|
||||
use LibreNMS\Interfaces\Exceptions\UpgradeableException;
|
||||
use Illuminate\Support\Str;
|
||||
use LibreNMS\Interfaces\Exceptions\UpgradeableException;
|
||||
use Symfony\Component\Debug\Exception\FatalErrorException;
|
||||
|
||||
class MaximumExecutionTimeExceeded extends \Exception implements UpgradeableException
|
||||
|
@ -27,5 +27,4 @@ namespace LibreNMS\Exceptions;
|
||||
|
||||
class SnmpVersionUnsupportedException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ class Fping
|
||||
$interval,
|
||||
'-t',
|
||||
max($timeout, $interval),
|
||||
$host
|
||||
$host,
|
||||
]);
|
||||
|
||||
$process = app()->make(Process::class, ['command' => $cmd]);
|
||||
@ -79,12 +79,12 @@ class Fping
|
||||
}
|
||||
|
||||
$response = [
|
||||
'xmt' => (int)$xmt,
|
||||
'rcv' => (int)$rcv,
|
||||
'loss' => (int)$loss,
|
||||
'min' => (float)$min,
|
||||
'max' => (float)$max,
|
||||
'avg' => (float)$avg,
|
||||
'xmt' => (int) $xmt,
|
||||
'rcv' => (int) $rcv,
|
||||
'loss' => (int) $loss,
|
||||
'min' => (float) $min,
|
||||
'max' => (float) $max,
|
||||
'avg' => (float) $avg,
|
||||
'dup' => substr_count($output, 'duplicate'),
|
||||
'exitcode' => $process->getExitCode(),
|
||||
];
|
||||
|
@ -20,18 +20,17 @@
|
||||
|
||||
namespace LibreNMS;
|
||||
|
||||
use LibreNMS\DB\Eloquent;
|
||||
use LibreNMS\Authentication\LegacyAuth;
|
||||
use LibreNMS\DB\Eloquent;
|
||||
use LibreNMS\Enum\AlertState;
|
||||
|
||||
class IRCBot
|
||||
{
|
||||
|
||||
private $last_activity = '';
|
||||
|
||||
private $data = '';
|
||||
|
||||
private $authd = array();
|
||||
private $authd = [];
|
||||
|
||||
private $debug = false;
|
||||
|
||||
@ -45,9 +44,9 @@ class IRCBot
|
||||
|
||||
private $nick = 'LibreNMS';
|
||||
|
||||
private $chan = array();
|
||||
private $chan = [];
|
||||
|
||||
private $commands = array(
|
||||
private $commands = [
|
||||
'auth',
|
||||
'quit',
|
||||
'listdevices',
|
||||
@ -60,13 +59,12 @@ class IRCBot
|
||||
'help',
|
||||
'reload',
|
||||
'join',
|
||||
);
|
||||
];
|
||||
|
||||
private $external = array();
|
||||
private $external = [];
|
||||
|
||||
private $tick = 62500;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->log('Setting up IRC-Bot..');
|
||||
@ -93,7 +91,7 @@ class IRCBot
|
||||
} elseif (strstr($this->config['irc_chan'], ',')) {
|
||||
$this->chan = explode(',', $this->config['irc_chan']);
|
||||
} else {
|
||||
$this->chan = array($this->config['irc_chan']);
|
||||
$this->chan = [$this->config['irc_chan']];
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,7 +99,7 @@ class IRCBot
|
||||
if (strstr($this->config['irc_alert_chan'], ',')) {
|
||||
$this->config['irc_alert_chan'] = explode(',', $this->config['irc_alert_chan']);
|
||||
} else {
|
||||
$this->config['irc_alert_chan'] = array($this->config['irc_alert_chan']);
|
||||
$this->config['irc_alert_chan'] = [$this->config['irc_alert_chan']];
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,29 +110,31 @@ class IRCBot
|
||||
$this->loadExternal();
|
||||
$this->log('Starting IRC-Bot..');
|
||||
$this->init();
|
||||
}//end __construct()
|
||||
}
|
||||
|
||||
//end __construct()
|
||||
|
||||
private function loadExternal()
|
||||
{
|
||||
if (!$this->config['irc_external']) {
|
||||
if (! $this->config['irc_external']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->log('Caching external commands...');
|
||||
if (!is_array($this->config['irc_external'])) {
|
||||
if (! is_array($this->config['irc_external'])) {
|
||||
$this->config['irc_external'] = explode(',', $this->config['irc_external']);
|
||||
}
|
||||
|
||||
foreach ($this->config['irc_external'] as $ext) {
|
||||
if (($this->external[$ext] = file_get_contents('includes/ircbot/'.$ext.'.inc.php')) == '') {
|
||||
if (($this->external[$ext] = file_get_contents('includes/ircbot/' . $ext . '.inc.php')) == '') {
|
||||
unset($this->external[$ext]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->log('Cached '.sizeof($this->external).' commands.');
|
||||
}//end load_external()
|
||||
return $this->log('Cached ' . sizeof($this->external) . ' commands.');
|
||||
}
|
||||
|
||||
//end load_external()
|
||||
|
||||
private function init()
|
||||
{
|
||||
@ -149,20 +149,20 @@ class IRCBot
|
||||
$this->connect();
|
||||
$this->log('Connected');
|
||||
if ($this->pass) {
|
||||
fwrite($this->socket['irc'], 'PASS '.$this->pass."\n\r");
|
||||
fwrite($this->socket['irc'], 'PASS ' . $this->pass . "\n\r");
|
||||
}
|
||||
|
||||
$this->doAuth();
|
||||
while (true) {
|
||||
foreach ($this->socket as $n => $socket) {
|
||||
if (!is_resource($socket) || feof($socket)) {
|
||||
if (! is_resource($socket) || feof($socket)) {
|
||||
$this->log("Socket '$n' closed. Restarting.");
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->tempnick)) {
|
||||
$this->ircRaw('NICK '.$this->nick);
|
||||
$this->ircRaw('NICK ' . $this->nick);
|
||||
}
|
||||
|
||||
$this->getData();
|
||||
@ -179,32 +179,36 @@ class IRCBot
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
usleep($this->tick);
|
||||
}
|
||||
|
||||
return $this->init();
|
||||
}//end init()
|
||||
}
|
||||
|
||||
//end init()
|
||||
|
||||
private function connectAlert()
|
||||
{
|
||||
$f = $this->config['install_dir'].'/.ircbot.alert';
|
||||
if (( file_exists($f) && filetype($f) != 'fifo' && !unlink($f) ) || ( !file_exists($f) && !shell_exec("mkfifo $f && echo 1") )) {
|
||||
$f = $this->config['install_dir'] . '/.ircbot.alert';
|
||||
if ((file_exists($f) && filetype($f) != 'fifo' && ! unlink($f)) || (! file_exists($f) && ! shell_exec("mkfifo $f && echo 1"))) {
|
||||
$this->log('Error - Cannot create Alert-File');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (($this->socket['alert'] = fopen($f, 'r+'))) {
|
||||
$this->log('Opened Alert-File');
|
||||
stream_set_blocking($this->socket['alert'], false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->log('Error - Cannot open Alert-File');
|
||||
return false;
|
||||
}//end connect_alert()
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//end connect_alert()
|
||||
|
||||
private function read($buff)
|
||||
{
|
||||
@ -215,29 +219,30 @@ class IRCBot
|
||||
$tmp = explode("\n", $this->buff[$buff], 2);
|
||||
$this->buff[$buff] = substr($this->buff[$buff], (strlen($tmp[0]) + 1));
|
||||
if ($this->debug) {
|
||||
$this->log("Returning buffer '$buff': '".trim($tmp[0])."'");
|
||||
$this->log("Returning buffer '$buff': '" . trim($tmp[0]) . "'");
|
||||
}
|
||||
|
||||
return $tmp[0];
|
||||
}
|
||||
|
||||
if ($this->debug && $r > 0) {
|
||||
$this->log("Expanding buffer '$buff' = '".trim($this->buff[$buff])."'");
|
||||
$this->log("Expanding buffer '$buff' = '" . trim($this->buff[$buff]) . "'");
|
||||
}
|
||||
|
||||
return false;
|
||||
}//end read()
|
||||
}
|
||||
|
||||
//end read()
|
||||
|
||||
private function alertData()
|
||||
{
|
||||
if (($alert = $this->read('alert')) !== false) {
|
||||
$alert = json_decode($alert, true);
|
||||
if (!is_array($alert)) {
|
||||
if (! is_array($alert)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ($alert['state']) :
|
||||
switch ($alert['state']) {
|
||||
case AlertState::WORSE:
|
||||
$severity_extended = '+';
|
||||
break;
|
||||
@ -246,22 +251,22 @@ class IRCBot
|
||||
break;
|
||||
default:
|
||||
$severity_extended = '';
|
||||
endswitch;
|
||||
}
|
||||
|
||||
$severity = str_replace(array('warning', 'critical'), array($this->_color('Warning', 'yellow'), $this->_color('Critical', 'red')), $alert['severity']).$severity_extended.' ';
|
||||
$severity = str_replace(['warning', 'critical'], [$this->_color('Warning', 'yellow'), $this->_color('Critical', 'red')], $alert['severity']) . $severity_extended . ' ';
|
||||
if ($alert['state'] == AlertState::RECOVERED and $this->config['irc_alert_utf8']) {
|
||||
$severity = str_replace(array('Warning', 'Critical'), array('̶W̶a̶r̶n̶i̶n̶g', '̶C̶r̶i̶t̶i̶c̶a̶l'), $severity);
|
||||
$severity = str_replace(['Warning', 'Critical'], ['̶W̶a̶r̶n̶i̶n̶g', '̶C̶r̶i̶t̶i̶c̶a̶l'], $severity);
|
||||
}
|
||||
|
||||
if ($this->config['irc_alert_chan']) {
|
||||
foreach ($this->config['irc_alert_chan'] as $chan) {
|
||||
$this->ircRaw('PRIVMSG '.$chan.' :'.$severity.trim($alert['title']));
|
||||
if (!$this->config['irc_alert_short']) { // Only send the title if set to short
|
||||
$this->ircRaw('PRIVMSG ' . $chan . ' :' . $severity . trim($alert['title']));
|
||||
if (! $this->config['irc_alert_short']) { // Only send the title if set to short
|
||||
foreach (explode("\n", $alert['msg']) as $line) {
|
||||
// We don't need to repeat the title
|
||||
$line = strip_tags($line);
|
||||
if (trim($line) != trim($alert['title'])) {
|
||||
$this->ircRaw('PRIVMSG '.$chan.' :'.$line);
|
||||
$this->ircRaw('PRIVMSG ' . $chan . ' :' . $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -269,13 +274,13 @@ class IRCBot
|
||||
} else {
|
||||
foreach ($this->authd as $nick => $data) {
|
||||
if ($data['expire'] >= time()) {
|
||||
$this->ircRaw('PRIVMSG '.$nick.' :'.$severity.trim($alert['title']));
|
||||
if (!$this->config['irc_alert_short']) { // Only send the title if set to short
|
||||
$this->ircRaw('PRIVMSG ' . $nick . ' :' . $severity . trim($alert['title']));
|
||||
if (! $this->config['irc_alert_short']) { // Only send the title if set to short
|
||||
foreach (explode("\n", $alert['msg']) as $line) {
|
||||
// We don't need to repeat the title
|
||||
$line = strip_tags($line);
|
||||
if (trim($line) != trim($alert['title'])) {
|
||||
$this->ircRaw('PRIVMSG '.$nick.' :'.$line);
|
||||
$this->ircRaw('PRIVMSG ' . $nick . ' :' . $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -283,8 +288,9 @@ class IRCBot
|
||||
}
|
||||
}
|
||||
}//end if
|
||||
}//end alertData()
|
||||
}
|
||||
|
||||
//end alertData()
|
||||
|
||||
private function getData()
|
||||
{
|
||||
@ -293,7 +299,7 @@ class IRCBot
|
||||
$this->data = $data;
|
||||
$ex = explode(' ', $this->data);
|
||||
if ($ex[0] == 'PING') {
|
||||
return $this->ircRaw('PONG '.$ex[1]);
|
||||
return $this->ircRaw('PONG ' . $ex[1]);
|
||||
}
|
||||
|
||||
if ($ex[1] == 376 || $ex[1] == 422 || ($ex[1] == 'MODE' && $ex[2] == $this->nick)) {
|
||||
@ -303,25 +309,26 @@ class IRCBot
|
||||
}
|
||||
}
|
||||
|
||||
if (($this->config['irc_ctcp']) && (preg_match("/^:".chr(1).".*/", $ex[3]))) {
|
||||
if (($this->config['irc_ctcp']) && (preg_match("/^:" . chr(1) . ".*/", $ex[3]))) {
|
||||
// Handle CTCP
|
||||
$ctcp = trim(preg_replace("/[^A-Z]/", "", $ex[3]));
|
||||
$ctcp_reply = null;
|
||||
$this->log("Received irc CTCP: ".$ctcp." from ".$this->getUser($this->data));
|
||||
$this->log("Received irc CTCP: " . $ctcp . " from " . $this->getUser($this->data));
|
||||
switch ($ctcp) {
|
||||
case 'VERSION':
|
||||
$ctcp_reply = chr(1)."$ctcp ".$this->config['irc_ctcp_version'].chr(1);
|
||||
$ctcp_reply = chr(1) . "$ctcp " . $this->config['irc_ctcp_version'] . chr(1);
|
||||
break;
|
||||
case 'PING':
|
||||
$ctcp_reply = chr(1)."$ctcp ".$ex[4]. " ".$ex[5].chr(1);
|
||||
$ctcp_reply = chr(1) . "$ctcp " . $ex[4] . " " . $ex[5] . chr(1);
|
||||
break;
|
||||
case 'TIME':
|
||||
$ctcp_reply = chr(1)."$ctcp ".date('c').chr(1);
|
||||
$ctcp_reply = chr(1) . "$ctcp " . date('c') . chr(1);
|
||||
break;
|
||||
}
|
||||
if ($ctcp_reply !== null) {
|
||||
$this->log("Sending irc CTCP: ".'NOTICE '.$this->getUser($this->data)." :".$ctcp_reply);
|
||||
return $this->ircRaw('NOTICE '.$this->getUser($this->data)." :".$ctcp_reply);
|
||||
$this->log("Sending irc CTCP: " . 'NOTICE ' . $this->getUser($this->data) . " :" . $ctcp_reply);
|
||||
|
||||
return $this->ircRaw('NOTICE ' . $this->getUser($this->data) . " :" . $ctcp_reply);
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,22 +347,24 @@ class IRCBot
|
||||
if ($ex[2] != "*") {
|
||||
$this->tempnick = $ex[2];
|
||||
}
|
||||
if (!isset($this->tempnick)) {
|
||||
$this->tempnick = $this->nick.rand(0, 99);
|
||||
if (! isset($this->tempnick)) {
|
||||
$this->tempnick = $this->nick . rand(0, 99);
|
||||
}
|
||||
if ($this->debug) {
|
||||
$this->log("Using temp nick ".$this->tempnick);
|
||||
}
|
||||
return $this->ircRaw('NICK '.$this->tempnick);
|
||||
$this->log("Using temp nick " . $this->tempnick);
|
||||
}
|
||||
|
||||
$this->command = str_replace(array(chr(10), chr(13)), '', $ex[3]);
|
||||
return $this->ircRaw('NICK ' . $this->tempnick);
|
||||
}
|
||||
|
||||
$this->command = str_replace([chr(10), chr(13)], '', $ex[3]);
|
||||
if (strstr($this->command, ':.')) {
|
||||
$this->handleCommand();
|
||||
}
|
||||
}
|
||||
}//end getData()
|
||||
}
|
||||
|
||||
//end getData()
|
||||
|
||||
private function joinChan($chan = false)
|
||||
{
|
||||
@ -364,19 +373,20 @@ class IRCBot
|
||||
}
|
||||
|
||||
foreach ($this->chan as $chan) {
|
||||
$this->ircRaw('JOIN '.$chan);
|
||||
$this->ircRaw('JOIN ' . $chan);
|
||||
}
|
||||
|
||||
return true;
|
||||
}//end joinChan()
|
||||
}
|
||||
|
||||
//end joinChan()
|
||||
|
||||
private function handleCommand()
|
||||
{
|
||||
$this->command = str_replace(':.', '', $this->command);
|
||||
$tmp = explode(':.'.$this->command.' ', $this->data);
|
||||
$tmp = explode(':.' . $this->command . ' ', $this->data);
|
||||
$this->user = $this->getAuthdUser();
|
||||
if (!$this->isAuthd() && (isset($this->config['irc_auth']))) {
|
||||
if (! $this->isAuthd() && (isset($this->config['irc_auth']))) {
|
||||
$this->hostAuth();
|
||||
}
|
||||
if ($this->isAuthd() || trim($this->command) == 'auth') {
|
||||
@ -384,82 +394,98 @@ class IRCBot
|
||||
}
|
||||
|
||||
$this->authd[$this->getUser($this->data)] = $this->user;
|
||||
return false;
|
||||
}//end handleCommand()
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//end handleCommand()
|
||||
|
||||
private function proceedCommand($command, $params)
|
||||
{
|
||||
$command = strtolower($command);
|
||||
if (in_array($command, $this->commands)) {
|
||||
$this->chkdb();
|
||||
$this->log($command." ( '".$params."' )");
|
||||
return $this->{'_'.$command}($params);
|
||||
$this->log($command . " ( '" . $params . "' )");
|
||||
|
||||
return $this->{'_' . $command}($params);
|
||||
} elseif ($this->external[$command]) {
|
||||
$this->chkdb();
|
||||
$this->log($command." ( '".$params."' ) [Ext]");
|
||||
$this->log($command . " ( '" . $params . "' ) [Ext]");
|
||||
|
||||
return eval($this->external[$command]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}//end proceedCommand()
|
||||
}
|
||||
|
||||
//end proceedCommand()
|
||||
|
||||
private function respond($msg)
|
||||
{
|
||||
$chan = $this->getChan($this->data);
|
||||
return $this->sendMessage($msg, strstr($chan, '#') ? $chan : $this->getUser($this->data));
|
||||
}//end respond()
|
||||
|
||||
return $this->sendMessage($msg, strstr($chan, '#') ? $chan : $this->getUser($this->data));
|
||||
}
|
||||
|
||||
//end respond()
|
||||
|
||||
private function getChan($param)
|
||||
{
|
||||
$data = explode('PRIVMSG ', $this->data, 3);
|
||||
$data = explode(' ', $data[1], 2);
|
||||
return $data[0];
|
||||
}//end getChan()
|
||||
|
||||
return $data[0];
|
||||
}
|
||||
|
||||
//end getChan()
|
||||
|
||||
private function getUser($param)
|
||||
{
|
||||
$arrData = explode('!', $param, 2);
|
||||
|
||||
return str_replace(':', '', $arrData[0]);
|
||||
}//end getUser()
|
||||
}
|
||||
|
||||
//end getUser()
|
||||
|
||||
private function getUserHost($param)
|
||||
{
|
||||
$arrData = explode(' ', $param, 2);
|
||||
|
||||
return str_replace(':', '', $arrData[0]);
|
||||
}//end getUserHost()
|
||||
}
|
||||
|
||||
//end getUserHost()
|
||||
|
||||
private function connect($try = 0)
|
||||
{
|
||||
if ($try > $this->max_retry) {
|
||||
$this->log('Failed too many connection attempts, aborting');
|
||||
return die();
|
||||
|
||||
return exit();
|
||||
}
|
||||
|
||||
$this->log('Trying to connect ('.($try + 1).') to '.$this->server.':'.$this->port.($this->ssl ? ' (SSL)' : ''));
|
||||
$this->log('Trying to connect (' . ($try + 1) . ') to ' . $this->server . ':' . $this->port . ($this->ssl ? ' (SSL)' : ''));
|
||||
if ($this->socket['irc']) {
|
||||
$this->ircRaw('QUIT :Reloading');
|
||||
fclose($this->socket['irc']);
|
||||
}
|
||||
|
||||
if ($this->ssl) {
|
||||
$server = 'ssl://'.$this->server;
|
||||
$server = 'ssl://' . $this->server;
|
||||
} else {
|
||||
$server = $this->server;
|
||||
}
|
||||
|
||||
if ($this->ssl && $this->config['irc_disable_ssl_check']) {
|
||||
$ssl_context_params = array('ssl'=>array('allow_self_signed'=> true, 'verify_peer' => false, 'verify_peer_name' => false ));
|
||||
$ssl_context_params = ['ssl'=>['allow_self_signed'=> true, 'verify_peer' => false, 'verify_peer_name' => false]];
|
||||
$ssl_context = stream_context_create($ssl_context_params);
|
||||
$this->socket['irc'] = stream_socket_client($server.':'.$this->port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $ssl_context);
|
||||
$this->socket['irc'] = stream_socket_client($server . ':' . $this->port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $ssl_context);
|
||||
} else {
|
||||
$this->socket['irc'] = fsockopen($server, $this->port);
|
||||
}
|
||||
|
||||
if (!is_resource($this->socket['irc'])) {
|
||||
if (! is_resource($this->socket['irc'])) {
|
||||
if ($try < 5) {
|
||||
sleep(5);
|
||||
} elseif ($try < 10) {
|
||||
@ -467,70 +493,84 @@ class IRCBot
|
||||
} else {
|
||||
sleep(300);
|
||||
}
|
||||
|
||||
return $this->connect($try + 1);
|
||||
} else {
|
||||
stream_set_blocking($this->socket['irc'], false);
|
||||
|
||||
return true;
|
||||
}
|
||||
}//end connect()
|
||||
}
|
||||
|
||||
//end connect()
|
||||
|
||||
private function doAuth()
|
||||
{
|
||||
if ($this->ircRaw('USER '.$this->nick.' 0 '.$this->nick.' :'.$this->nick) && $this->ircRaw('NICK '.$this->nick)) {
|
||||
if ($this->ircRaw('USER ' . $this->nick . ' 0 ' . $this->nick . ' :' . $this->nick) && $this->ircRaw('NICK ' . $this->nick)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}//end doAuth()
|
||||
}
|
||||
|
||||
//end doAuth()
|
||||
|
||||
private function sendMessage($message, $chan)
|
||||
{
|
||||
if ($this->debug) {
|
||||
$this->log("Sending 'PRIVMSG ".trim($chan).' :'.trim($message)."'");
|
||||
$this->log("Sending 'PRIVMSG " . trim($chan) . ' :' . trim($message) . "'");
|
||||
}
|
||||
|
||||
return $this->ircRaw('PRIVMSG '.trim($chan).' :'.trim($message));
|
||||
}//end sendMessage()
|
||||
return $this->ircRaw('PRIVMSG ' . trim($chan) . ' :' . trim($message));
|
||||
}
|
||||
|
||||
//end sendMessage()
|
||||
|
||||
private function log($msg)
|
||||
{
|
||||
echo '['.date('r').'] '.trim($msg)."\n";
|
||||
return true;
|
||||
}//end log()
|
||||
echo '[' . date('r') . '] ' . trim($msg) . "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//end log()
|
||||
|
||||
private function chkdb()
|
||||
{
|
||||
if (!Eloquent::isConnected()) {
|
||||
if (! Eloquent::isConnected()) {
|
||||
try {
|
||||
Eloquent::boot();
|
||||
} catch (\PDOException $e) {
|
||||
$this->log('Cannot connect to MySQL: ' . $e->getMessage());
|
||||
return die();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}//end chkdb()
|
||||
|
||||
return exit();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//end chkdb()
|
||||
|
||||
private function isAuthd()
|
||||
{
|
||||
if ($this->user['expire'] >= time()) {
|
||||
$this->user['expire'] = (time() + ($this->config['irc_authtime'] * 3600));
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}//end isAuthd()
|
||||
}
|
||||
|
||||
//end isAuthd()
|
||||
|
||||
private function getAuthdUser()
|
||||
{
|
||||
return $this->authd[$this->getUser($this->data)];
|
||||
}//end getAuthUser()
|
||||
}
|
||||
|
||||
//end getAuthUser()
|
||||
|
||||
private function hostAuth()
|
||||
{
|
||||
@ -550,21 +590,25 @@ class IRCBot
|
||||
$this->user['ports'] = Permissions::portsForUser($this->user['id'])->toArray();
|
||||
}
|
||||
if ($this->debug) {
|
||||
$this->log("HostAuth on irc for '".$user['username']."', ID: '".$user_id."', Host: '".$host);
|
||||
$this->log("HostAuth on irc for '" . $user['username'] . "', ID: '" . $user_id . "', Host: '" . $host);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}//end hostAuth
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//end hostAuth
|
||||
|
||||
private function ircRaw($params)
|
||||
{
|
||||
return fputs($this->socket['irc'], $params."\r\n");
|
||||
}//end irc_raw()
|
||||
return fputs($this->socket['irc'], $params . "\r\n");
|
||||
}
|
||||
|
||||
//end irc_raw()
|
||||
|
||||
private function _auth($params)
|
||||
{
|
||||
@ -594,10 +638,10 @@ class IRCBot
|
||||
$this->user['name'] = $params[0];
|
||||
$this->user['id'] = $user['user_id'];
|
||||
if ($this->debug) {
|
||||
$this->log("Auth for '".$params[0]."', ID: '".$user['user_id']."', Token: '".$token."', Mail: '".$user['email']."'");
|
||||
$this->log("Auth for '" . $params[0] . "', ID: '" . $user['user_id'] . "', Token: '" . $token . "', Mail: '" . $user['email'] . "'");
|
||||
}
|
||||
|
||||
if (send_mail($user['email'], 'LibreNMS IRC-Bot Authtoken', "Your Authtoken for the IRC-Bot:\r\n\r\n".$token."\r\n\r\n") === true) {
|
||||
if (send_mail($user['email'], 'LibreNMS IRC-Bot Authtoken', "Your Authtoken for the IRC-Bot:\r\n\r\n" . $token . "\r\n\r\n") === true) {
|
||||
return $this->respond('Token sent!');
|
||||
} else {
|
||||
return $this->respond('Sorry, seems like mail doesnt like us.');
|
||||
@ -606,9 +650,11 @@ class IRCBot
|
||||
return $this->respond('Who are you again?');
|
||||
}
|
||||
}//end if
|
||||
return false;
|
||||
}//end _auth()
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//end _auth()
|
||||
|
||||
private function _reload()
|
||||
{
|
||||
@ -621,8 +667,9 @@ class IRCBot
|
||||
} else {
|
||||
return $this->respond('Permission denied.');
|
||||
}
|
||||
}//end _reload()
|
||||
}
|
||||
|
||||
//end _reload()
|
||||
|
||||
private function _join($params)
|
||||
{
|
||||
@ -631,30 +678,35 @@ class IRCBot
|
||||
} else {
|
||||
return $this->respond('Permission denied.');
|
||||
}
|
||||
}//end _join()
|
||||
}
|
||||
|
||||
//end _join()
|
||||
|
||||
private function _quit($params)
|
||||
{
|
||||
if ($this->user['level'] == 10) {
|
||||
$this->ircRaw("QUIT :Requested");
|
||||
return die();
|
||||
|
||||
return exit();
|
||||
} else {
|
||||
return $this->respond('Permission denied.');
|
||||
}
|
||||
}//end _quit()
|
||||
}
|
||||
|
||||
//end _quit()
|
||||
|
||||
private function _help($params)
|
||||
{
|
||||
foreach ($this->commands as $cmd) {
|
||||
$msg .= ', '.$cmd;
|
||||
$msg .= ', ' . $cmd;
|
||||
}
|
||||
|
||||
$msg = substr($msg, 2);
|
||||
return $this->respond("Available commands: $msg");
|
||||
}//end _help()
|
||||
|
||||
return $this->respond("Available commands: $msg");
|
||||
}
|
||||
|
||||
//end _help()
|
||||
|
||||
private function _version($params)
|
||||
{
|
||||
@ -662,10 +714,12 @@ class IRCBot
|
||||
$schema_version = $versions['db_schema'];
|
||||
$version = $versions['local_ver'];
|
||||
|
||||
$msg = $this->config['project_name'].', Version: '.$version.', DB schema: '.$schema_version.', PHP: '.PHP_VERSION;
|
||||
return $this->respond($msg);
|
||||
}//end _version()
|
||||
$msg = $this->config['project_name'] . ', Version: ' . $version . ', DB schema: ' . $schema_version . ', PHP: ' . PHP_VERSION;
|
||||
|
||||
return $this->respond($msg);
|
||||
}
|
||||
|
||||
//end _version()
|
||||
|
||||
private function _log($params)
|
||||
{
|
||||
@ -675,76 +729,81 @@ class IRCBot
|
||||
}
|
||||
|
||||
if ($this->user['level'] < 5) {
|
||||
$tmp = dbFetchRows('SELECT `event_id`,`device_id`,`datetime`,`message`,`type` FROM `eventlog` WHERE `device_id` IN ('.implode(',', $this->user['devices']).') ORDER BY `event_id` DESC LIMIT '. (int)$num);
|
||||
$tmp = dbFetchRows('SELECT `event_id`,`device_id`,`datetime`,`message`,`type` FROM `eventlog` WHERE `device_id` IN (' . implode(',', $this->user['devices']) . ') ORDER BY `event_id` DESC LIMIT ' . (int) $num);
|
||||
} else {
|
||||
$tmp = dbFetchRows('SELECT `event_id`,`device_id`,`datetime`,`message`,`type` FROM `eventlog` ORDER BY `event_id` DESC LIMIT '.(int)$num);
|
||||
$tmp = dbFetchRows('SELECT `event_id`,`device_id`,`datetime`,`message`,`type` FROM `eventlog` ORDER BY `event_id` DESC LIMIT ' . (int) $num);
|
||||
}
|
||||
|
||||
foreach ($tmp as $device) {
|
||||
$hostid = dbFetchRow('SELECT `hostname` FROM `devices` WHERE `device_id` = '.$device['device_id']);
|
||||
$this->respond($device['event_id'].' '.$hostid['hostname'].' '.$device['datetime'].' '.$device['message'].' '.$device['type']);
|
||||
$hostid = dbFetchRow('SELECT `hostname` FROM `devices` WHERE `device_id` = ' . $device['device_id']);
|
||||
$this->respond($device['event_id'] . ' ' . $hostid['hostname'] . ' ' . $device['datetime'] . ' ' . $device['message'] . ' ' . $device['type']);
|
||||
}
|
||||
|
||||
if (!$hostid) {
|
||||
if (! $hostid) {
|
||||
$this->respond('Nothing to see, maybe a bug?');
|
||||
}
|
||||
|
||||
return true;
|
||||
}//end _log()
|
||||
}
|
||||
|
||||
//end _log()
|
||||
|
||||
private function _down($params)
|
||||
{
|
||||
if ($this->user['level'] < 5) {
|
||||
$tmp = dbFetchRows('SELECT `hostname` FROM `devices` WHERE status=0 AND `device_id` IN ('.implode(',', $this->user['devices']).')');
|
||||
$tmp = dbFetchRows('SELECT `hostname` FROM `devices` WHERE status=0 AND `device_id` IN (' . implode(',', $this->user['devices']) . ')');
|
||||
} else {
|
||||
$tmp = dbFetchRows('SELECT `hostname` FROM `devices` WHERE status=0');
|
||||
}
|
||||
|
||||
foreach ($tmp as $db) {
|
||||
if ($db['hostname']) {
|
||||
$msg .= ', '.$db['hostname'];
|
||||
$msg .= ', ' . $db['hostname'];
|
||||
}
|
||||
}
|
||||
|
||||
$msg = substr($msg, 2);
|
||||
$msg = $msg ? $msg : 'Nothing to show :)';
|
||||
return $this->respond($msg);
|
||||
}//end _down()
|
||||
|
||||
return $this->respond($msg);
|
||||
}
|
||||
|
||||
//end _down()
|
||||
|
||||
private function _device($params)
|
||||
{
|
||||
$params = explode(' ', $params);
|
||||
$hostname = $params[0];
|
||||
$device = dbFetchRow('SELECT * FROM `devices` WHERE `hostname` = ?', array($hostname));
|
||||
if (!$device) {
|
||||
$device = dbFetchRow('SELECT * FROM `devices` WHERE `hostname` = ?', [$hostname]);
|
||||
if (! $device) {
|
||||
return $this->respond('Error: Bad or Missing hostname, use .listdevices to show all devices.');
|
||||
}
|
||||
|
||||
if ($this->user['level'] < 5 && !in_array($device['device_id'], $this->user['devices'])) {
|
||||
if ($this->user['level'] < 5 && ! in_array($device['device_id'], $this->user['devices'])) {
|
||||
return $this->respond('Error: Permission denied.');
|
||||
}
|
||||
|
||||
$status = $device['status'] ? 'Up '.formatUptime($device['uptime']) : 'Down';
|
||||
$status = $device['status'] ? 'Up ' . formatUptime($device['uptime']) : 'Down';
|
||||
$status .= $device['ignore'] ? '*Ignored*' : '';
|
||||
$status .= $device['disabled'] ? '*Disabled*' : '';
|
||||
return $this->respond($device['os'].' '.$device['version'].' '.$device['features'].' '.$status);
|
||||
}//end _device()
|
||||
|
||||
return $this->respond($device['os'] . ' ' . $device['version'] . ' ' . $device['features'] . ' ' . $status);
|
||||
}
|
||||
|
||||
//end _device()
|
||||
|
||||
private function _port($params)
|
||||
{
|
||||
$params = explode(' ', $params);
|
||||
$hostname = $params[0];
|
||||
$ifname = $params[1];
|
||||
if (!$hostname || !$ifname) {
|
||||
if (! $hostname || ! $ifname) {
|
||||
return $this->respond('Error: Missing hostname or ifname.');
|
||||
}
|
||||
|
||||
$device = dbFetchRow('SELECT * FROM `devices` WHERE `hostname` = ?', array($hostname));
|
||||
$port = dbFetchRow('SELECT * FROM `ports` WHERE (`ifName` = ? OR `ifDescr` = ?) AND device_id = ?', array($ifname, $ifname, $device['device_id']));
|
||||
if ($this->user['level'] < 5 && !in_array($port['port_id'], $this->user['ports']) && !in_array($device['device_id'], $this->user['devices'])) {
|
||||
$device = dbFetchRow('SELECT * FROM `devices` WHERE `hostname` = ?', [$hostname]);
|
||||
$port = dbFetchRow('SELECT * FROM `ports` WHERE (`ifName` = ? OR `ifDescr` = ?) AND device_id = ?', [$ifname, $ifname, $device['device_id']]);
|
||||
if ($this->user['level'] < 5 && ! in_array($port['port_id'], $this->user['ports']) && ! in_array($device['device_id'], $this->user['devices'])) {
|
||||
return $this->respond('Error: Permission denied.');
|
||||
}
|
||||
|
||||
@ -752,48 +811,52 @@ class IRCBot
|
||||
$bps_out = formatRates($port['ifOutOctets_rate'] * 8);
|
||||
$pps_in = format_bi($port['ifInUcastPkts_rate']);
|
||||
$pps_out = format_bi($port['ifOutUcastPkts_rate']);
|
||||
return $this->respond($port['ifAdminStatus'].'/'.$port['ifOperStatus'].' '.$bps_in.' > bps > '.$bps_out.' | '.$pps_in.'pps > PPS > '.$pps_out.'pps');
|
||||
}//end _port()
|
||||
|
||||
return $this->respond($port['ifAdminStatus'] . '/' . $port['ifOperStatus'] . ' ' . $bps_in . ' > bps > ' . $bps_out . ' | ' . $pps_in . 'pps > PPS > ' . $pps_out . 'pps');
|
||||
}
|
||||
|
||||
//end _port()
|
||||
|
||||
private function _listdevices($params)
|
||||
{
|
||||
if ($this->user['level'] < 5) {
|
||||
$tmp = dbFetchRows('SELECT `hostname` FROM `devices` WHERE `device_id` IN ('.implode(',', $this->user['devices']).')');
|
||||
$tmp = dbFetchRows('SELECT `hostname` FROM `devices` WHERE `device_id` IN (' . implode(',', $this->user['devices']) . ')');
|
||||
} else {
|
||||
$tmp = dbFetchRows('SELECT `hostname` FROM `devices`');
|
||||
}
|
||||
|
||||
foreach ($tmp as $device) {
|
||||
$msg .= ', '.$device['hostname'];
|
||||
$msg .= ', ' . $device['hostname'];
|
||||
}
|
||||
|
||||
$msg = substr($msg, 2);
|
||||
$msg = $msg ? $msg : 'Nothing to show..?';
|
||||
return $this->respond($msg);
|
||||
}//end _listdevices()
|
||||
|
||||
return $this->respond($msg);
|
||||
}
|
||||
|
||||
//end _listdevices()
|
||||
|
||||
private function _status($params)
|
||||
{
|
||||
$params = explode(' ', $params);
|
||||
$statustype = $params[0];
|
||||
if ($this->user['level'] < 5) {
|
||||
$d_w = ' WHERE device_id IN ('.implode(',', $this->user['devices']).')';
|
||||
$d_a = ' AND device_id IN ('.implode(',', $this->user['devices']).')';
|
||||
$p_w = ' WHERE port_id IN ('.implode(',', $this->user['ports']).') OR device_id IN ('.implode(',', $this->user['devices']).')';
|
||||
$p_a = ' AND (I.port_id IN ('.implode(',', $this->user['ports']).') OR I.device_id IN ('.implode(',', $this->user['devices']).'))';
|
||||
$d_w = ' WHERE device_id IN (' . implode(',', $this->user['devices']) . ')';
|
||||
$d_a = ' AND device_id IN (' . implode(',', $this->user['devices']) . ')';
|
||||
$p_w = ' WHERE port_id IN (' . implode(',', $this->user['ports']) . ') OR device_id IN (' . implode(',', $this->user['devices']) . ')';
|
||||
$p_a = ' AND (I.port_id IN (' . implode(',', $this->user['ports']) . ') OR I.device_id IN (' . implode(',', $this->user['devices']) . '))';
|
||||
}
|
||||
|
||||
switch ($statustype) {
|
||||
case 'devices':
|
||||
case 'device':
|
||||
case 'dev':
|
||||
$devcount = dbFetchCell('SELECT count(*) FROM devices'.$d_w);
|
||||
$devup = dbFetchCell("SELECT count(*) FROM devices WHERE status = '1' AND `ignore` = '0'".$d_a);
|
||||
$devdown = dbFetchCell("SELECT count(*) FROM devices WHERE status = '0' AND `ignore` = '0'".$d_a);
|
||||
$devign = dbFetchCell("SELECT count(*) FROM devices WHERE `ignore` = '1'".$d_a);
|
||||
$devdis = dbFetchCell("SELECT count(*) FROM devices WHERE `disabled` = '1'".$d_a);
|
||||
$devcount = dbFetchCell('SELECT count(*) FROM devices' . $d_w);
|
||||
$devup = dbFetchCell("SELECT count(*) FROM devices WHERE status = '1' AND `ignore` = '0'" . $d_a);
|
||||
$devdown = dbFetchCell("SELECT count(*) FROM devices WHERE status = '0' AND `ignore` = '0'" . $d_a);
|
||||
$devign = dbFetchCell("SELECT count(*) FROM devices WHERE `ignore` = '1'" . $d_a);
|
||||
$devdis = dbFetchCell("SELECT count(*) FROM devices WHERE `disabled` = '1'" . $d_a);
|
||||
if ($devup > 0) {
|
||||
$devup = $this->_color($devup, 'green');
|
||||
}
|
||||
@ -803,17 +866,17 @@ class IRCBot
|
||||
} else {
|
||||
$devcount = $this->_color($devcount, 'green', null, 'bold');
|
||||
}
|
||||
$msg = 'Devices: '.$devcount.' ('.$devup.' up, '.$devdown.' down, '.$devign.' ignored, '.$devdis.' disabled'.')';
|
||||
$msg = 'Devices: ' . $devcount . ' (' . $devup . ' up, ' . $devdown . ' down, ' . $devign . ' ignored, ' . $devdis . ' disabled' . ')';
|
||||
break;
|
||||
|
||||
case 'ports':
|
||||
case 'port':
|
||||
case 'prt':
|
||||
$prtcount = dbFetchCell('SELECT count(*) FROM ports'.$p_w);
|
||||
$prtup = dbFetchCell("SELECT count(*) FROM ports AS I, devices AS D WHERE I.ifOperStatus = 'up' AND I.ignore = '0' AND I.device_id = D.device_id AND D.ignore = '0'".$p_a);
|
||||
$prtdown = dbFetchCell("SELECT count(*) FROM ports AS I, devices AS D WHERE I.ifOperStatus = 'down' AND I.ifAdminStatus = 'up' AND I.ignore = '0' AND D.device_id = I.device_id AND D.ignore = '0'".$p_a);
|
||||
$prtsht = dbFetchCell("SELECT count(*) FROM ports AS I, devices AS D WHERE I.ifAdminStatus = 'down' AND I.ignore = '0' AND D.device_id = I.device_id AND D.ignore = '0'".$p_a);
|
||||
$prtign = dbFetchCell("SELECT count(*) FROM ports AS I, devices AS D WHERE D.device_id = I.device_id AND (I.ignore = '1' OR D.ignore = '1')".$p_a);
|
||||
$prtcount = dbFetchCell('SELECT count(*) FROM ports' . $p_w);
|
||||
$prtup = dbFetchCell("SELECT count(*) FROM ports AS I, devices AS D WHERE I.ifOperStatus = 'up' AND I.ignore = '0' AND I.device_id = D.device_id AND D.ignore = '0'" . $p_a);
|
||||
$prtdown = dbFetchCell("SELECT count(*) FROM ports AS I, devices AS D WHERE I.ifOperStatus = 'down' AND I.ifAdminStatus = 'up' AND I.ignore = '0' AND D.device_id = I.device_id AND D.ignore = '0'" . $p_a);
|
||||
$prtsht = dbFetchCell("SELECT count(*) FROM ports AS I, devices AS D WHERE I.ifAdminStatus = 'down' AND I.ignore = '0' AND D.device_id = I.device_id AND D.ignore = '0'" . $p_a);
|
||||
$prtign = dbFetchCell("SELECT count(*) FROM ports AS I, devices AS D WHERE D.device_id = I.device_id AND (I.ignore = '1' OR D.ignore = '1')" . $p_a);
|
||||
// $prterr = dbFetchCell("SELECT count(*) FROM ports AS I, devices AS D WHERE D.device_id = I.device_id AND (I.ignore = '0' OR D.ignore = '0') AND (I.ifInErrors_delta > '0' OR I.ifOutErrors_delta > '0')".$p_a);
|
||||
if ($prtup > 0) {
|
||||
$prtup = $this->_color($prtup, 'green');
|
||||
@ -824,17 +887,17 @@ class IRCBot
|
||||
} else {
|
||||
$prtcount = $this->_color($prtcount, 'green', null, 'bold');
|
||||
}
|
||||
$msg = 'Ports: '.$prtcount.' ('.$prtup.' up, '.$prtdown.' down, '.$prtign.' ignored, '.$prtsht.' shutdown'.')';
|
||||
$msg = 'Ports: ' . $prtcount . ' (' . $prtup . ' up, ' . $prtdown . ' down, ' . $prtign . ' ignored, ' . $prtsht . ' shutdown' . ')';
|
||||
break;
|
||||
|
||||
case 'services':
|
||||
case 'service':
|
||||
case 'srv':
|
||||
$status_counts = array();
|
||||
$status_colors = array(0 => 'green', 3 => 'lightblue', 1 => 'yellow', 2 => 'red');
|
||||
$srvcount = dbFetchCell('SELECT COUNT(*) FROM services'.$d_w);
|
||||
$srvign = dbFetchCell("SELECT COUNT(*) FROM services WHERE service_ignore = 1".$d_a);
|
||||
$srvdis = dbFetchCell("SELECT COUNT(*) FROM services WHERE service_disabled = 1".$d_a);
|
||||
$status_counts = [];
|
||||
$status_colors = [0 => 'green', 3 => 'lightblue', 1 => 'yellow', 2 => 'red'];
|
||||
$srvcount = dbFetchCell('SELECT COUNT(*) FROM services' . $d_w);
|
||||
$srvign = dbFetchCell("SELECT COUNT(*) FROM services WHERE service_ignore = 1" . $d_a);
|
||||
$srvdis = dbFetchCell("SELECT COUNT(*) FROM services WHERE service_disabled = 1" . $d_a);
|
||||
$service_status = dbFetchRows("SELECT `service_status`, COUNT(*) AS `count` FROM `services` WHERE `service_disabled`=0 AND `service_ignore`=0 $d_a GROUP BY `service_status`");
|
||||
$service_status = array_column($service_status, 'count', 'service_status'); // key by status
|
||||
|
||||
@ -856,11 +919,13 @@ class IRCBot
|
||||
}//end switch
|
||||
|
||||
return $this->respond($msg);
|
||||
}//end _status()
|
||||
}
|
||||
|
||||
//end _status()
|
||||
|
||||
private function _color($text, $fg_color, $bg_color = null, $other = null)
|
||||
{
|
||||
$colors = array(
|
||||
$colors = [
|
||||
'white' => "00",
|
||||
'black' => "01",
|
||||
'blue' => "02",
|
||||
@ -877,12 +942,12 @@ class IRCBot
|
||||
'pink' => "13",
|
||||
'grey' => "14",
|
||||
'lightgrey' => "15",
|
||||
);
|
||||
];
|
||||
$ret = chr(3);
|
||||
if (array_key_exists($fg_color, $colors)) {
|
||||
$ret .= $colors[$fg_color];
|
||||
if (array_key_exists($bg_color, $colors)) {
|
||||
$ret .= ",".$colors[$fg_color];
|
||||
$ret .= "," . $colors[$fg_color];
|
||||
}
|
||||
}
|
||||
switch ($other) {
|
||||
@ -899,6 +964,9 @@ class IRCBot
|
||||
}
|
||||
$ret .= $text;
|
||||
$ret .= chr(15);
|
||||
|
||||
return $ret;
|
||||
}// end _color
|
||||
}
|
||||
|
||||
// end _color
|
||||
}//end class
|
||||
|
@ -30,14 +30,14 @@ interface Datastore
|
||||
/**
|
||||
* Check if this is enabled by the configuration
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public static function isEnabled();
|
||||
|
||||
/**
|
||||
* Checks if the datastore wants rrdtags to be sent when issuing put()
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function wantsRrdTags();
|
||||
|
||||
|
@ -11,10 +11,11 @@ abstract class Model
|
||||
{
|
||||
$instance = new static();
|
||||
$instance->fill($data);
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
protected function fill(array $data = array())
|
||||
protected function fill(array $data = [])
|
||||
{
|
||||
foreach ($data as $field => $value) {
|
||||
$this->$field = $value;
|
||||
@ -31,10 +32,10 @@ abstract class Model
|
||||
* @param array $unique_fields fields to search for an existing entry
|
||||
* @param array $ignored_update_fields Don't compare these field when updating
|
||||
*/
|
||||
final public static function sync($device_id, array $models, $unique_fields = array(), $ignored_update_fields = array())
|
||||
final public static function sync($device_id, array $models, $unique_fields = [], $ignored_update_fields = [])
|
||||
{
|
||||
// save and collect valid ids
|
||||
$valid_ids = array();
|
||||
$valid_ids = [];
|
||||
foreach ($models as $model) {
|
||||
/** @var $this $model */
|
||||
if ($model->isValid()) {
|
||||
@ -57,10 +58,10 @@ abstract class Model
|
||||
$table = static::$table;
|
||||
$key = static::$primaryKey;
|
||||
|
||||
$params = array($device_id);
|
||||
$params = [$device_id];
|
||||
$where = '`device_id`=?';
|
||||
|
||||
if (!empty($model_ids)) {
|
||||
if (! empty($model_ids)) {
|
||||
$where .= " AND `$key` NOT IN " . dbGenPlaceholders(count($model_ids));
|
||||
$params = array_merge($params, $model_ids);
|
||||
}
|
||||
@ -69,7 +70,7 @@ abstract class Model
|
||||
foreach ($rows as $row) {
|
||||
static::onDelete(static::create($row));
|
||||
}
|
||||
if (!empty($rows)) {
|
||||
if (! empty($rows)) {
|
||||
dbDelete($table, $where, $params);
|
||||
}
|
||||
}
|
||||
@ -81,23 +82,23 @@ abstract class Model
|
||||
* @param array $ignored_update_fields Don't compare these field when updating
|
||||
* @return int the id of this model in the database
|
||||
*/
|
||||
final public function save($unique_fields = array(), $ignored_update_fields = array())
|
||||
final public function save($unique_fields = [], $ignored_update_fields = [])
|
||||
{
|
||||
$db_model = $this->fetch($unique_fields);
|
||||
$key = static::$primaryKey;
|
||||
|
||||
if ($db_model) {
|
||||
$new_model = $this->toArray(array_merge(array($key), $ignored_update_fields));
|
||||
$new_model = $this->toArray(array_merge([$key], $ignored_update_fields));
|
||||
$update = array_diff($new_model, $db_model);
|
||||
|
||||
if (empty($update)) {
|
||||
static::onNoUpdate();
|
||||
} else {
|
||||
dbUpdate($update, static::$table, "`$key`=?", array($this->$key));
|
||||
dbUpdate($update, static::$table, "`$key`=?", [$this->$key]);
|
||||
static::onUpdate($this);
|
||||
}
|
||||
} else {
|
||||
$new_model = $this->toArray(array($key));
|
||||
$new_model = $this->toArray([$key]);
|
||||
$this->$key = dbInsert($new_model, static::$table);
|
||||
if ($this->$key !== null) {
|
||||
static::onCreate($this);
|
||||
@ -114,7 +115,7 @@ abstract class Model
|
||||
* @param array $unique_fields fields to search for an existing entry
|
||||
* @return array|null
|
||||
*/
|
||||
protected function fetch($unique_fields = array())
|
||||
protected function fetch($unique_fields = [])
|
||||
{
|
||||
$table = static::$table;
|
||||
$key = static::$primaryKey;
|
||||
@ -122,12 +123,12 @@ abstract class Model
|
||||
if (isset($this->id)) {
|
||||
return dbFetchRow(
|
||||
"SELECT `$table` FROM ? WHERE `$key`=?",
|
||||
array($this->$key)
|
||||
[$this->$key]
|
||||
);
|
||||
}
|
||||
|
||||
$where = array();
|
||||
$params = array();
|
||||
$where = [];
|
||||
$params = [];
|
||||
foreach ($unique_fields as $field) {
|
||||
if (isset($this->$field)) {
|
||||
$where[] = " $field=?";
|
||||
@ -145,6 +146,7 @@ abstract class Model
|
||||
);
|
||||
|
||||
$this->$key = $row[$key];
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
@ -154,7 +156,7 @@ abstract class Model
|
||||
* @param array $exclude Exclude the listed fields
|
||||
* @return array
|
||||
*/
|
||||
abstract public function toArray($exclude = array());
|
||||
abstract public function toArray($exclude = []);
|
||||
|
||||
/**
|
||||
* Returns if this model passes validation and should be saved to the database
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user