mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
API mac search (#12964)
* API find a switchport with the mac from device * fix style * convert SQL to Eloquent * convert SQL to Eloquent * git mistake * Global use App\Models\Port * git mistake partII * Refractor Eloquent - Not finish but easier to help for others * Better Eloquent Query without filter option * Validation * fix style * Add filter option and DOC * convert to the better macToHex method * add a maxToHex unit test * fix style * fix style * fix syle - seems my dev:check is running again :-) * Fix phpStan * phpStan #2
This commit is contained in:
105
doc/API/Ports.md
105
doc/API/Ports.md
@@ -90,6 +90,111 @@ Output:
|
||||
}
|
||||
```
|
||||
|
||||
### `ports_with_associated_mac`
|
||||
|
||||
Search for ports matching the search mac.
|
||||
|
||||
Route: `/api/v0/ports/mac/:search?filter=first`
|
||||
|
||||
- search a mac address in fdb and print the ports ordered by the mac count of the associated port.
|
||||
|
||||
Input:
|
||||
|
||||
-
|
||||
|
||||
Example:
|
||||
|
||||
```curl
|
||||
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/mac/00:11:22:33:44:55
|
||||
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/mac/001122.334455?filter=first
|
||||
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/mac/001122334455?filter=first
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "",
|
||||
"port": [
|
||||
{
|
||||
"port_id": "323",
|
||||
"device_id": "55",
|
||||
"port_descr_type": null,
|
||||
"port_descr_descr": null,
|
||||
"port_descr_circuit": null,
|
||||
"port_descr_speed": null,
|
||||
"port_descr_notes": null,
|
||||
"ifDescr": "GigabitEthernet0/0/0",
|
||||
"ifName": "Gi0/0/0",
|
||||
"portName": null,
|
||||
"ifIndex": "1",
|
||||
"ifSpeed": "1000000000",
|
||||
"ifConnectorPresent": "true",
|
||||
"ifPromiscuousMode": "false",
|
||||
"ifHighSpeed": "1000",
|
||||
"ifOperStatus": "up",
|
||||
"ifOperStatus_prev": null,
|
||||
"ifAdminStatus": "up",
|
||||
"ifAdminStatus_prev": null,
|
||||
"ifDuplex": "fullDuplex",
|
||||
"ifMtu": "1560",
|
||||
"ifType": "ethernetCsmacd",
|
||||
"ifAlias": "ASR Interconnect Trunk",
|
||||
"ifPhysAddress": "84bf20853e00",
|
||||
"ifHardType": null,
|
||||
"ifLastChange": "42407358",
|
||||
"ifVlan": "",
|
||||
"ifTrunk": "",
|
||||
"ifVrf": "0",
|
||||
"counter_in": null,
|
||||
"counter_out": null,
|
||||
"ignore": "0",
|
||||
"disabled": "0",
|
||||
"detailed": "0",
|
||||
"deleted": "0",
|
||||
"pagpOperationMode": null,
|
||||
"pagpPortState": null,
|
||||
"pagpPartnerDeviceId": null,
|
||||
"pagpPartnerLearnMethod": null,
|
||||
"pagpPartnerIfIndex": null,
|
||||
"pagpPartnerGroupIfIndex": null,
|
||||
"pagpPartnerDeviceName": null,
|
||||
"pagpEthcOperationMode": null,
|
||||
"pagpDeviceId": null,
|
||||
"pagpGroupIfIndex": null,
|
||||
"ifInUcastPkts": "128518576",
|
||||
"ifInUcastPkts_prev": "128517284",
|
||||
"ifInUcastPkts_delta": "1292",
|
||||
"ifInUcastPkts_rate": "4",
|
||||
"ifOutUcastPkts": "128510560",
|
||||
"ifOutUcastPkts_prev": "128509268",
|
||||
"ifOutUcastPkts_delta": "1292",
|
||||
"ifOutUcastPkts_rate": "4",
|
||||
"ifInErrors": "0",
|
||||
"ifInErrors_prev": "0",
|
||||
"ifInErrors_delta": "0",
|
||||
"ifInErrors_rate": "0",
|
||||
"ifOutErrors": "0",
|
||||
"ifOutErrors_prev": "0",
|
||||
"ifOutErrors_delta": "0",
|
||||
"ifOutErrors_rate": "0",
|
||||
"ifInOctets": "12827393730",
|
||||
"ifInOctets_prev": "12827276736",
|
||||
"ifInOctets_delta": "116994",
|
||||
"ifInOctets_rate": "387",
|
||||
"ifOutOctets": "14957481766",
|
||||
"ifOutOctets_prev": "14957301765",
|
||||
"ifOutOctets_delta": "180001",
|
||||
"ifOutOctets_rate": "596",
|
||||
"poll_time": "1483779150",
|
||||
"poll_prev": "1483778848",
|
||||
"poll_period": "302"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
### `get_port_info`
|
||||
|
||||
Get all info for a particular port.
|
||||
|
||||
@@ -17,6 +17,7 @@ use App\Models\Device;
|
||||
use App\Models\DeviceGroup;
|
||||
use App\Models\DeviceOutage;
|
||||
use App\Models\OspfPort;
|
||||
use App\Models\Port;
|
||||
use App\Models\PortGroup;
|
||||
use App\Models\PortsFdb;
|
||||
use App\Models\Sensor;
|
||||
@@ -32,6 +33,7 @@ use LibreNMS\Data\Store\Datastore;
|
||||
use LibreNMS\Exceptions\InvalidIpException;
|
||||
use LibreNMS\Util\IP;
|
||||
use LibreNMS\Util\IPv4;
|
||||
use LibreNMS\Util\Rewrite;
|
||||
|
||||
function api_success($result, $result_name, $message = null, $code = 200, $count = null, $extra = null)
|
||||
{
|
||||
@@ -465,8 +467,8 @@ function device_availability(Illuminate\Http\Request $request)
|
||||
|
||||
return check_device_permission($device_id, function ($device_id) {
|
||||
$availabilities = Availability::select('duration', 'availability_perc')
|
||||
->where('device_id', '=', $device_id)
|
||||
->orderBy('duration', 'ASC');
|
||||
->where('device_id', '=', $device_id)
|
||||
->orderBy('duration', 'ASC');
|
||||
|
||||
return api_success($availabilities->get(), 'availability');
|
||||
});
|
||||
@@ -486,8 +488,8 @@ function device_outages(Illuminate\Http\Request $request)
|
||||
|
||||
return check_device_permission($device_id, function ($device_id) {
|
||||
$outages = DeviceOutage::select('going_down', 'up_again')
|
||||
->where('device_id', '=', $device_id)
|
||||
->orderBy('going_down', 'DESC');
|
||||
->where('device_id', '=', $device_id)
|
||||
->orderBy('going_down', 'DESC');
|
||||
|
||||
return api_success($outages->get(), 'outages');
|
||||
});
|
||||
@@ -653,7 +655,7 @@ function list_ospf(Illuminate\Http\Request $request)
|
||||
function list_ospf_ports(Illuminate\Http\Request $request)
|
||||
{
|
||||
$ospf_ports = OspfPort::hasAccess(Auth::user())
|
||||
->get();
|
||||
->get();
|
||||
if ($ospf_ports->isEmpty()) {
|
||||
return api_error(404, 'Ospf ports do not exist');
|
||||
}
|
||||
@@ -990,13 +992,13 @@ function search_ports(Illuminate\Http\Request $request)
|
||||
{
|
||||
$search = $request->route('search');
|
||||
$value = "%$search%";
|
||||
$ports = \App\Models\Port::hasAccess(Auth::user())
|
||||
->select(['device_id', 'port_id', 'ifIndex', 'ifName'])
|
||||
->where('ifAlias', 'like', $value)
|
||||
->orWhere('ifDescr', 'like', $value)
|
||||
->orWhere('ifName', 'like', $value)
|
||||
->orderBy('ifName')
|
||||
->get();
|
||||
$ports = Port::hasAccess(Auth::user())
|
||||
->select(['device_id', 'port_id', 'ifIndex', 'ifName'])
|
||||
->where('ifAlias', 'like', $value)
|
||||
->orWhere('ifDescr', 'like', $value)
|
||||
->orWhere('ifName', 'like', $value)
|
||||
->orderBy('ifName')
|
||||
->get();
|
||||
|
||||
if ($ports->isEmpty()) {
|
||||
return api_error(404, 'No ports found');
|
||||
@@ -1357,15 +1359,15 @@ function list_oxidized(Illuminate\Http\Request $request)
|
||||
{
|
||||
$return = [];
|
||||
$devices = Device::query()
|
||||
->where('disabled', 0)
|
||||
->when($request->route('hostname'), function ($query, $hostname) {
|
||||
return $query->where('hostname', $hostname);
|
||||
})
|
||||
->whereNotIn('type', Config::get('oxidized.ignore_types', []))
|
||||
->whereNotIn('os', Config::get('oxidized.ignore_os', []))
|
||||
->whereAttributeDisabled('override_Oxidized_disable')
|
||||
->select(['hostname', 'sysName', 'sysDescr', 'hardware', 'os', 'ip', 'location_id'])
|
||||
->get();
|
||||
->where('disabled', 0)
|
||||
->when($request->route('hostname'), function ($query, $hostname) {
|
||||
return $query->where('hostname', $hostname);
|
||||
})
|
||||
->whereNotIn('type', Config::get('oxidized.ignore_types', []))
|
||||
->whereNotIn('os', Config::get('oxidized.ignore_os', []))
|
||||
->whereAttributeDisabled('override_Oxidized_disable')
|
||||
->select(['hostname', 'sysName', 'sysDescr', 'hardware', 'os', 'ip', 'location_id'])
|
||||
->get();
|
||||
|
||||
/** @var Device $device */
|
||||
foreach ($devices as $device) {
|
||||
@@ -1614,8 +1616,8 @@ function get_bill_history_graphdata(Illuminate\Http\Request $request)
|
||||
}
|
||||
|
||||
return ! isset($graph_data) ?
|
||||
api_error(400, "Unsupported graph type $graph_type") :
|
||||
api_success($graph_data, 'graph_data');
|
||||
api_error(400, "Unsupported graph type $graph_type") :
|
||||
api_success($graph_data, 'graph_data');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2145,10 +2147,10 @@ function list_fdb(Illuminate\Http\Request $request)
|
||||
$mac = $request->route('mac');
|
||||
|
||||
$fdb = PortsFdb::hasAccess(Auth::user())
|
||||
->when(! empty($mac), function (Builder $query) use ($mac) {
|
||||
return $query->where('mac_address', $mac);
|
||||
})
|
||||
->get();
|
||||
->when(! empty($mac), function (Builder $query) use ($mac) {
|
||||
return $query->where('mac_address', $mac);
|
||||
})
|
||||
->get();
|
||||
|
||||
if ($fdb->isEmpty()) {
|
||||
return api_error(404, 'Fdb do not exist');
|
||||
@@ -2602,6 +2604,36 @@ function del_service_from_host(Illuminate\Http\Request $request)
|
||||
return api_error(500, 'Failed to delete the service');
|
||||
}
|
||||
|
||||
function search_by_mac(Illuminate\Http\Request $request)
|
||||
{
|
||||
$macAddress = Rewrite::macToHex((string) $request->route('search'));
|
||||
|
||||
$rules = [
|
||||
'macAddress' => 'required|string|regex:/^[0-9a-fA-F]{12}$/',
|
||||
];
|
||||
|
||||
$validate = Validator::make(['macAddress' => $macAddress], $rules);
|
||||
if ($validate->fails()) {
|
||||
return api_error(422, $validate->messages());
|
||||
}
|
||||
|
||||
$ports = Port::whereHas('fdbEntries', function ($fdbDownlink) use ($macAddress) {
|
||||
$fdbDownlink->where('mac_address', $macAddress);
|
||||
})
|
||||
->withCount('fdbEntries')
|
||||
->orderBy('fdb_entries_count')
|
||||
->get();
|
||||
|
||||
if ($ports->count() == 0) {
|
||||
return api_error(404, 'mac not found');
|
||||
}
|
||||
|
||||
if ($request->has('filter') && $request->get('filter') === 'first') {
|
||||
return api_success($ports->first(), 'ports');
|
||||
}
|
||||
|
||||
return api_success($ports, 'ports');
|
||||
}
|
||||
function edit_service_for_host(Illuminate\Http\Request $request)
|
||||
{
|
||||
$service_id = $request->route('id');
|
||||
|
||||
@@ -117,6 +117,7 @@ Route::group(['prefix' => 'v0', 'namespace' => '\App\Api\Controllers'], function
|
||||
Route::get('{portid}', 'LegacyApiController@get_port_info')->name('get_port_info');
|
||||
Route::get('{portid}/ip', 'LegacyApiController@get_port_ip_addresses')->name('get_port_ip_info');
|
||||
Route::get('search/{search}', 'LegacyApiController@search_ports')->name('search_ports');
|
||||
Route::get('mac/{search}', 'LegacyApiController@search_by_mac')->name('search_mac');
|
||||
Route::get(null, 'LegacyApiController@get_all_ports')->name('get_all_ports');
|
||||
});
|
||||
|
||||
|
||||
36
tests/Unit/Util/RewriteTest.php
Normal file
36
tests/Unit/Util/RewriteTest.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace LibreNMS\Tests\Unit\Util;
|
||||
|
||||
use LibreNMS\Tests\TestCase;
|
||||
use LibreNMS\Util\Rewrite;
|
||||
|
||||
class RewriteTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
* @dataProvider validMacProvider
|
||||
*/
|
||||
public function testMacToHex(string $from, string $to): void
|
||||
{
|
||||
$this->assertEquals(Rewrite::macToHex($from), $to);
|
||||
}
|
||||
|
||||
public function validMacProvider(): array
|
||||
{
|
||||
return [
|
||||
['00:00:00:00:00:01', '000000000001'],
|
||||
['00-00-00-00-00-01', '000000000001'],
|
||||
['000000.000001', '000000000001'],
|
||||
['000000000001', '000000000001'],
|
||||
['00:12:34:ab:cd:ef', '001234abcdef'],
|
||||
['00:12:34:AB:CD:EF', '001234ABCDEF'],
|
||||
['0:12:34:AB:CD:EF', '001234ABCDEF'],
|
||||
['00-12-34-AB-CD-EF', '001234ABCDEF'],
|
||||
['001234-ABCDEF', '001234ABCDEF'],
|
||||
['0012.34AB.CDEF', '001234ABCDEF'],
|
||||
['00:02:04:0B:0D:0F', '0002040B0D0F'],
|
||||
['0:2:4:B:D:F', '0002040B0D0F'],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user