2019-01-12 12:42:42 +02:00
<? php
/* Copyright (C) 2019 LibreNMS
* 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
2021-02-09 00:29:04 +01:00
* along with this program. If not, see <https://www.gnu.org/licenses/>. */
2019-01-12 12:42:42 +02:00
/**
* Alertmanager Transport
2021-09-10 20:09:53 +02:00
*
2019-01-12 12:42:42 +02:00
* @copyright 2019 LibreNMS
* @license GPL
*/
2020-09-21 14:54:51 +02:00
2019-01-12 12:42:42 +02:00
namespace LibreNMS\Alert\Transport ;
use LibreNMS\Alert\Transport ;
use LibreNMS\Config ;
2020-05-24 04:14:36 +02:00
use LibreNMS\Enum\AlertState ;
2021-10-06 07:29:47 -05:00
use LibreNMS\Util\Proxy ;
2019-01-12 12:42:42 +02:00
class Alertmanager extends Transport
{
2021-10-06 07:29:47 -05:00
protected $name = 'Alert Manager' ;
2019-01-12 12:42:42 +02:00
public function deliverAlert ( $obj , $opts )
{
2019-03-27 07:18:02 -05:00
$alertmanager_opts = $this -> parseUserOptions ( $this -> config [ 'alertmanager-options' ]);
2019-01-12 12:42:42 +02:00
$alertmanager_opts [ 'url' ] = $this -> config [ 'alertmanager-url' ];
2019-03-27 07:18:02 -05:00
2022-03-31 22:45:44 +02:00
$alertmanager_username = $this -> config [ 'alertmanager-username' ];
$alertmanager_password = $this -> config [ 'alertmanager-password' ];
return $this -> contactAlertmanager ( $obj , $alertmanager_opts , $alertmanager_username , $alertmanager_password );
2019-01-12 12:42:42 +02:00
}
2022-03-31 22:45:44 +02:00
public function contactAlertmanager ( $obj , $api , string $username , string $password )
2019-01-12 12:42:42 +02:00
{
2020-05-24 04:14:36 +02:00
if ( $obj [ 'state' ] == AlertState :: RECOVERED ) {
2019-02-13 01:51:20 +02:00
$alertmanager_status = 'endsAt' ;
2019-01-12 12:42:42 +02:00
} else {
2019-02-13 01:51:20 +02:00
$alertmanager_status = 'startsAt' ;
2019-01-12 12:42:42 +02:00
}
$gen_url = ( Config :: get ( 'base_url' ) . 'device/device=' . $obj [ 'device_id' ]);
$alertmanager_msg = strip_tags ( $obj [ 'msg' ]);
$data = [[
2019-02-13 01:51:20 +02:00
$alertmanager_status => date ( 'c' ),
2019-01-12 12:42:42 +02:00
'generatorURL' => $gen_url ,
'annotations' => [
'summary' => $obj [ 'name' ],
'title' => $obj [ 'title' ],
'description' => $alertmanager_msg ,
],
'labels' => [
'alertname' => $obj [ 'name' ],
'severity' => $obj [ 'severity' ],
'instance' => $obj [ 'hostname' ],
],
]];
2021-03-27 16:01:48 +01:00
$url = $api [ 'url' ];
2019-03-02 07:09:25 +02:00
unset ( $api [ 'url' ]);
foreach ( $api as $label => $value ) {
2022-03-14 22:39:00 +01:00
// To allow dynamic values
if (( preg_match ( '/^extra_[A-Za-z0-9_]+$/' , $label )) && ( ! empty ( $obj [ 'faults' ][ 1 ][ $value ]))) {
$data [ 0 ][ 'labels' ][ $label ] = $obj [ 'faults' ][ 1 ][ $value ];
} else {
$data [ 0 ][ 'labels' ][ $label ] = $value ;
}
2019-03-02 07:09:25 +02:00
}
2022-03-31 22:45:44 +02:00
return $this -> postAlerts ( $url , $data , $username , $password );
2021-03-27 16:01:48 +01:00
}
2022-03-31 22:45:44 +02:00
public static function postAlerts ( $url , $data , string $username , string $password )
2021-03-27 16:01:48 +01:00
{
$curl = curl_init ();
2021-10-06 07:29:47 -05:00
Proxy :: applyToCurl ( $curl );
2021-03-27 16:01:48 +01:00
curl_setopt ( $curl , CURLOPT_HTTPHEADER , [ 'Content-Type: application/json' ]);
2019-01-12 12:42:42 +02:00
curl_setopt ( $curl , CURLOPT_RETURNTRANSFER , 1 );
2021-03-27 16:01:48 +01:00
curl_setopt ( $curl , CURLOPT_TIMEOUT , 5 );
curl_setopt ( $curl , CURLOPT_TIMEOUT_MS , 5000 );
curl_setopt ( $curl , CURLOPT_CONNECTTIMEOUT , 5 );
curl_setopt ( $curl , CURLOPT_CONNECTTIMEOUT_MS , 5000 );
2019-01-12 12:42:42 +02:00
curl_setopt ( $curl , CURLOPT_POST , true );
2021-03-27 16:01:48 +01:00
2022-03-31 22:45:44 +02:00
if ( $username != '' && $password != '' ) {
curl_setopt ( $curl , CURLOPT_HTTPAUTH , CURLAUTH_BASIC );
curl_setopt ( $curl , CURLOPT_USERNAME , $username );
curl_setopt ( $curl , CURLOPT_PASSWORD , $password );
}
2021-03-27 16:01:48 +01:00
$alert_message = json_encode ( $data );
2019-01-12 12:42:42 +02:00
curl_setopt ( $curl , CURLOPT_POSTFIELDS , $alert_message );
2021-03-27 16:01:48 +01:00
foreach ( explode ( ',' , $url ) as $am ) {
$post_url = ( $am . '/api/v2/alerts' );
curl_setopt ( $curl , CURLOPT_URL , $post_url );
$ret = curl_exec ( $curl );
if ( $ret === false || curl_errno ( $curl )) {
logfile ( "Failed to contact $post_url : " . curl_error ( $curl ));
continue ;
}
$code = curl_getinfo ( $curl , CURLINFO_HTTP_CODE );
if ( $code == 200 ) {
curl_close ( $curl );
return true ;
}
}
$err = "Unable to POST to Alertmanager at $post_url ." ;
if ( $ret === false || curl_errno ( $curl )) {
$err .= ' cURL error: ' . curl_error ( $curl );
} else {
$err .= ' HTTP status: ' . curl_getinfo ( $curl , CURLINFO_HTTP_CODE );
2019-01-12 12:42:42 +02:00
}
2020-09-21 14:54:51 +02:00
2021-03-27 16:01:48 +01:00
curl_close ( $curl );
logfile ( $err );
return $err ;
2019-01-12 12:42:42 +02:00
}
public static function configTemplate ()
{
return [
'config' => [
[
2021-03-27 16:01:48 +01:00
'title' => 'Alertmanager URL(s)' ,
2019-01-12 12:42:42 +02:00
'name' => 'alertmanager-url' ,
2021-03-27 16:01:48 +01:00
'descr' => 'Alertmanager Webhook URL(s). Can contain comma-separated URLs' ,
2019-01-12 12:42:42 +02:00
'type' => 'text' ,
],
2022-03-31 22:45:44 +02:00
[
'title' => 'Alertmanager Username' ,
'name' => 'alertmanager-username' ,
'descr' => 'Alertmanager Basic Username to authenticate to Alertmanager' ,
'type' => 'text' ,
],
[
'title' => 'Alertmanager Password' ,
'name' => 'alertmanager-password' ,
'descr' => 'Alertmanager Basic Password to authenticate to Alertmanager' ,
'type' => 'password' ,
],
2019-01-12 12:42:42 +02:00
[
'title' => 'Alertmanager Options' ,
'name' => 'alertmanager-options' ,
2022-03-14 22:39:00 +01:00
'descr' => 'Alertmanager Options. You can add any fixed string value or dynamic value from alert details (label name must start with extra_ and value must exists in alert details).' ,
2019-01-12 12:42:42 +02:00
'type' => 'textarea' ,
],
],
'validation' => [
2021-03-27 16:01:48 +01:00
'alertmanager-url' => 'required|string' ,
2019-01-12 12:42:42 +02:00
],
];
}
}