Alert transport cleanup, no_proxy support and other proxy cleanups (#14763)

* Add no_proxy and other proxy related settings
Set user agent on all http client requests
Unify http client usage

* Style fixes

* Remove useless use statements

* Correct variable, good job phpstan

* Add tests
fix https_proxy bug
add tcp:// to the config settings format

* style and lint fixes

* Remove guzzle from the direct dependencies

* Use built in Laravel testing functionality

* update baseline
This commit is contained in:
Tony Murray
2023-05-23 09:25:17 -05:00
committed by GitHub
parent 02896172bd
commit 04bb75f5f3
78 changed files with 1545 additions and 2314 deletions

View File

@@ -25,8 +25,7 @@
namespace App\ApiClients;
use Illuminate\Support\Facades\Http;
use LibreNMS\Util\Proxy;
use LibreNMS\Util\Http;
class BaseApi
{
@@ -37,9 +36,7 @@ class BaseApi
protected function getClient(): \Illuminate\Http\Client\PendingRequest
{
if (is_null($this->client)) {
$this->client = Http::withOptions([
'proxy' => Proxy::forGuzzle($this->base_uri),
])->baseUrl($this->base_uri)
$this->client = Http::client()->baseUrl($this->base_uri)
->timeout($this->timeout);
}

View File

@@ -49,7 +49,7 @@ class BingApi extends BaseApi implements Geocoder
}
/**
* Build Guzzle request option array
* Build request option array
*
* @throws \Exception you may throw an Exception if validation fails
*/

View File

@@ -83,7 +83,7 @@ trait GeocodingHelper
abstract protected function parseLatLng(array $data): array;
/**
* Build Guzzle request option array
* Build request option array
*
* @param string $address
* @return array

View File

@@ -60,7 +60,7 @@ class GoogleMapsApi extends BaseApi implements Geocoder
}
/**
* Build Guzzle request option array
* Build request option array
*
* @throws \Exception you may throw an Exception if validation fails
*/

View File

@@ -26,12 +26,12 @@
namespace App\ApiClients;
use App\Models\Device;
use GuzzleHttp\Client;
use LibreNMS\Config;
use LibreNMS\Util\Http;
class GraylogApi
{
private Client $client;
private \Illuminate\Http\Client\PendingRequest $client;
private string $api_prefix = '';
public function __construct(array $config = [])
@@ -53,7 +53,7 @@ class GraylogApi
];
}
$this->client = new Client($config);
$this->client = Http::client()->withOptions($config);
}
public function getStreams(): array
@@ -65,9 +65,8 @@ class GraylogApi
$uri = $this->api_prefix . '/streams';
$response = $this->client->get($uri);
$data = json_decode($response->getBody(), true);
return $data ?: [];
return $response->json() ?: [];
}
/**
@@ -93,10 +92,9 @@ class GraylogApi
'filter' => $filter,
];
$response = $this->client->get($uri, ['query' => $data]);
$data = json_decode($response->getBody(), true);
$response = $this->client->get($uri, $data);
return $data ?: [];
return $response->json() ?: [];
}
/**

View File

@@ -49,7 +49,7 @@ class MapquestApi extends BaseApi implements Geocoder
}
/**
* Build Guzzle request option array
* Build request option array
*
* @throws \Exception you may throw an Exception if validation fails
*/

View File

@@ -46,7 +46,7 @@ class NominatimApi extends BaseApi implements Geocoder
}
/**
* Build Guzzle request option array
* Build request option array
*
* @throws \Exception you may throw an Exception if validation fails
*/

View File

@@ -25,7 +25,6 @@
namespace App\ApiClients;
use GuzzleHttp\Exception\RequestException;
use LibreNMS\Exceptions\ApiClientException;
class RipeApi extends BaseApi
@@ -68,21 +67,12 @@ class RipeApi extends BaseApi
*/
private function makeApiCall(string $uri, array $options): mixed
{
try {
$response_data = $this->getClient()->get($uri, $options['query'])->json();
if (isset($response_data['status']) && $response_data['status'] == 'ok') {
return $response_data;
} else {
throw new ApiClientException('RIPE API call failed', $response_data);
}
} catch (RequestException $e) {
$message = 'RIPE API call to ' . $e->getRequest()->getUri() . ' failed: ';
$message .= $e->getResponse()->getReasonPhrase() . ' ' . $e->getResponse()->getStatusCode();
$response_data = $this->getClient()->get($uri, $options['query'])->json();
throw new ApiClientException(
$message,
json_decode($e->getResponse()->getBody(), true)
);
if (isset($response_data['status']) && $response_data['status'] == 'ok') {
return $response_data;
}
throw new ApiClientException("RIPE API call to $this->base_uri/$uri failed: " . $this->getClient()->get($uri, $options['query'])->status(), $response_data);
}
}

View File

@@ -54,6 +54,7 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use LibreNMS\Config;
use LibreNMS\Data\Store\Rrd;
use LibreNMS\Util\Http;
use LibreNMS\Util\Version;
class AboutController extends Controller
@@ -113,7 +114,7 @@ class AboutController extends Controller
// try to clear usage data if we have a uuid
if ($usage_uuid) {
if (! \Http::post(Config::get('callback_clear'), ['uuid' => $usage_uuid])->successful()) {
if (! Http::client()->post(Config::get('callback_clear'), ['uuid' => $usage_uuid])->successful()) {
return response()->json([], 500); // don't clear if this fails to delete upstream data
}
}

View File

@@ -5,41 +5,19 @@ namespace App\Http\Controllers;
use App\Models\AlertTransport;
use App\Models\Device;
use Illuminate\Http\Request;
use LibreNMS\Alert\AlertUtil;
use LibreNMS\Config;
use LibreNMS\Alert\AlertData;
use LibreNMS\Exceptions\AlertTransportDeliveryException;
class AlertTransportController extends Controller
{
public function test(Request $request, AlertTransport $transport): \Illuminate\Http\JsonResponse
{
/** @var Device $device */
$device = Device::with('location')->first();
$obj = [
'hostname' => $device->hostname,
'device_id' => $device->device_id,
'sysDescr' => $device->sysDescr,
'version' => $device->version,
'hardware' => $device->hardware,
'location' => $device->location,
'title' => 'Testing transport from ' . Config::get('project_name'),
'elapsed' => '11s',
'alert_id' => '000',
'id' => '000',
'faults' => [],
'uid' => '000',
'severity' => 'critical',
'rule' => 'macros.device = 1',
'name' => 'Test-Rule',
'string' => '#1: test => string;',
'timestamp' => date('Y-m-d H:i:s'),
'contacts' => AlertUtil::getContacts($device->toArray()),
'state' => '1',
'msg' => 'This is a test alert',
];
$alert_data = AlertData::testData($device);
$opts = Config::get('alert.transports.' . $transport->transport_type);
try {
$result = $transport->instance()->deliverAlert($obj, $opts);
$result = $transport->instance()->deliverAlert($alert_data);
if ($result === true) {
return response()->json(['status' => 'ok']);
@@ -47,7 +25,7 @@ class AlertTransportController extends Controller
} catch (AlertTransportDeliveryException $e) {
return response()->json([
'status' => 'error',
'message' => $e->getMessage(),
'message' => strip_tags($e->getMessage()),
]);
} catch (\Exception $e) {
\Log::error($e);
@@ -56,7 +34,7 @@ class AlertTransportController extends Controller
return response()->json([
'status' => 'error',
'message' => $result,
'message' => strip_tags($result),
]);
}
}

View File

@@ -5,27 +5,8 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use LibreNMS\Alert\Transport;
use LibreNMS\Alert\Transport\Dummy;
/**
* \App\Models\AlertTransport
*
* @property int $transport_id
* @property string $transport_name
* @property string $transport_type
* @property bool $is_default
* @property array|null $transport_config
*
* @method static \Illuminate\Database\Eloquent\Builder|AlertTransport newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|AlertTransport newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|AlertTransport query()
* @method static \Illuminate\Database\Eloquent\Builder|AlertTransport whereIsDefault($value)
* @method static \Illuminate\Database\Eloquent\Builder|AlertTransport whereTransportConfig($value)
* @method static \Illuminate\Database\Eloquent\Builder|AlertTransport whereTransportId($value)
* @method static \Illuminate\Database\Eloquent\Builder|AlertTransport whereTransportName($value)
* @method static \Illuminate\Database\Eloquent\Builder|AlertTransport whereTransportType($value)
*
* @mixin \Eloquent
*/
class AlertTransport extends Model
{
use HasFactory;
@@ -36,11 +17,16 @@ class AlertTransport extends Model
'is_default' => 'boolean',
'transport_config' => 'array',
];
protected $fillable = ['transport_config'];
public function instance(): Transport
{
$class = Transport::getClass($this->transport_type);
return new $class($this);
if (class_exists($class)) {
return new $class($this);
}
return new Dummy;
}
}