Better handling of some alerting errors (#13446)

* Better handling of some alerting errors

* Better error output

* Consolidate simple template parsing

* Fixes reported by phpstan (one was a bug, yay!)

* add back forgotten trim

* don't remove the template if there is no match

* Match previous behavior, which was inconsistent.

* use anonymous class for tests instead

* Oopsie, Stringable is PHP8+

* fix style
This commit is contained in:
Tony Murray
2021-10-29 22:12:20 -05:00
committed by GitHub
parent 99d2462b80
commit 2c77edf4d2
12 changed files with 187 additions and 124 deletions

View File

@@ -93,19 +93,19 @@ class AlertUtil
$uids = [];
foreach ($results as $result) {
$tmp = null;
if (is_numeric($result['bill_id'])) {
if (isset($result['bill_id']) && is_numeric($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'])) {
if (isset($result['port_id']) && is_numeric($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'];
}
}
if (is_numeric($result['device_id'])) {
if (isset($result['device_id']) && 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 = ?", [$result['device_id']]);

View File

@@ -65,12 +65,12 @@ abstract class Transport implements TransportInterface
* @param string $input
* @return array
*/
protected function parseUserOptions($input)
protected function parseUserOptions(string $input): array
{
$options = [];
foreach (explode(PHP_EOL, $input) as $option) {
foreach (preg_split('/\\r\\n|\\r|\\n/', $input, -1, PREG_SPLIT_NO_EMPTY) as $option) {
if (Str::contains($option, '=')) {
[$k,$v] = explode('=', $option, 2);
[$k, $v] = explode('=', $option, 2);
$options[$k] = trim($v);
}
}

View File

@@ -24,6 +24,7 @@
namespace LibreNMS\Alert\Transport;
use App\View\SimpleTemplate;
use LibreNMS\Alert\Transport;
use LibreNMS\Util\Proxy;
@@ -46,31 +47,14 @@ class Api extends Transport
private function contactAPI($obj, $api, $options, $method, $auth, $headers, $body)
{
$request_opts = [];
$request_heads = [];
$query = [];
$method = strtolower($method);
$host = explode('?', $api, 2)[0]; //we don't use the parameter part, cause we build it out of options.
//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) {
[$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);
}
//store the parameter in the array for HTTP headers
$request_heads[$u_key] = $u_val;
}
$request_heads = $this->parseUserOptions(SimpleTemplate::parse($headers, $obj));
//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) {
[$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);
}
//store the parameter in the array for HTTP query
$query[$u_key] = $u_val;
}
$query = $this->parseUserOptions(SimpleTemplate::parse($options, $obj));
$client = new \GuzzleHttp\Client();
$request_opts['proxy'] = Proxy::forGuzzle();
@@ -89,10 +73,7 @@ class Api extends Transport
$res = $client->request('PUT', $host, $request_opts);
} else { //Method POST
$request_opts['query'] = $query;
foreach ($obj as $metric => $value) {
$body = str_replace('{{ $' . $metric . ' }}', $value, $body);
}
$request_opts['body'] = $body;
$request_opts['body'] = SimpleTemplate::parse($body, $obj);
$res = $client->request('POST', $host, $request_opts);
}

View File

@@ -23,6 +23,7 @@
namespace LibreNMS\Alert\Transport;
use App\View\SimpleTemplate;
use LibreNMS\Alert\Transport;
use LibreNMS\Util\Proxy;
@@ -51,9 +52,7 @@ class Matrix extends Transport
$request_heads['Content-Type'] = 'application/json';
$request_heads['Accept'] = 'application/json';
foreach ($obj as $p_key => $p_val) {
$message = str_replace('{{ $' . $p_key . ' }}', $p_val, $message);
}
$message = SimpleTemplate::parse($message, $obj);
$body = ['body'=>$message, 'msgtype'=>'m.text'];

View File

@@ -28,6 +28,8 @@ use LibreNMS\Util\Proxy;
class Rocket extends Transport
{
protected $name = 'Rocket Chat';
public function deliverAlert($obj, $opts)
{
$rocket_opts = $this->parseUserOptions($this->config['rocket-options']);
@@ -51,10 +53,10 @@ class Rocket extends Transport
'text' => $rocket_msg,
],
],
'channel' => $api['channel'],
'username' => $api['username'],
'icon_url' => $api['icon_url'],
'icon_emoji' => $api['icon_emoji'],
'channel' => $api['channel'] ?? null,
'username' => $api['username'] ?? null,
'icon_url' => $api['icon_url'] ?? null,
'icon_emoji' => $api['icon_emoji'] ?? null,
];
$alert_message = json_encode($data);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);