mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Refactor Api transport to use Guzzle (and new variables syntax) (#10070)
* Allow new {{ $xxxx }} syntax * Properly handle urlencode on variable values without braking the URL, and uses Blades * Doc Doc typo * use Guzzle for HTTP requests * Add Basic auth support * Doc update * clean * Revert Blades, but keep the {{ $xxxx }} syntax * Revert Blades, but keep the {{ $xxxx }} syntax * Init Vars and comments * Notifications * api-options are not required * Update notifications.rss
This commit is contained in:
committed by
Neil Lathwood
parent
fce185b55c
commit
55f67f42fe
@@ -16,6 +16,7 @@
|
||||
/**
|
||||
* API Transport
|
||||
* @author f0o <f0o@devilcode.org>
|
||||
* @author PipoCanaja (github.com/PipoCanaja)
|
||||
* @copyright 2014 f0o, LibreNMS
|
||||
* @license GPL
|
||||
* @package LibreNMS
|
||||
@@ -25,42 +26,62 @@
|
||||
namespace LibreNMS\Alert\Transport;
|
||||
|
||||
use LibreNMS\Alert\Transport;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Api extends Transport
|
||||
{
|
||||
public function deliverAlert($obj, $opts)
|
||||
{
|
||||
$url = $this->config['api-url'];
|
||||
$options = $this->config['api-options'];
|
||||
$method = $this->config['api-method'];
|
||||
return $this->contactAPI($obj, $url, $method);
|
||||
$auth = [$this->config['api-auth-username'], $this->config['api-auth-password']];
|
||||
return $this->contactAPI($obj, $url, $options, $method, $auth);
|
||||
}
|
||||
|
||||
private function contactAPI($obj, $api, $method)
|
||||
private function contactAPI($obj, $api, $options, $method, $auth)
|
||||
{
|
||||
$request_opts = [];
|
||||
$query = [];
|
||||
|
||||
$method = strtolower($method);
|
||||
list($host, $api) = explode("?", $api, 2);
|
||||
foreach ($obj as $k => $v) {
|
||||
$api = str_replace("%" . $k, $method == "get" ? urlencode($v) : $v, $api);
|
||||
}
|
||||
// var_dump($api); //FIXME: propper debuging
|
||||
$curl = curl_init();
|
||||
set_curl_proxy($curl);
|
||||
curl_setopt($curl, CURLOPT_URL, ($method == "get" ? $host."?".$api : $host));
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));
|
||||
if (json_decode($api) !== null) {
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
|
||||
}
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $api);
|
||||
$ret = curl_exec($curl);
|
||||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
if ($code != 200) {
|
||||
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;
|
||||
$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;
|
||||
foreach (preg_split("/\\r\\n|\\r|\\n/", $options) as $current_line) {
|
||||
list($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;
|
||||
}
|
||||
|
||||
$client = new \GuzzleHttp\Client();
|
||||
if (isset($auth) && !empty($auth[0])) {
|
||||
$request_opts['auth'] = $auth;
|
||||
}
|
||||
if ($method == "get") {
|
||||
$request_opts['query'] = $query;
|
||||
$res = $client->request('GET', $host, $request_opts);
|
||||
} else { //Method POST
|
||||
$request_opts['form_params'] = $query;
|
||||
$res = $client->request('POST', $host, $request_opts);
|
||||
}
|
||||
|
||||
$code = $res->getStatusCode();
|
||||
if ($code != 200) {
|
||||
var_dump("API '$host' returned Error");
|
||||
var_dump("Params:");
|
||||
var_dump($query);
|
||||
var_dump("Response headers:");
|
||||
var_dump($res->getHeaders());
|
||||
var_dump("Return: ".$res->getReasonPhrase());
|
||||
return 'HTTP Status code '.$code;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -83,6 +104,24 @@ class Api extends Transport
|
||||
'name' => 'api-url',
|
||||
'descr' => 'API URL',
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Options',
|
||||
'name' => 'api-options',
|
||||
'descr' => 'Enter the options (format: option=value separated by new lines)',
|
||||
'type' => 'textarea',
|
||||
],
|
||||
[
|
||||
'title' => 'Auth Username',
|
||||
'name' => 'api-auth-username',
|
||||
'descr' => 'Auth Username',
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'title' => 'Auth Password',
|
||||
'name' => 'api-auth-password',
|
||||
'descr' => 'Auth Password',
|
||||
'type' => 'password',
|
||||
]
|
||||
],
|
||||
'validation' => [
|
||||
|
@@ -60,31 +60,32 @@ entered as a new line.
|
||||
| Config | Example |
|
||||
| ------ | ------- |
|
||||
| Alertmanager URL | http://alertmanager.example.com |
|
||||
| Alertmanager Options: | source=librenms |
|
||||
| | customlabel=value |
|
||||
| Alertmanager Options: | source=librenms <br/> customlabel=value |
|
||||
|
||||
## API
|
||||
|
||||
API transports definitions are a bit more complex than the E-Mail configuration.
|
||||
API transports definitions are a bit more complex than the E-Mail configuration. It
|
||||
allows to reach any service provider using POST or GET URLs (Like SMS provider, etc).
|
||||
|
||||
The URL can have the same placeholders as defined in the [Template-Syntax](Templates.md#syntax).
|
||||
|
||||
If the `Api Method` is `get`, all placeholders will be URL-Encoded.
|
||||
|
||||
The API transport uses cURL to call the APIs, therefore you might need
|
||||
to install `php curl` to make it work.
|
||||
The API-Option field can have the same placeholders as defined in the
|
||||
[Template-Syntax](Templates.md#syntax).
|
||||
|
||||
__Note__: it is highly recommended to define your own
|
||||
[Templates](Templates.md) when you want to use the API transport. The
|
||||
default template might exceed URL-length for GET requests and
|
||||
therefore cause all sorts of errors.
|
||||
[Templates](Templates.md) when you want to use the API transport.
|
||||
You have to be carefull with length (for HTTP GET requests) and
|
||||
should adapt to the Service Provider limits.
|
||||
|
||||
**Example:**
|
||||
|
||||
The exemple below will use the API named sms-api of my.example.com and send the title of the alert to the provided number using the provided service key. Refer to your service documentation to configure it properly.
|
||||
|
||||
| Config | Example |
|
||||
| ------ | ------- |
|
||||
| API Method | get |
|
||||
| API URL | http://my.example.com/api |
|
||||
| API Method | get |
|
||||
| API URL | http://my.example.com/sms-api
|
||||
| API Options | rcpt=0123456789 <br/> key=0987654321abcdef <br/> msg=(LNMS) {{ $title }} |
|
||||
| API Username | myUsername |
|
||||
| API Password | myPassword |
|
||||
|
||||
## Boxcar
|
||||
|
||||
@@ -211,9 +212,7 @@ for details on acceptable values.
|
||||
| API URL | https://api.hipchat.com/v1/rooms/message?auth_token=109jawregoaihj |
|
||||
| Room ID | 7654321 |
|
||||
| From Name | LibreNMS |
|
||||
| Options | color = red |
|
||||
| | notify = 1 |
|
||||
| | message_format = text |
|
||||
| Options | color = red <br/> notify = 1 <br/> message_format = text |
|
||||
|
||||
At present the following options are supported: `color`, `notify` and `message_format`.
|
||||
|
||||
@@ -430,9 +429,7 @@ Application and setup the transport.
|
||||
| ------ | ------- |
|
||||
| Api Key | APPLICATIONAPIKEYGOESHERE |
|
||||
| User Key | USERKEYGOESHERE |
|
||||
| Pushover Options | sound_critical=falling |
|
||||
| | sound_warning=siren |
|
||||
| | sound_ok=magic |
|
||||
| Pushover Options | sound_critical=falling <br/> sound_warning=siren <br/> sound_ok=magic |
|
||||
|
||||
## Rocket.chat
|
||||
|
||||
@@ -448,10 +445,7 @@ required value is for url, without this then no call to Rocket.chat will be made
|
||||
| Config | Example |
|
||||
| ------ | ------- |
|
||||
| Webhook URL | https://rocket.url/api/v1/chat.postMessage |
|
||||
| Rocket.chat Options | channel=#Alerting |
|
||||
| | username=myname |
|
||||
| | icon_url=http://someurl/image.gif |
|
||||
| | icon_emoji=:smirk: |
|
||||
| Rocket.chat Options | channel=#Alerting <br/> username=myname <br/> icon_url=http://someurl/image.gif <br/> icon_emoji=:smirk: |
|
||||
|
||||
## Slack
|
||||
|
||||
@@ -491,8 +485,7 @@ either local or international dialling format.
|
||||
| SMSEagle Host | ip.add.re.ss |
|
||||
| User | smseagle_user |
|
||||
| Password | smseagle_user_password |
|
||||
| Mobiles | +3534567890 |
|
||||
| | 0834567891 |
|
||||
| Mobiles | +3534567890 <br/> 0834567891 |
|
||||
|
||||
## Syslog
|
||||
|
||||
|
@@ -85,7 +85,7 @@ foreach ($transports_list as $transport) {
|
||||
if ($item['type'] !== 'hidden') {
|
||||
echo '<div class="form-group" title="' . $item['descr'] . '">';
|
||||
echo '<label for="' . $item['name'] . '" class="col-sm-3 col-md-2 control-label">' . $item['title'] . ': </label>';
|
||||
if ($item['type'] == 'text') {
|
||||
if ($item['type'] == 'text' || $item['type'] == 'password') {
|
||||
echo '<div class="col-sm-9 col-md-10">';
|
||||
echo '<input type="' . $item['type'] . '" id="' . $item['name'] . '" name="' . $item['name'] . '" class="form-control" ';
|
||||
if ($item['required']) {
|
||||
|
@@ -65,7 +65,9 @@ foreach (dbFetchRows($query) as $transport) {
|
||||
}
|
||||
|
||||
$val = $transport_config[$item['name']];
|
||||
|
||||
if ($item['type'] == 'password') {
|
||||
$val = '<b>••••••••</b>';
|
||||
}
|
||||
// Match value to key name for select inputs
|
||||
if ($item['type'] == 'select') {
|
||||
$val = array_search($val, $item['options']);
|
||||
|
Reference in New Issue
Block a user