2014-07-07 00:15:04 +01:00
<? php
/*
* LibreNMS
*
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
*
* 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. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
2022-03-15 06:54:02 -05:00
use App\Actions\Device\ValidateDeviceAndCreate ;
2020-09-24 00:21:08 +02:00
use App\Models\Availability ;
2019-06-19 16:01:53 -05:00
use App\Models\Device ;
use App\Models\DeviceGroup ;
2020-09-24 00:21:08 +02:00
use App\Models\DeviceOutage ;
2024-06-25 11:04:55 -05:00
use App\Models\Ipv4Mac ;
2023-08-03 20:35:20 -04:00
use App\Models\Location ;
2022-01-20 15:15:23 +01:00
use App\Models\MplsSap ;
use App\Models\MplsService ;
2021-06-16 21:31:05 +03:00
use App\Models\OspfPort ;
2023-11-01 23:33:35 -04:00
use App\Models\PollerGroup ;
2021-08-10 02:33:04 +02:00
use App\Models\Port ;
2021-04-07 00:25:08 +02:00
use App\Models\PortGroup ;
2019-07-29 16:32:37 -05:00
use App\Models\PortsFdb ;
use App\Models\Sensor ;
2021-02-02 06:40:11 +00:00
use App\Models\ServiceTemplate ;
2021-09-28 21:54:52 +02:00
use App\Models\UserPref ;
2019-07-29 16:32:37 -05:00
use Illuminate\Database\Eloquent\Builder ;
2022-11-18 16:27:56 -06:00
use Illuminate\Http\JsonResponse ;
2022-11-03 01:08:52 -05:00
use Illuminate\Http\Request ;
2019-07-29 16:32:37 -05:00
use Illuminate\Routing\Router ;
2020-04-17 17:37:56 -05:00
use Illuminate\Support\Arr ;
2019-11-08 13:11:56 +00:00
use Illuminate\Support\Facades\Validator ;
2020-04-17 17:37:56 -05:00
use Illuminate\Support\Str ;
2018-09-19 13:47:45 +01:00
use LibreNMS\Alerting\QueryBuilderParser ;
2023-04-21 19:52:47 -05:00
use LibreNMS\Billing ;
2018-09-19 23:38:01 +01:00
use LibreNMS\Config ;
2019-04-10 16:33:25 -05:00
use LibreNMS\Exceptions\InvalidIpException ;
2022-11-18 16:27:56 -06:00
use LibreNMS\Exceptions\InvalidTableColumnException ;
2022-10-22 14:58:51 -05:00
use LibreNMS\Util\Graph ;
2020-04-12 01:11:57 +02:00
use LibreNMS\Util\IP ;
2020-04-17 17:37:56 -05:00
use LibreNMS\Util\IPv4 ;
2023-10-06 07:34:14 -05:00
use LibreNMS\Util\Mac ;
2022-08-24 14:01:54 -05:00
use LibreNMS\Util\Number ;
2017-11-18 11:33:03 +01:00
2022-11-18 16:27:56 -06:00
function api_success ( $result , $result_name , $message = null , $code = 200 , $count = null , $extra = null ) : JsonResponse
2017-11-29 09:42:52 +00:00
{
if ( isset ( $result ) && ! isset ( $result_name )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Result name not specified' );
2017-11-29 09:42:52 +00:00
}
2017-12-02 16:53:45 -06:00
2019-07-29 16:32:37 -05:00
$output = [ 'status' => 'ok' ];
2017-12-02 16:53:45 -06:00
2017-11-29 09:42:52 +00:00
if ( isset ( $result )) {
$output [ $result_name ] = $result ;
}
if ( isset ( $message ) && $message != '' ) {
$output [ 'message' ] = $message ;
}
if ( ! isset ( $count ) && is_array ( $result )) {
$count = count ( $result );
}
if ( isset ( $count )) {
$output [ 'count' ] = $count ;
}
if ( isset ( $extra )) {
$output = array_merge ( $output , $extra );
}
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return response () -> json ( $output , $code , [], JSON_PRETTY_PRINT );
2017-11-29 09:42:52 +00:00
} // end api_success()
2015-07-13 20:10:26 +02:00
2022-11-18 16:27:56 -06:00
function api_success_noresult ( $code , $message = null ) : JsonResponse
2017-11-29 09:42:52 +00:00
{
2019-07-29 16:32:37 -05:00
return api_success ( null , null , $message , $code );
2017-11-29 09:42:52 +00:00
} // end api_success_noresult
2022-11-18 16:27:56 -06:00
function api_error ( $statusCode , $message ) : JsonResponse
2017-11-29 09:42:52 +00:00
{
2019-07-29 16:32:37 -05:00
return response () -> json ([
2024-01-05 05:39:12 +01:00
'status' => 'error' ,
2017-11-29 09:42:52 +00:00
'message' => $message ,
2019-07-29 16:32:37 -05:00
], $statusCode , [], JSON_PRETTY_PRINT );
2017-11-29 09:42:52 +00:00
} // end api_error()
2022-11-18 16:27:56 -06:00
function api_not_found () : JsonResponse
2018-02-09 21:14:55 +00:00
{
2019-07-29 16:32:37 -05:00
return api_error ( 404 , "This API route doesn't exist." );
2018-02-09 21:14:55 +00:00
}
2022-11-03 01:08:52 -05:00
function api_get_graph ( Request $request , array $additional = [])
2017-11-29 09:42:52 +00:00
{
2022-10-22 14:58:51 -05:00
try {
2022-11-03 01:08:52 -05:00
$vars = $request -> only ([
'from' ,
'to' ,
'legend' ,
'title' ,
'absolute' ,
'font' ,
'bg' ,
'bbg' ,
'title' ,
'graph_title' ,
'nototal' ,
'nodetails' ,
'noagg' ,
'inverse' ,
'previous' ,
2023-08-24 14:40:33 -05:00
'duration' ,
2022-11-03 01:08:52 -05:00
]);
$graph = Graph :: get ([
2024-01-05 05:39:12 +01:00
'width' => $request -> get ( 'width' , 1075 ),
2022-11-03 01:08:52 -05:00
'height' => $request -> get ( 'height' , 300 ),
... $additional ,
... $vars ,
]);
if ( $request -> get ( 'output' ) === 'base64' ) {
2022-10-28 08:06:29 -05:00
return api_success ([ 'image' => $graph -> base64 (), 'content-type' => $graph -> contentType ()], 'image' );
2022-10-22 14:58:51 -05:00
}
2019-07-29 16:32:37 -05:00
2022-10-28 08:06:29 -05:00
return response ( $graph -> data , 200 , [ 'Content-Type' => $graph -> contentType ()]);
2022-10-22 14:58:51 -05:00
} catch ( \LibreNMS\Exceptions\RrdGraphException $e ) {
return api_error ( 500 , $e -> getMessage ());
2019-08-12 09:46:36 -05:00
}
2017-11-29 09:42:52 +00:00
}
2019-07-29 16:32:37 -05:00
function check_bill_permission ( $bill_id , $callback )
2017-11-29 09:42:52 +00:00
{
2019-07-29 16:32:37 -05:00
if ( ! bill_permitted ( $bill_id )) {
return api_error ( 403 , 'Insufficient permissions to access this bill' );
2017-11-29 09:42:52 +00:00
}
2019-07-29 16:32:37 -05:00
return $callback ( $bill_id );
2017-11-29 09:42:52 +00:00
}
2019-07-29 16:32:37 -05:00
function check_device_permission ( $device_id , $callback = null )
2017-11-29 09:42:52 +00:00
{
2019-07-29 16:32:37 -05:00
if ( ! device_permitted ( $device_id )) {
return api_error ( 403 , 'Insufficient permissions to access this device' );
2017-11-29 09:42:52 +00:00
}
2019-07-29 16:32:37 -05:00
return is_callable ( $callback ) ? $callback ( $device_id ) : true ;
2017-11-29 09:42:52 +00:00
}
2019-07-29 16:32:37 -05:00
function check_port_permission ( $port_id , $device_id , $callback )
2017-11-29 09:42:52 +00:00
{
2019-07-29 16:32:37 -05:00
if ( ! device_permitted ( $device_id ) && ! port_permitted ( $port_id , $device_id )) {
return api_error ( 403 , 'Insufficient permissions to access this port' );
2017-11-29 09:42:52 +00:00
}
2019-07-29 16:32:37 -05:00
return $callback ( $port_id );
2017-11-29 09:42:52 +00:00
}
2015-07-13 20:10:26 +02:00
2022-11-03 01:08:52 -05:00
function get_graph_by_port_hostname ( Request $request , $ifname = null , $type = 'port_bits' )
2016-08-18 20:28:22 -05:00
{
2014-07-08 14:39:19 +01:00
// This will return a graph for a given port by the ifName
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2017-07-04 23:41:22 +02:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2019-07-29 16:32:37 -05:00
$vars = [
2022-11-03 01:08:52 -05:00
'port' => $ifname ?: $request -> route ( 'ifname' ),
'type' => $request -> route ( 'type' , $type ),
2019-07-29 16:32:37 -05:00
];
2015-07-13 20:10:26 +02:00
2022-11-03 01:08:52 -05:00
$port_field = $request -> get ( 'ifDescr' ) ? 'ifDescr' : 'ifName' ; // don't accept user input
$vars [ 'id' ] = Port :: where ([
'device_id' => $device_id ,
'deleted' => 0 ,
$port_field => $vars [ 'port' ],
]) -> value ( 'port_id' );
2017-12-02 16:53:45 -06:00
2022-11-03 01:08:52 -05:00
return check_port_permission ( $vars [ 'id' ], $device_id , function () use ( $request , $vars ) {
return api_get_graph ( $request , $vars );
2019-07-29 16:32:37 -05:00
});
2014-07-08 14:39:19 +01:00
}
2020-09-22 02:52:01 +02:00
function get_port_stats_by_port_hostname ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-08-12 09:46:36 -05:00
$ifName = $request -> route ( 'ifname' );
// handle %2f in paths and pass to get_graph_by_port_hostname if needed
2020-04-17 17:37:56 -05:00
if ( Str :: contains ( $ifName , '/' )) {
2019-08-12 09:46:36 -05:00
$parts = explode ( '/' , $request -> path ());
if ( isset ( $parts [ 5 ])) {
$ifName = urldecode ( $parts [ 5 ]);
if ( isset ( $parts [ 6 ])) {
return get_graph_by_port_hostname ( $request , $ifName , $parts [ 6 ]);
}
}
}
2014-09-16 22:09:42 +01:00
// This will return port stats based on a devices hostname and ifName
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2015-02-18 16:22:52 +00:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2019-07-29 16:32:37 -05:00
$port = dbFetchRow ( 'SELECT * FROM `ports` WHERE `device_id`=? AND `ifName`=? AND `deleted` = 0' , [ $device_id , $ifName ]);
return check_port_permission ( $port [ 'port_id' ], $device_id , function () use ( $request , $port ) {
$in_rate = $port [ 'ifInOctets_rate' ] * 8 ;
$out_rate = $port [ 'ifOutOctets_rate' ] * 8 ;
2022-08-24 14:01:54 -05:00
$port [ 'in_rate' ] = Number :: formatSi ( $in_rate , 2 , 3 , 'bps' );
$port [ 'out_rate' ] = Number :: formatSi ( $out_rate , 2 , 3 , 'bps' );
2022-09-05 02:22:42 -05:00
$port [ 'in_perc' ] = Number :: calculatePercent ( $in_rate , $port [ 'ifSpeed' ]);
$port [ 'out_perc' ] = Number :: calculatePercent ( $out_rate , $port [ 'ifSpeed' ]);
2022-08-24 14:01:54 -05:00
$port [ 'in_pps' ] = Number :: formatBi ( $port [ 'ifInUcastPkts_rate' ], 2 , 3 , '' );
$port [ 'out_pps' ] = Number :: formatBi ( $port [ 'ifOutUcastPkts_rate' ], 2 , 3 , '' );
2019-07-29 16:32:37 -05:00
//only return requested columns
if ( $request -> has ( 'columns' )) {
$cols = explode ( ',' , $request -> get ( 'columns' ));
foreach ( array_keys ( $port ) as $c ) {
if ( ! in_array ( $c , $cols )) {
unset ( $port [ $c ]);
}
2016-12-23 21:54:13 +01:00
}
}
2019-07-29 16:32:37 -05:00
return api_success ( $port , 'port' );
});
2014-07-07 00:15:04 +01:00
}
2014-07-08 14:39:19 +01:00
2022-11-03 01:08:52 -05:00
function get_graph_generic_by_hostname ( Request $request )
2016-08-18 20:28:22 -05:00
{
2014-07-08 14:39:19 +01:00
// This will return a graph type given a device id.
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
$sensor_id = $request -> route ( 'sensor_id' );
$vars = [];
$vars [ 'type' ] = $request -> route ( 'type' , 'device_uptime' );
2017-01-19 10:09:20 +00:00
if ( isset ( $sensor_id )) {
$vars [ 'id' ] = $sensor_id ;
2020-04-17 17:37:56 -05:00
if ( Str :: contains ( $vars [ 'type' ], '_wireless' )) {
2017-12-06 22:27:30 +00:00
$vars [ 'type' ] = str_replace ( 'device_' , '' , $vars [ 'type' ]);
} else {
// If this isn't a wireless graph we need to fix the name.
$vars [ 'type' ] = str_replace ( 'device_' , 'sensor_' , $vars [ 'type' ]);
}
2017-01-19 10:09:20 +00:00
}
2016-05-04 15:50:41 -04:00
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
$device = device_by_id_cache ( $device_id );
2019-07-29 16:32:37 -05:00
$vars [ 'device' ] = $device [ 'device_id' ];
2016-05-04 15:50:41 -04:00
2020-11-01 01:48:24 +01:00
return check_device_permission ( $device_id , function () use ( $request , $vars ) {
2022-11-03 01:08:52 -05:00
return api_get_graph ( $request , $vars );
2019-07-29 16:32:37 -05:00
});
2014-07-08 14:39:19 +01:00
}
2014-07-13 21:28:26 +01:00
2023-07-20 04:19:43 +01:00
function get_graph_by_service ( Request $request )
{
$vars = [];
$vars [ 'id' ] = $request -> route ( 'id' );
$vars [ 'type' ] = 'service_graph' ;
$vars [ 'ds' ] = $request -> route ( 'datasource' );
$hostname = $request -> route ( 'hostname' );
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
$device = device_by_id_cache ( $device_id );
$vars [ 'device' ] = $device [ 'device_id' ];
return check_device_permission ( $device_id , function () use ( $request , $vars ) {
return api_get_graph ( $request , $vars );
});
}
2018-01-18 18:43:15 +03:00
function list_locations ()
{
$locations = dbFetchRows ( 'SELECT `locations`.* FROM `locations` WHERE `locations`.`location` IS NOT NULL' );
$total_locations = count ( $locations );
if ( $total_locations == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'Locations do not exist' );
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
return api_success ( $locations , 'locations' );
2018-01-18 18:43:15 +03:00
}
2020-09-22 02:52:01 +02:00
function get_device ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2014-09-27 15:25:43 +10:00
// return details of a single device
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2015-07-13 20:10:26 +02:00
2014-09-27 16:34:36 +10:00
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2015-07-13 20:10:26 +02:00
2014-09-27 16:34:36 +10:00
// find device matching the id
$device = device_by_id_cache ( $device_id );
2022-10-27 21:02:27 +02:00
if ( ! $device || ! isset ( $device [ 'device_id' ])) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , "Device $hostname does not exist" );
2017-11-29 09:42:52 +00:00
}
2019-07-29 16:32:37 -05:00
return check_device_permission ( $device_id , function () use ( $device ) {
$host_id = get_vm_parent_id ( $device );
if ( is_numeric ( $host_id )) {
$device = array_merge ( $device , [ 'parent_id' => $host_id ]);
}
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success ([ $device ], 'devices' );
});
2014-09-27 15:25:43 +10:00
}
2020-09-22 02:52:01 +02:00
function list_devices ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2014-07-13 21:28:26 +01:00
// This will return a list of devices
2019-07-29 16:32:37 -05:00
$order = $request -> get ( 'order' );
$type = $request -> get ( 'type' );
$query = $request -> get ( 'query' );
$param = [];
2018-01-14 23:43:55 +03:00
2024-04-16 17:38:17 +02:00
if ( preg_match ( '/^([a-z_]+)(?: (desc|asc))?$/i' , $order , $matches )) {
$order = "d.` $matches[1] ` " . ( $matches [ 2 ] ?? 'ASC' );
} else {
$order = 'd.`hostname` ASC' ;
2014-07-13 21:28:26 +01:00
}
2015-07-13 20:10:26 +02:00
2019-05-13 09:45:19 -05:00
$select = ' d.*, GROUP_CONCAT(dd.device_id) AS dependency_parent_id, GROUP_CONCAT(dd.hostname) AS dependency_parent_hostname, `location`, `lat`, `lng` ' ;
2018-11-28 16:49:18 -06:00
$join = ' LEFT JOIN `device_relationships` AS dr ON dr.`child_device_id` = d.`device_id` LEFT JOIN `devices` AS dd ON dr.`parent_device_id` = dd.`device_id` LEFT JOIN `locations` ON `locations`.`id` = `d`.`location_id`' ;
2018-01-14 23:43:55 +03:00
2014-07-13 21:28:26 +01:00
if ( $type == 'all' || empty ( $type )) {
$sql = '1' ;
2021-11-26 08:38:50 +11:00
} elseif ( $type == 'device_id' ) {
$sql = '`d`.`device_id` = ?' ;
$param [] = $query ;
2018-08-28 18:44:47 +02:00
} elseif ( $type == 'active' ) {
$sql = "`d`.`ignore`='0' AND `d`.`disabled`='0'" ;
2017-02-08 22:57:15 +01:00
} elseif ( $type == 'location' ) {
2021-11-26 08:38:50 +11:00
$sql = '`locations`.`location` LIKE ?' ;
$param [] = "% $query %" ;
2019-10-20 17:18:10 +02:00
} elseif ( $type == 'hostname' ) {
2021-11-26 08:38:50 +11:00
$sql = '`d`.`hostname` LIKE ?' ;
$param [] = "% $query %" ;
2016-08-18 20:28:22 -05:00
} elseif ( $type == 'ignored' ) {
2018-01-22 21:10:39 +00:00
$sql = "`d`.`ignore`='1' AND `d`.`disabled`='0'" ;
2016-08-18 20:28:22 -05:00
} elseif ( $type == 'up' ) {
2018-01-22 21:10:39 +00:00
$sql = "`d`.`status`='1' AND `d`.`ignore`='0' AND `d`.`disabled`='0'" ;
2016-08-18 20:28:22 -05:00
} elseif ( $type == 'down' ) {
2018-01-22 21:10:39 +00:00
$sql = "`d`.`status`='0' AND `d`.`ignore`='0' AND `d`.`disabled`='0'" ;
2016-08-18 20:28:22 -05:00
} elseif ( $type == 'disabled' ) {
2018-01-22 21:10:39 +00:00
$sql = "`d`.`disabled`='1'" ;
2017-06-19 12:49:43 -05:00
} elseif ( $type == 'os' ) {
2018-01-22 21:10:39 +00:00
$sql = '`d`.`os`=?' ;
2017-06-19 12:49:43 -05:00
$param [] = $query ;
2016-08-18 20:28:22 -05:00
} elseif ( $type == 'mac' ) {
2018-01-14 23:43:55 +03:00
$join .= ' LEFT JOIN `ports` AS p ON d.`device_id` = p.`device_id` LEFT JOIN `ipv4_mac` AS m ON p.`port_id` = m.`port_id` ' ;
$sql = 'm.`mac_address`=?' ;
$select .= ',p.* ' ;
2015-08-23 11:57:56 +00:00
$param [] = $query ;
2016-08-18 20:28:22 -05:00
} elseif ( $type == 'ipv4' ) {
2018-01-14 23:43:55 +03:00
$join .= ' LEFT JOIN `ports` AS p ON d.`device_id` = p.`device_id` LEFT JOIN `ipv4_addresses` AS a ON p.`port_id` = a.`port_id` ' ;
$sql = 'a.`ipv4_address`=?' ;
$select .= ',p.* ' ;
2015-08-23 11:57:56 +00:00
$param [] = $query ;
2016-08-18 20:28:22 -05:00
} elseif ( $type == 'ipv6' ) {
2018-01-14 23:43:55 +03:00
$join .= ' LEFT JOIN `ports` AS p ON d.`device_id` = p.`device_id` LEFT JOIN `ipv6_addresses` AS a ON p.`port_id` = a.`port_id` ' ;
$sql = 'a.`ipv6_address`=? OR a.`ipv6_compressed`=?' ;
$select .= ',p.* ' ;
2019-07-29 16:32:37 -05:00
$param = [ $query , $query ];
2022-12-15 14:25:11 +00:00
} elseif ( $type == 'sysName' ) {
$sql = '`d`.`sysName`=?' ;
$param [] = $query ;
} elseif ( $type == 'location_id' ) {
$sql = '`d`.`location_id`=?' ;
$param [] = $query ;
} elseif ( $type == 'type' ) {
$sql = '`d`.`type`=?' ;
$param [] = $query ;
2023-02-08 16:36:20 +00:00
} elseif ( $type == 'display' ) {
2023-07-20 12:17:28 +09:00
$sql = '`d`.`display` LIKE ?' ;
$param [] = "% $query %" ;
2016-08-18 20:28:22 -05:00
} else {
2014-07-17 20:43:13 +01:00
$sql = '1' ;
}
2018-01-14 23:43:55 +03:00
2019-07-29 16:32:37 -05:00
if ( ! Auth :: user () -> hasGlobalRead ()) {
2018-07-09 14:23:38 -05:00
$sql .= ' AND `d`.`device_id` IN (SELECT device_id FROM devices_perms WHERE user_id = ?)' ;
2019-07-29 16:32:37 -05:00
$param [] = Auth :: id ();
2017-11-29 09:42:52 +00:00
}
2019-07-29 16:32:37 -05:00
$devices = [];
2018-01-14 23:43:55 +03:00
$dev_query = "SELECT $select FROM `devices` AS d $join WHERE $sql GROUP BY d.`hostname` ORDER BY $order " ;
foreach ( dbFetchRows ( $dev_query , $param ) as $device ) {
2017-01-26 22:38:43 +00:00
$host_id = get_vm_parent_id ( $device );
2016-01-20 18:19:15 +00:00
$device [ 'ip' ] = inet6_ntop ( $device [ 'ip' ]);
2017-01-26 22:38:43 +00:00
if ( is_numeric ( $host_id )) {
$device [ 'parent_id' ] = $host_id ;
}
2014-07-13 21:28:26 +01:00
$devices [] = $device ;
}
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $devices , 'devices' );
2014-07-13 21:28:26 +01:00
}
2014-07-16 01:02:55 +01:00
2020-09-22 02:52:01 +02:00
function add_device ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2014-07-16 01:02:55 +01:00
// This will add a device using the data passed encoded with json
2022-03-15 06:54:02 -05:00
$data = $request -> json () -> all ();
2017-11-29 09:42:52 +00:00
2014-07-16 01:02:55 +01:00
if ( empty ( $data )) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'No information has been provided to add this new device' );
2017-11-29 09:42:52 +00:00
}
if ( empty ( $data [ 'hostname' ])) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Missing the device hostname' );
2014-07-16 01:02:55 +01:00
}
2015-07-13 20:10:26 +02:00
2022-03-15 06:54:02 -05:00
try {
$device = new Device ( Arr :: only ( $data , [
'hostname' ,
'display' ,
'overwrite_ip' ,
2023-10-18 02:00:39 -05:00
'location_id' ,
2022-03-15 06:54:02 -05:00
'port' ,
'transport' ,
'poller_group' ,
'snmpver' ,
'port_association_mode' ,
'community' ,
'authlevel' ,
'authname' ,
'authpass' ,
'authalgo' ,
'cryptopass' ,
'cryptoalgo' ,
]));
2023-10-18 02:00:39 -05:00
if ( ! empty ( $data [ 'location' ])) {
$device -> location_id = \App\Models\Location :: firstOrCreate ([ 'location' => $data [ 'location' ]]) -> id ;
}
2022-03-15 06:54:02 -05:00
// uses different name in legacy call
if ( ! empty ( $data [ 'version' ])) {
$device -> snmpver = $data [ 'version' ];
2015-07-13 20:10:26 +02:00
}
2024-08-27 07:08:19 -05:00
$force_add = ! empty ( $data [ 'force_add' ]);
2022-03-15 06:54:02 -05:00
if ( ! empty ( $data [ 'snmp_disable' ])) {
$device -> os = $data [ 'os' ] ?? 'ping' ;
$device -> sysName = $data [ 'sysName' ] ?? '' ;
$device -> hardware = $data [ 'hardware' ] ?? '' ;
$device -> snmp_disable = 1 ;
2024-08-27 07:08:19 -05:00
} elseif ( $force_add && ! $device -> hasSnmpInfo ()) {
return api_error ( 400 , 'SNMP information is required when force adding a device' );
2022-03-15 06:54:02 -05:00
}
2020-01-30 13:20:30 +01:00
2024-08-27 07:08:19 -05:00
( new ValidateDeviceAndCreate ( $device , $force_add , ! empty ( $data [ 'ping_fallback' ]))) -> execute ();
2017-11-29 09:42:52 +00:00
} catch ( Exception $e ) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , $e -> getMessage ());
2015-07-13 20:10:26 +02:00
}
2022-03-15 06:54:02 -05:00
$message = "Device $device->hostname ( $device->device_id ) has been added successfully" ;
2021-09-20 01:47:50 +02:00
2022-04-03 23:03:03 +10:00
return api_success ([ $device -> attributesToArray ()], 'devices' , $message );
2014-07-16 01:02:55 +01:00
}
2014-09-17 21:03:02 +01:00
2020-09-22 02:52:01 +02:00
function del_device ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2014-09-17 21:03:02 +01:00
// This will add a device using the data passed encoded with json
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2015-07-13 20:10:26 +02:00
2017-11-29 09:42:52 +00:00
if ( empty ( $hostname )) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'No hostname has been provided to delete' );
2017-11-29 09:42:52 +00:00
}
2015-07-13 20:10:26 +02:00
2017-11-29 09:42:52 +00:00
// allow deleting by device_id or hostname
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
$device = null ;
if ( $device_id ) {
// save the current details for returning to the client on successful delete
$device = device_by_id_cache ( $device_id );
2014-09-17 21:03:02 +01:00
}
2014-09-27 16:32:55 +10:00
2018-07-13 17:08:00 -05:00
if ( ! $device ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , "Device $hostname not found" );
2017-11-29 09:42:52 +00:00
}
$response = delete_device ( $device_id );
if ( empty ( $response )) {
// FIXME: Need to provide better diagnostics out of delete_device
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Device deletion failed' );
2017-11-29 09:42:52 +00:00
}
// deletion succeeded - include old device details in response
2019-07-29 16:32:37 -05:00
return api_success ([ $device ], 'devices' , $response );
2014-09-17 21:03:02 +01:00
}
2014-10-01 20:49:34 +01:00
2021-09-28 21:54:52 +02:00
function maintenance_device ( Illuminate\Http\Request $request )
{
if ( empty ( $request -> json ())) {
return api_error ( 400 , 'No information has been provided to set this device into maintenance' );
}
$hostname = $request -> route ( 'hostname' );
// use hostname as device_id if it's all digits
2022-07-29 00:38:46 +08:00
$device = ctype_digit ( $hostname ) ? Device :: find ( $hostname ) : Device :: findByHostname ( $hostname );
2021-09-28 21:54:52 +02:00
2022-07-29 00:38:46 +08:00
if ( is_null ( $device )) {
return api_error ( 404 , "Device $hostname not found" );
}
if ( ! $request -> json ( 'duration' )) {
return api_error ( 400 , 'Duration not provided' );
2021-09-28 21:54:52 +02:00
}
$notes = $request -> json ( 'notes' );
2022-07-29 00:38:46 +08:00
$title = $request -> json ( 'title' ) ?? $device -> displayName ();
2021-09-28 21:54:52 +02:00
$alert_schedule = new \App\Models\AlertSchedule ([
2022-07-29 00:38:46 +08:00
'title' => $title ,
2021-09-28 21:54:52 +02:00
'notes' => $notes ,
'recurring' => 0 ,
]);
2022-07-29 00:38:46 +08:00
$start = $request -> json ( 'start' ) ?? \Carbon\Carbon :: now () -> format ( 'Y-m-d H:i:00' );
$alert_schedule -> start = $start ;
2021-09-28 21:54:52 +02:00
$duration = $request -> json ( 'duration' );
2022-07-29 00:38:46 +08:00
2021-09-28 21:54:52 +02:00
if ( Str :: contains ( $duration , ':' )) {
[ $duration_hour , $duration_min ] = explode ( ':' , $duration );
2022-07-29 00:38:46 +08:00
$alert_schedule -> end = \Carbon\Carbon :: createFromFormat ( 'Y-m-d H:i:s' , $start )
2021-09-28 21:54:52 +02:00
-> addHours ( $duration_hour ) -> addMinutes ( $duration_min )
-> format ( 'Y-m-d H:i:00' );
}
2022-07-21 07:07:44 -05:00
$alert_schedule -> save ();
$alert_schedule -> devices () -> attach ( $device );
2021-09-28 21:54:52 +02:00
if ( $notes && UserPref :: getPref ( Auth :: user (), 'add_schedule_note_to_device' )) {
$device -> notes .= ( empty ( $device -> notes ) ? '' : PHP_EOL ) . date ( 'Y-m-d H:i' ) . ' Alerts delayed: ' . $notes ;
$device -> save ();
}
2022-07-29 00:38:46 +08:00
if ( $request -> json ( 'start' )) {
return api_success_noresult ( 201 , "Device { $device -> hostname } ( { $device -> device_id } ) will begin maintenance mode at $start " . ( $duration ? " for { $duration } h" : '' ));
} else {
return api_success_noresult ( 201 , "Device { $device -> hostname } ( { $device -> device_id } ) moved into maintenance mode" . ( $duration ? " for { $duration } h" : '' ));
}
2021-09-28 21:54:52 +02:00
}
2024-04-19 20:52:22 -04:00
function device_under_maintenance ( Illuminate\Http\Request $request )
{
// return whether or not a device is in an active maintenance window
$hostname = $request -> route ( 'hostname' );
if ( empty ( $hostname )) {
return api_error ( 400 , 'No hostname has been provided to get maintenance status' );
}
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
$model = null ;
if ( $device_id ) {
$model = DeviceCache :: get (( int ) $device_id );
}
if ( ! $model ) {
return api_error ( 404 , "Device $hostname not found" );
}
return check_device_permission ( $device_id , function () use ( $model ) {
$maintenance = $model -> isUnderMaintenance () ?? false ;
return api_success ( $maintenance , 'is_under_maintenance' );
});
}
2020-10-29 10:09:08 +00:00
function device_availability ( Illuminate\Http\Request $request )
2020-09-24 00:21:08 +02:00
{
// return availability per device
$hostname = $request -> route ( 'hostname' );
if ( empty ( $hostname )) {
return api_error ( 400 , 'No hostname has been provided to get availability' );
}
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
return check_device_permission ( $device_id , function ( $device_id ) {
$availabilities = Availability :: select ( 'duration' , 'availability_perc' )
2021-08-10 02:33:04 +02:00
-> where ( 'device_id' , '=' , $device_id )
-> orderBy ( 'duration' , 'ASC' );
2020-09-24 00:21:08 +02:00
return api_success ( $availabilities -> get (), 'availability' );
});
}
2020-10-29 10:09:08 +00:00
function device_outages ( Illuminate\Http\Request $request )
2020-09-24 00:21:08 +02:00
{
// return outages per device
$hostname = $request -> route ( 'hostname' );
if ( empty ( $hostname )) {
return api_error ( 400 , 'No hostname has been provided to get availability' );
}
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
return check_device_permission ( $device_id , function ( $device_id ) {
$outages = DeviceOutage :: select ( 'going_down' , 'up_again' )
2021-08-10 02:33:04 +02:00
-> where ( 'device_id' , '=' , $device_id )
-> orderBy ( 'going_down' , 'DESC' );
2020-09-24 00:21:08 +02:00
return api_success ( $outages -> get (), 'outages' );
});
}
2020-09-22 02:52:01 +02:00
function get_vlans ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2017-11-29 09:42:52 +00:00
2014-10-01 20:53:15 +01:00
if ( empty ( $hostname )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'No hostname has been provided' );
2017-11-29 09:42:52 +00:00
}
2015-07-13 20:10:26 +02:00
2017-11-29 09:42:52 +00:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
$device = null ;
if ( $device_id ) {
// save the current details for returning to the client on successful delete
$device = device_by_id_cache ( $device_id );
2014-10-01 20:49:34 +01:00
}
2015-07-13 20:10:26 +02:00
2017-11-29 09:42:52 +00:00
if ( ! $device ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , "Device $hostname not found" );
2017-11-29 09:42:52 +00:00
}
2019-07-29 16:32:37 -05:00
return check_device_permission ( $device_id , function ( $device_id ) {
$vlans = dbFetchRows ( 'SELECT vlan_vlan,vlan_domain,vlan_name,vlan_type,vlan_mtu FROM vlans WHERE `device_id` = ?' , [ $device_id ]);
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $vlans , 'vlans' );
});
2014-10-01 20:49:34 +01:00
}
2014-10-09 16:20:04 +00:00
2020-09-22 02:52:01 +02:00
function show_endpoints ( Illuminate\Http\Request $request , Router $router )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$output = [];
$base = str_replace ( 'api/v0' , '' , $request -> url ());
foreach ( $router -> getRoutes () as $route ) {
/** @var \Illuminate\Routing\Route $route */
2020-04-17 17:37:56 -05:00
if ( Str :: startsWith ( $route -> getPrefix (), 'api/v0' ) && $route -> getName ()) {
2019-07-29 16:32:37 -05:00
$output [ $route -> getName ()] = $base . $route -> uri ();
}
2014-10-09 16:20:04 +00:00
}
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
ksort ( $output );
return response () -> json ( $output , 200 , [], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES );
2014-10-09 16:20:04 +00:00
}
2014-10-26 15:48:51 +00:00
2020-09-22 02:52:01 +02:00
function list_bgp ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2014-10-29 21:30:35 +00:00
$sql = '' ;
2019-07-29 16:32:37 -05:00
$sql_params = [];
$hostname = $request -> get ( 'hostname' );
$asn = $request -> get ( 'asn' );
2020-02-26 14:29:44 +01:00
$remote_asn = $request -> get ( 'remote_asn' );
2020-04-05 17:16:16 +02:00
$local_address = $request -> get ( 'local_address' );
$remote_address = $request -> get ( 'remote_address' );
2023-11-29 21:58:30 +01:00
$bgp_descr = $request -> get ( 'bgp_descr' );
$bgp_state = $request -> get ( 'bgp_state' );
$bgp_adminstate = $request -> get ( 'bgp_adminstate' );
$bgp_family = $request -> get ( 'bgp_family' );
2014-10-26 15:48:51 +00:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
if ( is_numeric ( $device_id )) {
2020-02-26 14:29:44 +01:00
$sql .= ' AND `devices`.`device_id` = ?' ;
2017-03-13 02:17:09 +00:00
$sql_params [] = $device_id ;
}
if ( ! empty ( $asn )) {
2020-02-26 14:29:44 +01:00
$sql .= ' AND `devices`.`bgpLocalAs` = ?' ;
2023-11-29 21:58:30 +01:00
$sql_params [] = preg_replace ( '/[^0-9]/' , '' , $asn );
2014-10-26 15:48:51 +00:00
}
2020-02-26 14:29:44 +01:00
if ( ! empty ( $remote_asn )) {
$sql .= ' AND `bgpPeers`.`bgpPeerRemoteAs` = ?' ;
2023-11-29 21:58:30 +01:00
$sql_params [] = preg_replace ( '/[^0-9]/' , '' , $remote_asn );
2020-02-26 14:29:44 +01:00
}
2020-04-05 17:16:16 +02:00
if ( ! empty ( $local_address )) {
$sql .= ' AND `bgpPeers`.`bgpLocalAddr` = ?' ;
2020-04-12 01:11:57 +02:00
try {
$sql_params [] = IP :: parse ( $local_address ) -> uncompressed ();
} catch ( InvalidIpException $e ) {
return api_error ( 400 , 'Invalid local address' );
}
2020-04-05 17:16:16 +02:00
}
if ( ! empty ( $remote_address )) {
$sql .= ' AND `bgpPeers`.`bgpPeerIdentifier` = ?' ;
2020-04-12 01:11:57 +02:00
try {
$sql_params [] = IP :: parse ( $remote_address ) -> uncompressed ();
} catch ( InvalidIpException $e ) {
return api_error ( 400 , 'Invalid remote address' );
}
2020-04-05 17:16:16 +02:00
}
2023-11-29 21:58:30 +01:00
if ( ! empty ( $bgp_descr )) {
$sql .= ' AND `bgpPeers`.`bgpPeerDescr` LIKE ?' ;
$sql_params [] = "% $bgp_descr %" ;
}
if ( ! empty ( $bgp_state )) {
$sql .= ' AND `bgpPeers`.`bgpPeerState` = ?' ;
$sql_params [] = $bgp_state ;
}
if ( ! empty ( $bgp_adminstate )) {
$sql .= ' AND `bgpPeers`.`bgpPeerAdminStatus` = ?' ;
$sql_params [] = $bgp_adminstate ;
}
if ( ! empty ( $bgp_family )) {
if ( $bgp_family == 4 ) {
$sql .= ' AND `bgpPeers`.`bgpLocalAddr` LIKE \'%.%\'' ;
} elseif ( $bgp_family == 6 ) {
$sql .= ' AND `bgpPeers`.`bgpLocalAddr` LIKE \'%:%\'' ;
}
}
2015-07-13 20:10:26 +02:00
2017-03-13 02:17:09 +00:00
$bgp_sessions = dbFetchRows ( "SELECT `bgpPeers`.* FROM `bgpPeers` LEFT JOIN `devices` ON `bgpPeers`.`device_id` = `devices`.`device_id` WHERE `bgpPeerState` IS NOT NULL AND `bgpPeerState` != '' $sql " , $sql_params );
2014-10-26 15:48:51 +00:00
$total_bgp_sessions = count ( $bgp_sessions );
2017-11-29 09:42:52 +00:00
if ( ! is_numeric ( $total_bgp_sessions )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Error retrieving bgpPeers' );
2014-10-29 21:30:35 +00:00
}
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $bgp_sessions , 'bgp_sessions' );
2017-09-07 20:04:36 +01:00
}
2020-09-22 02:52:01 +02:00
function get_bgp ( Illuminate\Http\Request $request )
2017-11-30 22:51:20 +00:00
{
2019-07-29 16:32:37 -05:00
$bgpPeerId = $request -> route ( 'id' );
2017-11-30 22:51:20 +00:00
if ( ! is_numeric ( $bgpPeerId )) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Invalid id has been provided' );
2017-11-30 22:51:20 +00:00
}
2019-07-29 16:32:37 -05:00
$bgp_session = dbFetchRows ( "SELECT * FROM `bgpPeers` WHERE `bgpPeerState` IS NOT NULL AND `bgpPeerState` != '' AND bgpPeer_id = ?" , [ $bgpPeerId ]);
2017-11-30 22:51:20 +00:00
$bgp_session_count = count ( $bgp_session );
if ( ! is_numeric ( $bgp_session_count )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Error retrieving BGP peer' );
2017-11-30 22:51:20 +00:00
}
if ( $bgp_session_count == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , "BGP peer $bgpPeerId does not exist" );
2017-11-30 22:51:20 +00:00
}
2019-07-29 16:32:37 -05:00
return api_success ( $bgp_session , 'bgp_session' );
2017-11-30 22:51:20 +00:00
}
2021-08-13 00:58:47 +02:00
function edit_bgp_descr ( Illuminate\Http\Request $request )
{
$bgp_descr = $request -> json ( 'bgp_descr' );
if ( ! $bgp_descr ) {
return api_error ( 500 , 'Invalid JSON data' );
}
//find existing bgp for update
$bgpPeerId = $request -> route ( 'id' );
if ( ! is_numeric ( $bgpPeerId )) {
return api_error ( 400 , 'Invalid id has been provided' );
}
$peer = \App\Models\BgpPeer :: firstWhere ( 'bgpPeer_id' , $bgpPeerId );
// update existing bgp
if ( $peer === null ) {
return api_error ( 404 , 'BGP peer ' . $bgpPeerId . ' does not exist' );
}
$peer -> bgpPeerDescr = $bgp_descr ;
if ( $peer -> save ()) {
return api_success_noresult ( 200 , 'BGP description for peer ' . $peer -> bgpPeerIdentifier . ' on device ' . $peer -> device_id . ' updated to ' . $peer -> bgpPeerDescr . '.' );
}
return api_error ( 500 , 'Failed to update existing bgp' );
}
2020-09-22 02:52:01 +02:00
function list_cbgp ( Illuminate\Http\Request $request )
2018-01-18 18:43:15 +03:00
{
$sql = '' ;
2019-07-29 16:32:37 -05:00
$sql_params = [];
$hostname = $request -> get ( 'hostname' );
2018-01-18 18:43:15 +03:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
if ( is_numeric ( $device_id )) {
2019-07-29 16:32:37 -05:00
$permission = check_device_permission ( $device_id );
if ( $permission !== true ) {
return $permission ; // permission error
}
2018-01-18 18:43:15 +03:00
$sql = ' AND `devices`.`device_id` = ?' ;
$sql_params [] = $device_id ;
}
2019-07-29 16:32:37 -05:00
if ( ! Auth :: user () -> hasGlobalRead ()) {
2018-01-18 18:43:15 +03:00
$sql .= ' AND `bgpPeers_cbgp`.`device_id` IN (SELECT device_id FROM devices_perms WHERE user_id = ?)' ;
2019-07-29 16:32:37 -05:00
$sql_params [] = Auth :: id ();
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
$bgp_counters = dbFetchRows ( "SELECT `bgpPeers_cbgp`.* FROM `bgpPeers_cbgp` LEFT JOIN `devices` ON `bgpPeers_cbgp`.`device_id` = `devices`.`device_id` WHERE `bgpPeers_cbgp`.`device_id` IS NOT NULL $sql " , $sql_params );
2018-01-18 18:43:15 +03:00
$total_bgp_counters = count ( $bgp_counters );
if ( $total_bgp_counters == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'BGP counters does not exist' );
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
return api_success ( $bgp_counters , 'bgp_counters' );
2018-01-18 18:43:15 +03:00
}
2020-09-22 02:52:01 +02:00
function list_ospf ( Illuminate\Http\Request $request )
2017-09-07 20:04:36 +01:00
{
$sql = '' ;
2019-07-29 16:32:37 -05:00
$sql_params = [];
$hostname = $request -> get ( 'hostname' );
2017-09-07 20:04:36 +01:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
if ( is_numeric ( $device_id )) {
$sql = ' AND `device_id`=?' ;
2019-07-29 16:32:37 -05:00
$sql_params = [ $device_id ];
2017-09-07 20:04:36 +01:00
}
$ospf_neighbours = dbFetchRows ( "SELECT * FROM ospf_nbrs WHERE `ospfNbrState` IS NOT NULL AND `ospfNbrState` != '' $sql " , $sql_params );
$total_ospf_neighbours = count ( $ospf_neighbours );
2017-11-29 09:42:52 +00:00
if ( ! is_numeric ( $total_ospf_neighbours )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Error retrieving ospf_nbrs' );
2017-09-07 20:04:36 +01:00
}
2019-07-29 16:32:37 -05:00
return api_success ( $ospf_neighbours , 'ospf_neighbours' );
2014-10-26 15:48:51 +00:00
}
2014-11-12 23:05:47 +00:00
2021-06-16 21:31:05 +03:00
function list_ospf_ports ( Illuminate\Http\Request $request )
{
$ospf_ports = OspfPort :: hasAccess ( Auth :: user ())
2021-08-10 02:33:04 +02:00
-> get ();
2021-06-16 21:31:05 +03:00
if ( $ospf_ports -> isEmpty ()) {
return api_error ( 404 , 'Ospf ports do not exist' );
}
return api_success ( $ospf_ports , 'ospf_ports' , null , 200 , $ospf_ports -> count ());
}
2022-11-03 01:08:52 -05:00
function get_graph_by_portgroup ( Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$id = $request -> route ( 'id' );
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
if ( empty ( $id )) {
2022-11-03 01:08:52 -05:00
$group = $request -> route ( 'group' );
2017-03-13 02:17:09 +00:00
$ports = get_ports_from_type ( explode ( ',' , $group ));
2020-04-17 17:37:56 -05:00
$if_list = implode ( ',' , Arr :: pluck ( $ports , 'port_id' ));
2019-07-29 16:32:37 -05:00
} else {
$if_list = $id ;
2017-03-13 02:17:09 +00:00
}
2015-07-13 20:10:26 +02:00
2022-11-03 01:08:52 -05:00
return api_get_graph ( $request , [
2024-01-05 05:39:12 +01:00
'type' => 'multiport_bits_separate' ,
2022-11-03 01:08:52 -05:00
'id' => $if_list ,
]);
2014-11-12 23:05:47 +00:00
}
2014-11-29 15:43:19 +00:00
2020-09-22 02:52:01 +02:00
function get_components ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2015-08-15 16:01:43 +10:00
// Do some filtering if the user requests.
2019-07-29 16:32:37 -05:00
$options = [];
// Add the rest of the options with an equals query
foreach ( $request -> all () as $k => $v ) {
$options [ 'filter' ][ $k ] = [ '=' , $v ];
}
2016-01-14 05:22:37 +10:00
// We need to specify the label as this is a LIKE query
2019-07-29 16:32:37 -05:00
if ( $request -> has ( 'label' )) {
2015-08-15 16:01:43 +10:00
// set a label like filter
2019-07-29 16:32:37 -05:00
$options [ 'filter' ][ 'label' ] = [ 'LIKE' , $request -> get ( 'label' )];
2015-08-15 16:01:43 +10:00
}
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2019-07-29 16:32:37 -05:00
return check_device_permission ( $device_id , function ( $device_id ) use ( $options ) {
$COMPONENT = new LibreNMS\Component ();
$components = $COMPONENT -> getComponents ( $device_id , $options );
return api_success ( $components [ $device_id ], 'components' );
});
2015-08-15 16:01:43 +10:00
}
2020-09-22 02:52:01 +02:00
function add_components ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
$ctype = $request -> route ( 'type' );
2016-03-30 16:39:39 +10:00
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2016-08-21 08:07:14 -05:00
$COMPONENT = new LibreNMS\Component ();
2016-08-18 20:28:22 -05:00
$component = $COMPONENT -> createComponent ( $device_id , $ctype );
2016-03-30 16:39:39 +10:00
2019-07-29 16:32:37 -05:00
return api_success ( $component , 'components' );
2016-03-30 16:39:39 +10:00
}
2020-09-22 02:52:01 +02:00
function edit_components ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
$data = json_decode ( $request -> getContent (), true );
2016-03-30 16:39:39 +10:00
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2016-08-21 08:07:14 -05:00
$COMPONENT = new LibreNMS\Component ();
2016-03-30 16:39:39 +10:00
2017-11-29 09:42:52 +00:00
if ( ! $COMPONENT -> setComponentPrefs ( $device_id , $data )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Components could not be edited.' );
2016-03-30 16:39:39 +10:00
}
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 200 );
2016-03-30 16:39:39 +10:00
}
2020-09-22 02:52:01 +02:00
function delete_components ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$cid = $request -> route ( 'component' );
2016-03-30 16:39:39 +10:00
2016-08-21 08:07:14 -05:00
$COMPONENT = new LibreNMS\Component ();
2016-03-30 16:39:39 +10:00
if ( $COMPONENT -> deleteComponent ( $cid )) {
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 200 );
2016-08-18 20:28:22 -05:00
} else {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Components could not be deleted.' );
2016-03-30 16:39:39 +10:00
}
}
2020-09-22 02:52:01 +02:00
function get_graphs ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2014-11-29 15:43:19 +00:00
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return check_device_permission ( $device_id , function ( $device_id ) {
$graphs = [];
$graphs [] = [
'desc' => 'Poller Time' ,
'name' => 'device_poller_perf' ,
];
$graphs [] = [
'desc' => 'Ping Response' ,
2024-04-18 09:57:01 -05:00
'name' => 'device_icmp_perf' ,
2019-07-29 16:32:37 -05:00
];
foreach ( dbFetchRows ( 'SELECT * FROM device_graphs WHERE device_id = ? ORDER BY graph' , [ $device_id ]) as $graph ) {
$desc = Config :: get ( "graph_types.device. { $graph [ 'graph' ] } .descr" );
$graphs [] = [
'desc' => $desc ,
'name' => 'device_' . $graph [ 'graph' ],
];
}
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $graphs , 'graphs' );
});
2014-11-29 15:43:19 +00:00
}
2014-12-01 20:27:50 +00:00
2020-09-22 02:52:01 +02:00
function trigger_device_discovery ( Illuminate\Http\Request $request )
2019-12-08 22:17:27 +01:00
{
// return details of a single device
$hostname = $request -> route ( 'hostname' );
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
// find device matching the id
$device = device_by_id_cache ( $device_id );
if ( ! $device ) {
return api_error ( 404 , "Device $hostname does not exist" );
}
$ret = device_discovery_trigger ( $device_id );
2020-09-21 15:40:17 +02:00
2019-12-08 22:17:27 +01:00
return api_success ( $ret , 'result' );
}
2020-09-22 02:52:01 +02:00
function list_available_health_graphs ( Illuminate\Http\Request $request )
2017-01-19 10:09:20 +00:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2017-01-19 10:09:20 +00:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2019-07-29 16:32:37 -05:00
return check_device_permission ( $device_id , function ( $device_id ) use ( $request ) {
$input_type = $request -> route ( 'type' );
if ( $input_type ) {
$type = preg_replace ( '/^device_/' , '' , $input_type );
2017-01-19 10:09:20 +00:00
}
2019-07-29 16:32:37 -05:00
$sensor_id = $request -> route ( 'sensor_id' );
$graphs = [];
2018-05-19 00:36:06 -04:00
2019-07-29 16:32:37 -05:00
if ( isset ( $type )) {
if ( isset ( $sensor_id )) {
$graphs = dbFetchRows ( 'SELECT * FROM `sensors` WHERE `sensor_id` = ?' , [ $sensor_id ]);
} else {
foreach ( dbFetchRows ( 'SELECT `sensor_id`, `sensor_descr` FROM `sensors` WHERE `device_id` = ? AND `sensor_class` = ? AND `sensor_deleted` = 0' , [ $device_id , $type ]) as $graph ) {
$graphs [] = [
'sensor_id' => $graph [ 'sensor_id' ],
'desc' => $graph [ 'sensor_descr' ],
];
}
2018-05-19 00:36:06 -04:00
}
2019-07-29 16:32:37 -05:00
} else {
foreach ( dbFetchRows ( 'SELECT `sensor_class` FROM `sensors` WHERE `device_id` = ? AND `sensor_deleted` = 0 GROUP BY `sensor_class`' , [ $device_id ]) as $graph ) {
$graphs [] = [
'desc' => ucfirst ( $graph [ 'sensor_class' ]),
'name' => 'device_' . $graph [ 'sensor_class' ],
];
2018-05-19 00:36:06 -04:00
}
2019-07-29 16:32:37 -05:00
$device = Device :: find ( $device_id );
if ( $device ) {
if ( $device -> processors () -> count () > 0 ) {
array_push ( $graphs , [
'desc' => 'Processors' ,
'name' => 'device_processor' ,
]);
}
2018-07-09 14:23:38 -05:00
2019-07-29 16:32:37 -05:00
if ( $device -> storage () -> count () > 0 ) {
array_push ( $graphs , [
'desc' => 'Storage' ,
'name' => 'device_storage' ,
]);
}
if ( $device -> mempools () -> count () > 0 ) {
array_push ( $graphs , [
'desc' => 'Memory Pools' ,
'name' => 'device_mempool' ,
]);
}
2018-05-19 00:36:06 -04:00
}
}
2017-01-19 10:09:20 +00:00
2019-07-29 16:32:37 -05:00
return api_success ( $graphs , 'graphs' );
});
2017-01-19 10:09:20 +00:00
}
2015-07-13 20:10:26 +02:00
2020-09-22 02:52:01 +02:00
function list_available_wireless_graphs ( Illuminate\Http\Request $request )
2017-12-06 22:27:30 +00:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2017-12-06 22:27:30 +00:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return check_device_permission ( $device_id , function ( $device_id ) use ( $request ) {
$input_type = $request -> route ( 'type' );
if ( $input_type ) {
[, , $type ] = explode ( '_' , $input_type );
}
$sensor_id = $request -> route ( 'sensor_id' );
$graphs = [];
2017-12-06 22:27:30 +00:00
2019-07-29 16:32:37 -05:00
if ( isset ( $type )) {
if ( isset ( $sensor_id )) {
$graphs = dbFetchRows ( 'SELECT * FROM `wireless_sensors` WHERE `sensor_id` = ?' , [ $sensor_id ]);
} else {
foreach ( dbFetchRows ( 'SELECT `sensor_id`, `sensor_descr` FROM `wireless_sensors` WHERE `device_id` = ? AND `sensor_class` = ? AND `sensor_deleted` = 0' , [ $device_id , $type ]) as $graph ) {
$graphs [] = [
'sensor_id' => $graph [ 'sensor_id' ],
2024-01-05 05:39:12 +01:00
'desc' => $graph [ 'sensor_descr' ],
2019-07-29 16:32:37 -05:00
];
}
}
2017-12-06 22:27:30 +00:00
} else {
2019-07-29 16:32:37 -05:00
foreach ( dbFetchRows ( 'SELECT `sensor_class` FROM `wireless_sensors` WHERE `device_id` = ? AND `sensor_deleted` = 0 GROUP BY `sensor_class`' , [ $device_id ]) as $graph ) {
$graphs [] = [
'desc' => ucfirst ( $graph [ 'sensor_class' ]),
'name' => 'device_wireless_' . $graph [ 'sensor_class' ],
];
2017-12-06 22:27:30 +00:00
}
}
2019-07-29 16:32:37 -05:00
return api_success ( $graphs , 'graphs' );
});
2017-12-06 22:27:30 +00:00
}
2022-11-18 16:27:56 -06:00
/**
* @throws \LibreNMS\Exceptions\ApiException
*/
function get_port_graphs ( Illuminate\Http\Request $request ) : JsonResponse
2016-08-18 20:28:22 -05:00
{
2022-11-18 16:27:56 -06:00
$device = DeviceCache :: get ( $request -> route ( 'hostname' ));
$columns = validate_column_list ( $request -> get ( 'columns' ), 'ports' , [ 'ifName' ]);
2017-12-02 16:53:45 -06:00
2022-11-18 16:27:56 -06:00
$ports = $device -> ports () -> isNotDeleted () -> hasAccess ( Auth :: user ())
-> select ( $columns ) -> orderBy ( 'ifIndex' ) -> get ();
2020-09-21 15:40:17 +02:00
2024-05-21 22:05:44 -05:00
if ( $ports -> isEmpty ()) {
return api_error ( 404 , 'No ports found' );
}
2019-07-29 16:32:37 -05:00
return api_success ( $ports , 'ports' );
2014-11-30 15:45:10 +00:00
}
2014-12-02 23:43:11 +00:00
2020-09-22 02:52:01 +02:00
function get_device_ip_addresses ( Illuminate\Http\Request $request )
2017-02-07 02:46:09 -07:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return check_device_permission ( $device_id , function ( $device_id ) {
$ipv4 = dbFetchRows ( 'SELECT `ipv4_addresses`.* FROM `ipv4_addresses` JOIN `ports` ON `ports`.`port_id`=`ipv4_addresses`.`port_id` WHERE `ports`.`device_id` = ? AND `deleted` = 0' , [ $device_id ]);
$ipv6 = dbFetchRows ( 'SELECT `ipv6_addresses`.* FROM `ipv6_addresses` JOIN `ports` ON `ports`.`port_id`=`ipv6_addresses`.`port_id` WHERE `ports`.`device_id` = ? AND `deleted` = 0' , [ $device_id ]);
2018-01-18 18:43:15 +03:00
$ip_addresses_count = count ( array_merge ( $ipv4 , $ipv6 ));
if ( $ip_addresses_count == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , "Device $device_id does not have any IP addresses" );
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
return api_success ( array_merge ( $ipv4 , $ipv6 ), 'addresses' );
});
}
2020-09-22 02:52:01 +02:00
function get_port_ip_addresses ( Illuminate\Http\Request $request )
2019-07-29 16:32:37 -05:00
{
$port_id = $request -> route ( 'portid' );
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return check_port_permission ( $port_id , null , function ( $port_id ) {
$ipv4 = dbFetchRows ( 'SELECT * FROM `ipv4_addresses` WHERE `port_id` = ?' , [ $port_id ]);
$ipv6 = dbFetchRows ( 'SELECT * FROM `ipv6_addresses` WHERE `port_id` = ?' , [ $port_id ]);
2018-01-18 18:43:15 +03:00
$ip_addresses_count = count ( array_merge ( $ipv4 , $ipv6 ));
if ( $ip_addresses_count == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , "Port $port_id does not have any IP addresses" );
2018-01-18 18:43:15 +03:00
}
2017-02-07 02:46:09 -07:00
2019-07-29 16:32:37 -05:00
return api_success ( array_merge ( $ipv4 , $ipv6 ), 'addresses' );
});
2017-02-07 02:46:09 -07:00
}
2020-09-22 02:52:01 +02:00
function get_network_ip_addresses ( Illuminate\Http\Request $request )
2017-02-07 02:46:09 -07:00
{
2019-07-29 16:32:37 -05:00
$network_id = $request -> route ( 'id' );
$ipv4 = dbFetchRows ( 'SELECT * FROM `ipv4_addresses` WHERE `ipv4_network_id` = ?' , [ $network_id ]);
$ipv6 = dbFetchRows ( 'SELECT * FROM `ipv6_addresses` WHERE `ipv6_network_id` = ?' , [ $network_id ]);
$ip_addresses_count = count ( array_merge ( $ipv4 , $ipv6 ));
if ( $ip_addresses_count == 0 ) {
return api_error ( 404 , "IP network $network_id does not exist or is empty" );
}
2017-02-07 02:46:09 -07:00
2019-07-29 16:32:37 -05:00
return api_success ( array_merge ( $ipv4 , $ipv6 ), 'addresses' );
2017-02-07 02:46:09 -07:00
}
2024-09-29 11:05:44 -05:00
function get_port_transceiver ( Illuminate\Http\Request $request )
{
$port_id = $request -> route ( 'portid' );
return check_port_permission ( $port_id , null , function ( $port_id ) {
$transceivers = Port :: find ( $port_id ) -> transceivers () -> get ();
return api_success ( $transceivers , 'transceivers' );
});
}
2020-09-22 02:52:01 +02:00
function get_port_info ( Illuminate\Http\Request $request )
2017-02-07 02:46:09 -07:00
{
2019-07-29 16:32:37 -05:00
$port_id = $request -> route ( 'portid' );
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return check_port_permission ( $port_id , null , function ( $port_id ) {
// use hostname as device_id if it's all digits
2021-04-26 21:30:30 +02:00
$port = dbFetchRows ( 'SELECT * FROM `ports` WHERE `port_id` = ?' , [ $port_id ]);
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $port , 'port' );
});
}
2024-01-22 23:07:13 +00:00
function update_port_description ( Illuminate\Http\Request $request )
{
$port_id = $request -> route ( 'portid' );
$port = Port :: hasAccess ( Auth :: user ())
-> where ([
'port_id' => $port_id ,
]) -> first ();
if ( empty ( $port )) {
return api_error ( 400 , 'Invalid port ID.' );
}
$data = json_decode ( $request -> getContent (), true );
$field = 'description' ;
$description = $data [ $field ];
if ( empty ( $description )) {
// from update-ifalias.inc.php:
// "Set to repoll so we avoid using ifDescr on port poll"
$description = 'repoll' ;
}
$port -> ifAlias = $description ;
$port -> save ();
$ifName = $port -> ifName ;
$device = $port -> device_id ;
if ( $description == 'repoll' ) {
// No description provided, clear description
del_dev_attrib ( $port , 'ifName:' . $ifName ); // "port" object has required device_id
log_event ( " $ifName Port ifAlias cleared via API" , $device , 'interface' , 3 , $port_id );
return api_success_noresult ( 200 , 'Port description cleared.' );
} else {
// Prevent poller from overwriting new description
set_dev_attrib ( $port , 'ifName:' . $ifName , 1 ); // see above
log_event ( " $ifName Port ifAlias set via API: $description " , $device , 'interface' , 3 , $port_id );
return api_success_noresult ( 200 , 'Port description updated.' );
}
}
function get_port_description ( Illuminate\Http\Request $request )
{
$port_id = $request -> route ( 'portid' );
$port = Port :: hasAccess ( Auth :: user ())
-> where ([
'port_id' => $port_id ,
]) -> first ();
if ( empty ( $port )) {
return api_error ( 400 , 'Invalid port ID.' );
} else {
return api_success ( $port -> ifAlias , 'port_description' );
}
}
2022-11-18 16:27:56 -06:00
/**
* @throws \LibreNMS\Exceptions\ApiException
*/
function search_ports ( Illuminate\Http\Request $request ) : JsonResponse
2020-05-25 00:16:07 +02:00
{
2023-09-14 08:45:20 -05:00
$columns = validate_column_list ( $request -> get ( 'columns' ), 'ports' , [ 'device_id' , 'port_id' , 'ifIndex' , 'ifName' , 'ifAlias' ]);
2021-09-20 02:28:42 +02:00
$field = $request -> route ( 'field' );
2020-05-25 00:16:07 +02:00
$search = $request -> route ( 'search' );
2021-09-20 02:28:42 +02:00
2022-11-18 16:27:56 -06:00
// if only field is set, swap values
if ( empty ( $search )) {
[ $field , $search ] = [ $search , $field ];
2021-09-20 02:28:42 +02:00
}
2022-11-18 16:27:56 -06:00
$fields = validate_column_list ( $field , 'ports' , [ 'ifAlias' , 'ifDescr' , 'ifName' ]);
2021-09-20 02:28:42 +02:00
2022-11-18 16:27:56 -06:00
$ports = Port :: hasAccess ( Auth :: user ())
-> isNotDeleted ()
-> where ( function ( $query ) use ( $fields , $search ) {
foreach ( $fields as $field ) {
$query -> orWhere ( $field , 'like' , "% $search %" );
}
})
-> select ( $columns )
-> orderBy ( 'ifName' )
-> get ();
2020-05-25 00:16:07 +02:00
if ( $ports -> isEmpty ()) {
return api_error ( 404 , 'No ports found' );
}
return api_success ( $ports , 'ports' );
}
2022-11-18 16:27:56 -06:00
/**
* @throws \LibreNMS\Exceptions\ApiException
*/
function get_all_ports ( Illuminate\Http\Request $request ) : JsonResponse
2019-07-29 16:32:37 -05:00
{
2022-11-18 16:27:56 -06:00
$columns = validate_column_list ( $request -> get ( 'columns' ), 'ports' , [ 'port_id' , 'ifName' ]);
2019-07-29 16:32:37 -05:00
2022-11-18 16:27:56 -06:00
$ports = Port :: hasAccess ( Auth :: user ())
-> select ( $columns )
-> isNotDeleted ()
-> get ();
2017-02-07 02:46:09 -07:00
2019-07-29 16:32:37 -05:00
return api_success ( $ports , 'ports' );
2017-02-07 02:46:09 -07:00
}
2020-09-22 02:52:01 +02:00
function get_port_stack ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2024-07-26 08:45:34 -05:00
$device = DeviceCache :: get ( $hostname );
2016-04-05 14:25:45 -07:00
2024-07-26 08:45:34 -05:00
return check_device_permission ( $device -> device_id , function () use ( $device ) {
return api_success ( $device -> portsStack , 'mappings' );
2019-07-29 16:32:37 -05:00
});
2016-04-05 13:03:17 -07:00
}
2022-11-18 16:27:56 -06:00
function update_device_port_notes ( Illuminate\Http\Request $request ) : JsonResponse
2022-03-10 15:29:08 -06:00
{
$portid = $request -> route ( 'portid' );
$hostname = $request -> route ( 'hostname' );
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
$data = json_decode ( $request -> getContent (), true );
$field = 'notes' ;
$content = $data [ $field ];
if ( empty ( $data )) {
return api_error ( 400 , 'Port field to patch has not been supplied.' );
}
if ( set_dev_attrib ( $device_id , 'port_id_notes:' . $portid , $content )) {
return api_success_noresult ( 200 , 'Port ' . $field . ' field has been updated' );
} else {
return api_error ( 500 , 'Port ' . $field . ' field failed to be updated' );
}
}
2020-09-22 02:52:01 +02:00
function list_alert_rules ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$id = $request -> route ( 'id' );
2015-07-13 20:10:26 +02:00
2022-11-09 15:21:41 +01:00
$rules = \App\Http\Resources\AlertRule :: collection (
\App\Models\AlertRule :: when ( $id , fn ( $query ) => $query -> where ( 'id' , $id ))
-> with ([ 'devices:device_id' , 'groups:id' , 'locations:id' ]) -> get ()
);
2020-09-21 15:40:17 +02:00
2022-11-09 15:21:41 +01:00
return api_success ( $rules -> toArray ( $request ), 'rules' );
2014-12-16 20:39:58 +00:00
}
2022-11-18 16:27:56 -06:00
/**
* @throws \LibreNMS\Exceptions\ApiException
*/
function list_alerts ( Illuminate\Http\Request $request ) : JsonResponse
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$id = $request -> route ( 'id' );
2018-08-26 07:42:21 -05:00
2019-07-29 16:32:37 -05:00
$sql = 'SELECT `D`.`hostname`, `A`.*, `R`.`severity` FROM `alerts` AS `A`, `devices` AS `D`, `alert_rules` AS `R` WHERE `D`.`device_id` = `A`.`device_id` AND `A`.`rule_id` = `R`.`id` ' ;
$sql .= 'AND `A`.`state` IN ' ;
if ( $request -> has ( 'state' )) {
$param = explode ( ',' , $request -> get ( 'state' ));
2016-08-18 20:28:22 -05:00
} else {
2018-08-26 07:42:21 -05:00
$param = [ 1 ];
2014-12-16 20:39:58 +00:00
}
2018-08-26 07:42:21 -05:00
$sql .= dbGenPlaceholders ( count ( $param ));
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
if ( $id > 0 ) {
$param [] = $id ;
2018-08-26 07:42:21 -05:00
$sql .= 'AND `A`.id=?' ;
2014-12-16 20:39:58 +00:00
}
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
$severity = $request -> get ( 'severity' );
if ( $severity ) {
2018-08-28 18:44:47 +02:00
if ( in_array ( $severity , [ 'ok' , 'warning' , 'critical' ])) {
$param [] = $severity ;
$sql .= ' AND `R`.severity=?' ;
}
}
2019-11-05 15:16:29 -06:00
2019-07-29 16:32:37 -05:00
$order = 'timestamp desc' ;
2020-05-25 00:16:07 +02:00
2020-02-11 19:04:55 +01:00
$alert_rule = $request -> get ( 'alert_rule' );
if ( isset ( $alert_rule )) {
if ( is_numeric ( $alert_rule )) {
$param [] = $alert_rule ;
$sql .= ' AND `R`.id=?' ;
}
}
2020-05-25 00:16:07 +02:00
2019-07-29 16:32:37 -05:00
if ( $request -> has ( 'order' )) {
[ $sort_column , $sort_order ] = explode ( ' ' , $request -> get ( 'order' ), 2 );
2022-11-18 16:27:56 -06:00
validate_column_list ( $sort_column , 'alerts' );
2019-07-29 16:32:37 -05:00
if ( in_array ( $sort_order , [ 'asc' , 'desc' ])) {
$order = $request -> get ( 'order' );
}
}
2018-08-28 18:44:47 +02:00
$sql .= ' ORDER BY A.' . $order ;
2018-08-26 07:42:21 -05:00
$alerts = dbFetchRows ( $sql , $param );
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $alerts , 'alerts' );
2014-12-16 20:39:58 +00:00
}
2020-09-22 02:52:01 +02:00
function add_edit_rule ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$data = json_decode ( $request -> getContent (), true );
if ( json_last_error () || ! is_array ( $data )) {
return api_error ( 500 , "We couldn't parse the provided json" );
2018-09-19 13:47:45 +01:00
}
2014-12-16 20:39:58 +00:00
2019-07-29 16:32:37 -05:00
$rule_id = $data [ 'rule_id' ];
$tmp_devices = ( array ) $data [ 'devices' ];
2018-09-19 13:47:45 +01:00
$groups = ( array ) $data [ 'groups' ];
2020-02-12 19:53:26 +01:00
$locations = ( array ) $data [ 'locations' ];
2018-09-19 13:47:45 +01:00
if ( empty ( $tmp_devices ) && ! isset ( $rule_id )) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Missing the devices or global device (-1)' );
2017-11-29 09:42:52 +00:00
}
2017-12-02 16:53:45 -06:00
2018-09-19 13:47:45 +01:00
$devices = [];
foreach ( $tmp_devices as $device ) {
if ( $device == '-1' ) {
continue ;
}
2019-08-20 14:03:40 +02:00
$devices [] = ( ctype_digit ( $device ) || is_int ( $device )) ? $device : getidbyname ( $device );
2014-12-16 20:39:58 +00:00
}
2019-07-29 16:32:37 -05:00
if ( isset ( $data [ 'builder' ])) {
// accept inline json or json as a string
$builder = is_array ( $data [ 'builder' ]) ? json_encode ( $data [ 'builder' ]) : $data [ 'builder' ];
} else {
$builder = $data [ 'rule' ];
}
2018-09-19 13:47:45 +01:00
if ( empty ( $builder )) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Missing the alert builder rule' );
2014-12-16 20:39:58 +00:00
}
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
$name = $data [ 'name' ];
2015-07-01 21:35:37 +01:00
if ( empty ( $name )) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Missing the alert rule name' );
2015-07-01 21:35:37 +01:00
}
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
$severity = $data [ 'severity' ];
$sevs = [
2014-12-16 20:39:58 +00:00
'ok' ,
'warning' ,
'critical' ,
2019-07-29 16:32:37 -05:00
];
2014-12-16 20:39:58 +00:00
if ( ! in_array ( $severity , $sevs )) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Missing the severity' );
2014-12-16 20:39:58 +00:00
}
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
$disabled = $data [ 'disabled' ];
2014-12-16 20:39:58 +00:00
if ( $disabled != '0' && $disabled != '1' ) {
$disabled = 0 ;
}
2019-07-29 16:32:37 -05:00
$count = $data [ 'count' ];
$mute = $data [ 'mute' ];
$delay = $data [ 'delay' ];
2019-11-14 19:46:11 +01:00
$interval = $data [ 'interval' ];
2018-09-19 13:47:45 +01:00
$override_query = $data [ 'override_query' ];
$adv_query = $data [ 'adv_query' ];
2024-01-17 09:09:19 +01:00
$notes = $data [ 'notes' ];
2014-12-16 20:39:58 +00:00
$delay_sec = convert_delay ( $delay );
2019-11-14 19:46:11 +01:00
$interval_sec = convert_delay ( $interval );
2014-12-16 20:39:58 +00:00
if ( $mute == 1 ) {
$mute = true ;
2016-08-18 20:28:22 -05:00
} else {
2014-12-16 20:39:58 +00:00
$mute = false ;
}
2018-09-19 13:47:45 +01:00
$extra = [
2024-01-05 05:39:12 +01:00
'mute' => $mute ,
2014-12-16 20:39:58 +00:00
'count' => $count ,
'delay' => $delay_sec ,
2019-11-14 19:46:11 +01:00
'interval' => $interval_sec ,
2018-09-19 13:47:45 +01:00
'options' => [
'override_query' => $override_query ,
],
];
2014-12-16 20:39:58 +00:00
$extra_json = json_encode ( $extra );
2018-09-19 13:47:45 +01:00
if ( $override_query === 'on' ) {
$query = $adv_query ;
} else {
$query = QueryBuilderParser :: fromJson ( $builder ) -> toSql ();
if ( empty ( $query )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , "We couldn't parse your rule" );
2018-09-19 13:47:45 +01:00
}
}
2016-08-18 20:28:22 -05:00
if ( ! isset ( $rule_id )) {
2019-07-29 16:32:37 -05:00
if ( dbFetchCell ( 'SELECT `name` FROM `alert_rules` WHERE `name`=?' , [ $name ]) == $name ) {
return api_error ( 500 , 'Addition failed : Name has already been used' );
2015-10-16 16:18:18 +02:00
}
2019-07-29 16:32:37 -05:00
} elseif ( dbFetchCell ( 'SELECT name FROM alert_rules WHERE name=? AND id !=? ' , [ $name , $rule_id ]) == $name ) {
return api_error ( 500 , 'Update failed : Invalid rule id' );
2015-07-01 21:35:37 +01:00
}
2017-11-29 09:42:52 +00:00
if ( is_numeric ( $rule_id )) {
2024-01-17 09:09:19 +01:00
if ( ! ( dbUpdate ([ 'name' => $name , 'builder' => $builder , 'query' => $query , 'severity' => $severity , 'disabled' => $disabled , 'extra' => $extra_json , 'notes' => $notes ], 'alert_rules' , 'id=?' , [ $rule_id ]) >= 0 )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Failed to update existing alert rule' );
2014-12-16 20:39:58 +00:00
}
2024-01-17 09:09:19 +01:00
} elseif ( ! $rule_id = dbInsert ([ 'name' => $name , 'builder' => $builder , 'query' => $query , 'severity' => $severity , 'disabled' => $disabled , 'extra' => $extra_json , 'notes' => $notes ], 'alert_rules' )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Failed to create new alert rule' );
2014-12-16 20:39:58 +00:00
}
2015-07-13 20:10:26 +02:00
2018-09-19 13:47:45 +01:00
dbSyncRelationship ( 'alert_device_map' , 'rule_id' , $rule_id , 'device_id' , $devices );
dbSyncRelationship ( 'alert_group_map' , 'rule_id' , $rule_id , 'group_id' , $groups );
2020-02-12 19:53:26 +01:00
dbSyncRelationship ( 'alert_location_map' , 'rule_id' , $rule_id , 'location_id' , $locations );
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 200 );
2014-12-16 20:39:58 +00:00
}
2020-09-22 02:52:01 +02:00
function delete_rule ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$rule_id = $request -> route ( 'id' );
2014-12-16 20:39:58 +00:00
if ( is_numeric ( $rule_id )) {
2019-07-29 16:32:37 -05:00
if ( dbDelete ( 'alert_rules' , '`id` = ? LIMIT 1' , [ $rule_id ])) {
return api_success_noresult ( 200 , 'Alert rule has been removed' );
2016-08-18 20:28:22 -05:00
} else {
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 200 , 'No alert rule by that ID' );
2014-12-16 20:39:58 +00:00
}
}
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Invalid rule id has been provided' );
2014-12-16 20:39:58 +00:00
}
2020-09-22 02:52:01 +02:00
function ack_alert ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$alert_id = $request -> route ( 'id' );
$data = json_decode ( $request -> getContent (), true );
2017-11-29 09:42:52 +00:00
if ( ! is_numeric ( $alert_id )) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Invalid alert has been provided' );
2017-11-29 09:42:52 +00:00
}
2018-09-19 23:38:01 +01:00
$alert = dbFetchRow ( 'SELECT note, info FROM alerts WHERE id=?' , [ $alert_id ]);
$note = $alert [ 'note' ];
$info = json_decode ( $alert [ 'info' ], true );
if ( ! empty ( $note )) {
$note .= PHP_EOL ;
}
$note .= date ( Config :: get ( 'dateformat.long' )) . ' - Ack (' . Auth :: user () -> username . ") { $data [ 'note' ] } " ;
$info [ 'until_clear' ] = $data [ 'until_clear' ];
$info = json_encode ( $info );
if ( dbUpdate ([ 'state' => 2 , 'note' => $note , 'info' => $info ], 'alerts' , '`id` = ? LIMIT 1' , [ $alert_id ])) {
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 200 , 'Alert has been acknowledged' );
2016-08-18 20:28:22 -05:00
} else {
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 200 , 'No Alert by that ID' );
2014-12-16 20:39:58 +00:00
}
2015-10-08 16:45:36 +02:00
}
2015-07-13 20:10:26 +02:00
2020-09-22 02:52:01 +02:00
function unmute_alert ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$alert_id = $request -> route ( 'id' );
$data = json_decode ( $request -> getContent (), true );
2017-11-29 09:42:52 +00:00
if ( ! is_numeric ( $alert_id )) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Invalid alert has been provided' );
2018-09-19 23:38:01 +01:00
}
$alert = dbFetchRow ( 'SELECT note, info FROM alerts WHERE id=?' , [ $alert_id ]);
$note = $alert [ 'note' ];
2019-07-29 16:32:37 -05:00
2018-09-19 23:38:01 +01:00
if ( ! empty ( $note )) {
$note .= PHP_EOL ;
2015-10-08 16:45:36 +02:00
}
2018-09-19 23:38:01 +01:00
$note .= date ( Config :: get ( 'dateformat.long' )) . ' - Ack (' . Auth :: user () -> username . ") { $data [ 'note' ] } " ;
2015-10-08 16:45:36 +02:00
2018-09-19 23:38:01 +01:00
if ( dbUpdate ([ 'state' => 1 , 'note' => $note ], 'alerts' , '`id` = ? LIMIT 1' , [ $alert_id ])) {
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 200 , 'Alert has been unmuted' );
2017-11-29 09:42:52 +00:00
} else {
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 200 , 'No alert by that ID' );
2017-11-29 09:42:52 +00:00
}
2014-12-16 20:39:58 +00:00
}
2015-03-23 15:15:05 +00:00
2020-09-22 02:52:01 +02:00
function get_inventory ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2015-03-23 15:15:05 +00:00
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return check_device_permission ( $device_id , function ( $device_id ) use ( $request ) {
$sql = '' ;
$params = [];
if ( $request -> get ( 'entPhysicalClass' )) {
$sql .= ' AND entPhysicalClass=?' ;
$params [] = $request -> get ( 'entPhysicalClass' );
}
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
if ( $request -> get ( 'entPhysicalContainedIn' )) {
$sql .= ' AND entPhysicalContainedIn=?' ;
$params [] = $request -> get ( 'entPhysicalContainedIn' );
} else {
$sql .= ' AND entPhysicalContainedIn="0"' ;
}
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
if ( ! is_numeric ( $device_id )) {
return api_error ( 400 , 'Invalid device provided' );
}
$sql .= ' AND `device_id`=?' ;
$params [] = $device_id ;
$inventory = dbFetchRows ( "SELECT * FROM `entPhysical` WHERE 1 $sql " , $params );
2015-07-13 20:10:26 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $inventory , 'inventory' );
});
2015-03-23 15:15:05 +00:00
}
2015-05-07 00:32:58 +01:00
2020-09-22 02:52:01 +02:00
function get_inventory_for_device ( Illuminate\Http\Request $request )
2019-12-17 13:49:13 +01:00
{
$hostname = $request -> route ( 'hostname' );
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2020-09-21 15:40:17 +02:00
2019-12-17 13:49:13 +01:00
return check_device_permission ( $device_id , function ( $device_id ) {
$params = [];
$sql = 'SELECT * FROM `entPhysical` WHERE device_id = ?' ;
$params [] = $device_id ;
$inventory = dbFetchRows ( $sql , $params );
2020-09-21 15:40:17 +02:00
2019-12-17 13:49:13 +01:00
return api_success ( $inventory , 'inventory' );
});
}
2020-09-22 02:52:01 +02:00
function search_oxidized ( Illuminate\Http\Request $request )
2019-10-17 03:46:44 +01:00
{
$search_in_conf_textbox = $request -> route ( 'searchstring' );
$result = search_oxidized_config ( $search_in_conf_textbox );
if ( ! $result ) {
return api_error ( 404 , 'Received no data from Oxidized' );
} else {
return api_success ( $result , 'nodes' );
}
}
2020-09-22 02:52:01 +02:00
function get_oxidized_config ( Illuminate\Http\Request $request )
2019-12-08 19:04:53 +00:00
{
$hostname = $request -> route ( 'device_name' );
2023-02-01 11:49:29 -06:00
$node_info = json_decode (( new \App\ApiClients\Oxidized ()) -> getContent ( '/node/show/' . $hostname . '?format=json' ), true );
$result = json_decode (( new \App\ApiClients\Oxidized ()) -> getContent ( '/node/fetch/' . $node_info [ 'full_name' ] . '?format=json' ), true );
2019-12-08 19:04:53 +00:00
if ( ! $result ) {
return api_error ( 404 , 'Received no data from Oxidized' );
} else {
return api_success ( $result , 'config' );
}
}
2020-09-22 02:52:01 +02:00
function list_oxidized ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2021-05-11 08:08:59 -05:00
$return = [];
$devices = Device :: query ()
2023-11-07 15:44:47 -06:00
-> with ( 'attribs' )
2021-08-10 02:33:04 +02:00
-> 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' )
2024-01-15 16:55:20 -06:00
-> select ([ 'devices.device_id' , 'hostname' , 'sysName' , 'sysDescr' , 'sysObjectID' , 'hardware' , 'os' , 'ip' , 'location_id' , 'purpose' , 'notes' , 'poller_group' ])
2021-08-10 02:33:04 +02:00
-> get ();
2017-11-16 21:21:52 +00:00
2021-05-11 08:08:59 -05:00
/** @var Device $device */
foreach ( $devices as $device ) {
$output = [
'hostname' => $device -> hostname ,
'os' => $device -> os ,
'ip' => $device -> ip ,
];
2023-11-07 15:44:47 -06:00
$custom_ssh_port = $device -> getAttrib ( 'override_device_ssh_port' );
2023-09-04 03:15:51 +02:00
if ( ! empty ( $custom_ssh_port )) {
$output [ 'ssh_port' ] = $custom_ssh_port ;
}
2023-11-07 15:44:47 -06:00
$custom_telnet_port = $device -> getAttrib ( 'override_device_telnet_port' );
2023-09-04 03:15:51 +02:00
if ( ! empty ( $custom_telnet_port )) {
$output [ 'telnet_port' ] = $custom_telnet_port ;
}
2018-05-24 07:00:39 +10:00
// Pre-populate the group with the default
2019-06-23 00:29:12 -05:00
if ( Config :: get ( 'oxidized.group_support' ) === true && ! empty ( Config :: get ( 'oxidized.default_group' ))) {
2021-05-11 08:08:59 -05:00
$output [ 'group' ] = Config :: get ( 'oxidized.default_group' );
2018-05-24 07:00:39 +10:00
}
2021-05-11 08:08:59 -05:00
2019-06-23 00:29:12 -05:00
foreach ( Config :: get ( 'oxidized.maps' ) as $maps_column => $maps ) {
2018-05-24 07:00:39 +10:00
// Based on Oxidized group support we can apply groups by setting group_support to true
2019-06-23 00:29:12 -05:00
if ( $maps_column == 'group' && Config :: get ( 'oxidized.group_support' , true ) !== true ) {
2018-05-24 07:00:39 +10:00
continue ;
2017-10-15 13:37:20 -05:00
}
2018-07-09 14:23:38 -05:00
2018-05-24 07:00:39 +10:00
foreach ( $maps as $field_type => $fields ) {
2021-05-11 08:08:59 -05:00
if ( $field_type == 'sysname' ) {
$value = $device -> sysName ; // fix typo in previous code forcing users to use sysname instead of sysName
} elseif ( $field_type == 'location' ) {
$value = $device -> location -> location ;
} else {
$value = $device -> $field_type ;
}
2018-05-24 07:00:39 +10:00
foreach ( $fields as $field ) {
2021-05-11 08:08:59 -05:00
if ( isset ( $field [ 'regex' ]) && preg_match ( $field [ 'regex' ] . 'i' , $value )) {
$output [ $maps_column ] = $field [ 'value' ] ?? $field [ $maps_column ]; // compatibility with old format
2016-03-05 00:48:51 +00:00
break ;
2021-05-11 08:08:59 -05:00
} elseif ( isset ( $field [ 'match' ]) && $field [ 'match' ] == $value ) {
$output [ $maps_column ] = $field [ 'value' ] ?? $field [ $maps_column ]; // compatibility with old format
2016-01-10 19:45:54 +00:00
break ;
}
}
}
}
2021-06-28 12:53:16 +02:00
//Exclude groups from being sent to Oxidized
if ( in_array ( $output [ 'group' ], Config :: get ( 'oxidized.ignore_groups' ))) {
2021-07-05 18:38:52 +02:00
continue ;
2021-06-28 12:53:16 +02:00
}
2018-05-24 07:00:39 +10:00
2021-05-11 08:08:59 -05:00
$return [] = $output ;
2015-05-07 00:32:58 +01:00
}
2015-07-13 20:10:26 +02:00
2021-05-11 08:08:59 -05:00
return response () -> json ( $return , 200 , [], JSON_PRETTY_PRINT );
2015-05-07 00:32:58 +01:00
}
2015-07-02 23:19:46 +01:00
2020-09-22 02:52:01 +02:00
function list_bills ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$bills = [];
$bill_id = $request -> route ( 'bill_id' );
$bill_ref = $request -> get ( 'ref' );
$bill_custid = $request -> get ( 'custid' );
$period = $request -> get ( 'period' );
$param = [];
$sql = '' ;
2018-01-21 20:56:57 +01:00
2015-07-02 23:19:46 +01:00
if ( ! empty ( $bill_custid )) {
2017-11-29 09:42:52 +00:00
$sql .= '`bill_custid` = ?' ;
$param [] = $bill_custid ;
2016-08-18 20:28:22 -05:00
} elseif ( ! empty ( $bill_ref )) {
2017-11-29 09:42:52 +00:00
$sql .= '`bill_ref` = ?' ;
$param [] = $bill_ref ;
2016-08-18 20:28:22 -05:00
} elseif ( is_numeric ( $bill_id )) {
2017-11-29 09:42:52 +00:00
$sql .= '`bill_id` = ?' ;
$param [] = $bill_id ;
2017-12-07 22:56:31 +00:00
} else {
$sql = '1' ;
2015-07-02 23:19:46 +01:00
}
2019-07-29 16:32:37 -05:00
if ( ! Auth :: user () -> hasGlobalRead ()) {
2017-11-29 09:42:52 +00:00
$sql .= ' AND `bill_id` IN (SELECT `bill_id` FROM `bill_perms` WHERE `user_id` = ?)' ;
2019-07-29 16:32:37 -05:00
$param [] = Auth :: id ();
2015-07-02 23:19:46 +01:00
}
2018-03-19 16:40:17 -05:00
2018-02-09 21:14:55 +00:00
if ( $period === 'previous' ) {
2020-03-20 22:21:23 +01:00
$select = 'SELECT bills.bill_autoadded, bills.bill_cdr, bills.bill_custid, bills.bill_day, bills.bill_name,
bills.bill_notes, bills.bill_quota, bills.bill_ref, bill_history.*, bill_history.traf_total as total_data,
bill_history.traf_in as total_data_in, bill_history.traf_out as total_data_out, bill_history.updated as bill_last_calc
' ;
2018-02-09 21:14:55 +00:00
$query = 'FROM `bills`
2020-03-20 22:21:23 +01:00
INNER JOIN (SELECT bill_id, MAX(bill_hist_id) AS bill_hist_id FROM bill_history
WHERE bill_dateto < NOW() AND bill_dateto > subdate(NOW(), 40)
GROUP BY bill_id) qLastBills ON bills.bill_id = qLastBills.bill_id
2018-02-09 21:14:55 +00:00
INNER JOIN bill_history ON qLastBills.bill_hist_id = bill_history.bill_hist_id
2020-03-20 22:21:23 +01:00
' ;
2018-02-09 21:14:55 +00:00
} else {
$select = "SELECT bills.*,
2020-03-20 22:21:23 +01:00
IF(bills.bill_type = 'cdr', bill_cdr, bill_quota) AS bill_allowed
2018-02-09 21:14:55 +00:00
" ;
$query = "FROM `bills` \n " ;
}
2015-07-02 23:19:46 +01:00
2018-02-09 21:14:55 +00:00
foreach ( dbFetchRows ( " $select $query WHERE $sql ORDER BY `bill_name`" , $param ) as $bill ) {
2015-07-02 23:19:46 +01:00
$rate_data = $bill ;
2015-08-04 06:54:58 +00:00
$allowed = '' ;
$used = '' ;
$percent = '' ;
$overuse = '' ;
2015-07-02 23:19:46 +01:00
2020-03-20 22:21:23 +01:00
if ( strtolower ( $bill [ 'bill_type' ]) == 'cdr' ) {
2022-08-24 14:01:54 -05:00
$allowed = Number :: formatSi ( $bill [ 'bill_cdr' ], 2 , 3 , '' ) . 'bps' ;
$used = Number :: formatSi ( $rate_data [ 'rate_95th' ], 2 , 3 , '' ) . 'bps' ;
2020-03-27 00:18:17 +01:00
if ( $bill [ 'bill_cdr' ] > 0 ) {
2022-08-24 14:01:54 -05:00
$percent = Number :: calculatePercent ( $rate_data [ 'rate_95th' ], $bill [ 'bill_cdr' ]);
2020-03-27 00:18:17 +01:00
} else {
$percent = '-' ;
}
2015-07-02 23:19:46 +01:00
$overuse = $rate_data [ 'rate_95th' ] - $bill [ 'bill_cdr' ];
2022-08-24 14:01:54 -05:00
$overuse = (( $overuse <= 0 ) ? '-' : Number :: formatSi ( $overuse , 2 , 3 , '' ));
2020-03-20 22:21:23 +01:00
} elseif ( strtolower ( $bill [ 'bill_type' ]) == 'quota' ) {
2023-04-21 19:52:47 -05:00
$allowed = Billing :: formatBytes ( $bill [ 'bill_quota' ]);
$used = Billing :: formatBytes ( $rate_data [ 'total_data' ]);
2020-03-27 00:18:17 +01:00
if ( $bill [ 'bill_quota' ] > 0 ) {
2022-08-24 14:01:54 -05:00
$percent = Number :: calculatePercent ( $rate_data [ 'total_data' ], $bill [ 'bill_quota' ]);
2020-03-27 00:18:17 +01:00
} else {
$percent = '-' ;
}
2015-07-02 23:19:46 +01:00
$overuse = $rate_data [ 'total_data' ] - $bill [ 'bill_quota' ];
2023-04-21 19:52:47 -05:00
$overuse = (( $overuse <= 0 ) ? '-' : Billing :: formatBytes ( $overuse ));
2015-07-02 23:19:46 +01:00
}
$bill [ 'allowed' ] = $allowed ;
$bill [ 'used' ] = $used ;
$bill [ 'percent' ] = $percent ;
$bill [ 'overuse' ] = $overuse ;
2017-03-04 07:40:15 +11:00
2019-07-29 16:32:37 -05:00
$bill [ 'ports' ] = dbFetchRows ( 'SELECT `D`.`device_id`,`P`.`port_id`,`P`.`ifName` FROM `bill_ports` AS `B`, `ports` AS `P`, `devices` AS `D` WHERE `B`.`bill_id` = ? AND `P`.`port_id` = `B`.`port_id` AND `D`.`device_id` = `P`.`device_id`' , [ $bill [ 'bill_id' ]]);
2017-03-04 07:40:15 +11:00
2015-07-02 23:19:46 +01:00
$bills [] = $bill ;
}
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $bills , 'bills' );
2015-07-02 23:19:46 +01:00
}
2015-12-08 22:53:52 +00:00
2020-09-22 02:52:01 +02:00
function get_bill_graph ( Illuminate\Http\Request $request )
2018-02-09 21:14:55 +00:00
{
2019-07-29 16:32:37 -05:00
$bill_id = $request -> route ( 'bill_id' );
$graph_type = $request -> route ( 'graph_type' );
2018-02-20 14:57:56 +00:00
if ( $graph_type == 'monthly' ) {
$graph_type = 'historicmonthly' ;
}
2019-07-29 16:32:37 -05:00
$vars = [
'type' => "bill_ $graph_type " ,
'id' => $bill_id ,
];
2018-02-20 14:57:56 +00:00
2022-11-03 01:08:52 -05:00
return check_bill_permission ( $bill_id , function () use ( $request , $vars ) {
return api_get_graph ( $request , $vars );
2019-07-29 16:32:37 -05:00
});
2018-02-20 14:57:56 +00:00
}
2020-09-22 02:52:01 +02:00
function get_bill_graphdata ( Illuminate\Http\Request $request )
2018-02-20 14:57:56 +00:00
{
2019-07-29 16:32:37 -05:00
$bill_id = $request -> route ( 'bill_id' );
2018-02-20 14:57:56 +00:00
2019-07-29 16:32:37 -05:00
return check_bill_permission ( $bill_id , function ( $bill_id ) use ( $request ) {
$graph_type = $request -> route ( 'graph_type' );
if ( $graph_type == 'bits' ) {
$from = $request -> get ( 'from' , time () - 60 * 60 * 24 );
$to = $request -> get ( 'to' , time ());
$reducefactor = $request -> get ( 'reducefactor' );
2018-02-20 14:57:56 +00:00
2023-04-21 19:52:47 -05:00
$graph_data = Billing :: getBitsGraphData ( $bill_id , $from , $to , $reducefactor );
2019-07-29 16:32:37 -05:00
} elseif ( $graph_type == 'monthly' ) {
2023-04-23 20:33:50 -05:00
$graph_data = Billing :: getHistoricTransferGraphData ( $bill_id );
2019-07-29 16:32:37 -05:00
}
2018-03-19 16:40:17 -05:00
2019-07-29 16:32:37 -05:00
if ( ! isset ( $graph_data )) {
return api_error ( 400 , "Unsupported graph type $graph_type " );
} else {
return api_success ( $graph_data , 'graph_data' );
}
});
2018-02-20 14:57:56 +00:00
}
2020-09-22 02:52:01 +02:00
function get_bill_history ( Illuminate\Http\Request $request )
2018-02-20 14:57:56 +00:00
{
2019-07-29 16:32:37 -05:00
$bill_id = $request -> route ( 'bill_id' );
2018-02-20 14:57:56 +00:00
2019-07-29 16:32:37 -05:00
return check_bill_permission ( $bill_id , function ( $bill_id ) {
$result = dbFetchRows ( 'SELECT * FROM `bill_history` WHERE `bill_id` = ? ORDER BY `bill_datefrom` DESC LIMIT 24' , [ $bill_id ]);
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $result , 'bill_history' );
});
2018-02-09 21:14:55 +00:00
}
2020-09-22 02:52:01 +02:00
function get_bill_history_graph ( Illuminate\Http\Request $request )
2018-02-20 14:57:56 +00:00
{
2019-07-29 16:32:37 -05:00
$bill_id = $request -> route ( 'bill_id' );
$bill_hist_id = $request -> route ( 'bill_hist_id' );
$graph_type = $request -> route ( 'graph_type' );
2018-03-19 16:40:17 -05:00
2019-07-29 16:32:37 -05:00
$vars = [
'type' => "bill_ $graph_type " ,
'id' => $bill_id ,
'bill_hist_id' => $bill_hist_id ,
];
2018-02-20 14:57:56 +00:00
switch ( $graph_type ) {
case 'bits' :
2019-07-29 16:32:37 -05:00
$vars [ 'type' ] = 'bill_historicbits' ;
$vars [ 'reducefactor' ] = $request -> get ( 'reducefactor' );
2018-02-20 14:57:56 +00:00
break ;
2018-03-19 16:40:17 -05:00
2018-02-20 14:57:56 +00:00
case 'day' :
case 'hour' :
$vars [ 'imgtype' ] = $graph_type ;
2019-07-29 16:32:37 -05:00
$vars [ 'type' ] = 'bill_historictransfer' ;
2018-02-20 14:57:56 +00:00
break ;
2018-03-19 16:40:17 -05:00
2018-02-20 14:57:56 +00:00
default :
2019-07-29 16:32:37 -05:00
return api_error ( 400 , "Unknown Graph Type $graph_type " );
2018-02-20 14:57:56 +00:00
}
2022-11-03 01:08:52 -05:00
return check_bill_permission ( $bill_id , function () use ( $request , $vars ) {
return api_get_graph ( $request , $vars );
2019-07-29 16:32:37 -05:00
});
2018-02-20 14:57:56 +00:00
}
2020-09-22 02:52:01 +02:00
function get_bill_history_graphdata ( Illuminate\Http\Request $request )
2018-02-20 14:57:56 +00:00
{
2019-07-29 16:32:37 -05:00
$bill_id = $request -> route ( 'bill_id' );
2018-02-20 14:57:56 +00:00
2019-07-29 16:32:37 -05:00
return check_bill_permission ( $bill_id , function ( $bill_id ) use ( $request ) {
$bill_hist_id = $request -> route ( 'bill_hist_id' );
$graph_type = $request -> route ( 'graph_type' );
2018-03-19 16:40:17 -05:00
2019-07-29 16:32:37 -05:00
switch ( $graph_type ) {
case 'bits' :
$reducefactor = $request -> get ( 'reducefactor' );
2018-02-20 14:57:56 +00:00
2023-04-21 19:52:47 -05:00
$graph_data = Billing :: getHistoryBitsGraphData ( $bill_id , $bill_hist_id , $reducefactor );
2019-07-29 16:32:37 -05:00
break ;
case 'day' :
case 'hour' :
2023-04-21 19:52:47 -05:00
$graph_data = Billing :: getBandwidthGraphData ( $bill_id , $bill_hist_id , null , null , $graph_type );
2019-07-29 16:32:37 -05:00
break ;
}
2018-03-19 16:40:17 -05:00
2019-07-29 16:32:37 -05:00
return ! isset ( $graph_data ) ?
2021-08-10 02:33:04 +02:00
api_error ( 400 , "Unsupported graph type $graph_type " ) :
api_success ( $graph_data , 'graph_data' );
2019-07-29 16:32:37 -05:00
});
2018-02-20 14:57:56 +00:00
}
2020-09-22 02:52:01 +02:00
function delete_bill ( Illuminate\Http\Request $request )
2018-02-27 20:51:29 +01:00
{
2019-07-29 16:32:37 -05:00
$bill_id = $request -> route ( 'bill_id' );
2018-02-27 20:51:29 +01:00
if ( $bill_id < 1 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Could not remove bill with id ' . $bill_id . '. Invalid id' );
2018-02-27 20:51:29 +01:00
}
$res = dbDelete ( 'bills' , '`bill_id` = ? LIMIT 1' , [ $bill_id ]);
if ( $res == 1 ) {
dbDelete ( 'bill_ports' , '`bill_id` = ? ' , [ $bill_id ]);
dbDelete ( 'bill_data' , '`bill_id` = ? ' , [ $bill_id ]);
dbDelete ( 'bill_history' , '`bill_id` = ? ' , [ $bill_id ]);
dbDelete ( 'bill_history' , '`bill_id` = ? ' , [ $bill_id ]);
dbDelete ( 'bill_perms' , '`bill_id` = ? ' , [ $bill_id ]);
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 200 , 'Bill has been removed' );
2018-02-27 20:51:29 +01:00
}
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Could not remove bill with id ' . $bill_id );
2018-02-27 20:51:29 +01:00
}
function check_bill_key_value ( $bill_key , $bill_value )
{
$bill_types = [ 'quota' , 'cdr' ];
2019-07-29 16:32:37 -05:00
2018-02-27 20:51:29 +01:00
switch ( $bill_key ) {
case 'bill_type' :
2019-07-29 16:32:37 -05:00
if ( ! in_array ( $bill_value , $bill_types )) {
return api_error ( 400 , "Invalid value for $bill_key : $bill_value . Allowed: quota,cdr" );
2018-02-27 20:51:29 +01:00
}
break ;
case 'bill_cdr' :
2019-07-29 16:32:37 -05:00
if ( ! is_numeric ( $bill_value )) {
return api_error ( 400 , "Invalid value for $bill_key . Must be numeric." );
2018-02-27 20:51:29 +01:00
}
break ;
case 'bill_day' :
2019-07-29 16:32:37 -05:00
if ( $bill_value < 1 || $bill_value > 31 ) {
return api_error ( 400 , "Invalid value for $bill_key . range: 1-31" );
2018-02-27 20:51:29 +01:00
}
break ;
case 'bill_quota' :
2019-07-29 16:32:37 -05:00
if ( ! is_numeric ( $bill_value )) {
return api_error ( 400 , "Invalid value for $bill_key . Must be numeric" );
2018-02-27 20:51:29 +01:00
}
break ;
default :
}
2019-07-29 16:32:37 -05:00
return true ;
2018-02-27 20:51:29 +01:00
}
2020-09-22 02:52:01 +02:00
function create_edit_bill ( Illuminate\Http\Request $request )
2018-02-27 20:51:29 +01:00
{
2019-07-29 16:32:37 -05:00
$data = json_decode ( $request -> getContent (), true );
2018-02-27 20:51:29 +01:00
if ( ! $data ) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Invalid JSON data' );
2018-02-27 20:51:29 +01:00
}
//check ports
$ports_add = null ;
if ( array_key_exists ( 'ports' , $data )) {
$ports_add = [];
$ports = $data [ 'ports' ];
foreach ( $ports as $port_id ) {
$result = dbFetchRows ( 'SELECT port_id FROM `ports` WHERE `port_id` = ? LIMIT 1' , [ $port_id ]);
$result = $result [ 0 ];
if ( ! is_array ( $result ) || ! array_key_exists ( 'port_id' , $result )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Port ' . $port_id . ' does not exists' );
2018-02-27 20:51:29 +01:00
}
$ports_add [] = $port_id ;
}
}
$bill = [];
//find existing bill for update
$bill_id = ( int ) $data [ 'bill_id' ];
$bills = dbFetchRows ( "SELECT * FROM `bills` WHERE `bill_id` = $bill_id LIMIT 1" );
// update existing bill
if ( is_array ( $bills ) && count ( $bills ) == 1 ) {
$bill = $bills [ 0 ];
foreach ( $data as $bill_key => $bill_value ) {
2019-07-29 16:32:37 -05:00
$res = check_bill_key_value ( $bill_key , $bill_value );
if ( $res === true ) {
$bill [ $bill_key ] = $bill_value ;
} else {
return $res ;
}
2018-02-27 20:51:29 +01:00
}
$update_data = [
'bill_name' => $bill [ 'bill_name' ],
'bill_type' => $bill [ 'bill_type' ],
'bill_cdr' => $bill [ 'bill_cdr' ],
'bill_day' => $bill [ 'bill_day' ],
'bill_quota' => $bill [ 'bill_quota' ],
'bill_custid' => $bill [ 'bill_custid' ],
'bill_ref' => $bill [ 'bill_ref' ],
'bill_notes' => $bill [ 'bill_notes' ],
2022-09-06 11:49:15 -05:00
'dir_95th' => $bill [ 'dir_95th' ],
2018-02-27 20:51:29 +01:00
];
2019-07-29 16:32:37 -05:00
$update = dbUpdate ( $update_data , 'bills' , 'bill_id=?' , [ $bill_id ]);
2018-02-27 20:51:29 +01:00
if ( $update === false || $update < 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Failed to update existing bill' );
2018-02-27 20:51:29 +01:00
}
} else {
// create new bill
if ( array_key_exists ( 'bill_id' , $data )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Argument bill_id is not allowed on bill create (auto assigned)' );
2018-02-27 20:51:29 +01:00
}
$bill_keys = [
'bill_name' ,
'bill_type' ,
'bill_cdr' ,
'bill_day' ,
'bill_quota' ,
'bill_custid' ,
'bill_ref' ,
'bill_notes' ,
2022-09-06 11:49:15 -05:00
'dir_95th' ,
2018-02-27 20:51:29 +01:00
];
if ( $data [ 'bill_type' ] == 'quota' ) {
$data [ 'bill_cdr' ] = 0 ;
}
if ( $data [ 'bill_type' ] == 'cdr' ) {
$data [ 'bill_quota' ] = 0 ;
}
$missing_keys = '' ;
$missing = array_diff_key ( array_flip ( $bill_keys ), $data );
if ( count ( $missing ) > 0 ) {
foreach ( $missing as $missing_key => $dummy ) {
$missing_keys .= " $missing_key " ;
}
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Missing parameters: ' . $missing_keys );
2018-02-27 20:51:29 +01:00
}
foreach ( $bill_keys as $bill_key ) {
2019-07-29 16:32:37 -05:00
$res = check_bill_key_value ( $bill_key , $data [ $bill_key ]);
if ( $res === true ) {
$bill [ $bill_key ] = $data [ $bill_key ];
} else {
return $res ;
}
2018-02-27 20:51:29 +01:00
}
$bill_id = dbInsert (
[
'bill_name' => $bill [ 'bill_name' ],
'bill_type' => $bill [ 'bill_type' ],
'bill_cdr' => $bill [ 'bill_cdr' ],
'bill_day' => $bill [ 'bill_day' ],
'bill_quota' => $bill [ 'bill_quota' ],
'bill_custid' => $bill [ 'bill_custid' ],
'bill_ref' => $bill [ 'bill_ref' ],
'bill_notes' => $bill [ 'bill_notes' ],
2022-09-06 11:49:15 -05:00
'dir_95th' => $bill [ 'dir_95th' ],
2018-02-27 20:51:29 +01:00
],
'bills'
);
if ( $bill_id === null ) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Failed to create new bill' );
2018-02-27 20:51:29 +01:00
}
}
// set previously checked ports
if ( is_array ( $ports_add )) {
dbDelete ( 'bill_ports' , "`bill_id` = $bill_id " );
if ( count ( $ports_add ) > 0 ) {
foreach ( $ports_add as $port_id ) {
dbInsert ([ 'bill_id' => $bill_id , 'port_id' => $port_id , 'bill_port_autoadded' => 0 ], 'bill_ports' );
}
}
}
2019-07-29 16:32:37 -05:00
return api_success ( $bill_id , 'bill_id' );
2018-02-27 20:51:29 +01:00
}
2020-09-22 02:52:01 +02:00
function update_device ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2015-12-08 22:53:52 +00:00
// use hostname as device_id if it's all digits
2022-10-23 04:45:47 +08:00
$device = ctype_digit ( $hostname ) ? Device :: find ( $hostname ) : Device :: findByHostname ( $hostname );
if ( is_null ( $device )) {
return api_error ( 404 , "Device $hostname not found" );
}
2019-07-29 16:32:37 -05:00
$data = json_decode ( $request -> getContent (), true );
$bad_fields = [ 'device_id' , 'hostname' ];
2015-12-08 22:53:52 +00:00
if ( empty ( $data [ 'field' ])) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Device field to patch has not been supplied' );
2016-08-18 20:28:22 -05:00
} elseif ( in_array ( $data [ 'field' ], $bad_fields )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Device field is not allowed to be updated' );
2017-11-29 09:42:52 +00:00
}
if ( is_array ( $data [ 'field' ]) && is_array ( $data [ 'data' ])) {
foreach ( $data [ 'field' ] as $tmp_field ) {
if ( in_array ( $tmp_field , $bad_fields )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Device field is not allowed to be updated' );
2016-11-26 20:55:24 +00:00
}
2017-11-29 09:42:52 +00:00
}
if ( count ( $data [ 'field' ]) == count ( $data [ 'data' ])) {
2019-07-29 16:32:37 -05:00
$update = [];
2017-11-29 09:42:52 +00:00
for ( $x = 0 ; $x < count ( $data [ 'field' ]); $x ++ ) {
2022-09-09 11:40:55 -05:00
$field = $data [ 'field' ][ $x ];
$field_data = $data [ 'data' ][ $x ];
if ( $field == 'location' ) {
$field = 'location_id' ;
$field_data = \App\Models\Location :: firstOrCreate ([ 'location' => $field_data ]) -> id ;
}
$update [ $field ] = $field_data ;
2017-11-29 09:42:52 +00:00
}
2022-10-23 04:45:47 +08:00
if ( $device -> fill ( $update ) -> save ()) {
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 200 , 'Device fields have been updated' );
2017-11-29 09:42:52 +00:00
} else {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Device fields failed to be updated' );
2016-11-26 20:55:24 +00:00
}
2016-08-18 20:28:22 -05:00
} else {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Device fields failed to be updated as the number of fields (' . count ( $data [ 'field' ]) . ') does not match the supplied data (' . count ( $data [ 'data' ]) . ')' );
2015-12-08 22:53:52 +00:00
}
2022-10-23 04:45:47 +08:00
} elseif ( $device -> fill ([ $data [ 'field' ] => $data [ 'data' ]]) -> save ()) {
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 200 , 'Device ' . $data [ 'field' ] . ' field has been updated' );
2017-11-29 09:42:52 +00:00
} else {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Device ' . $data [ 'field' ] . ' field failed to be updated' );
2015-12-08 22:53:52 +00:00
}
}
2015-12-12 12:58:07 +00:00
2020-09-22 02:52:01 +02:00
function rename_device ( Illuminate\Http\Request $request )
2017-12-19 09:32:31 +00:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2017-12-19 09:32:31 +00:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2019-07-29 16:32:37 -05:00
$new_hostname = $request -> route ( 'new_hostname' );
2017-12-19 09:32:31 +00:00
$new_device = getidbyname ( $new_hostname );
if ( empty ( $new_hostname )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Missing new hostname' );
2017-12-19 09:32:31 +00:00
} elseif ( $new_device ) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Device failed to rename, new hostname already exists' );
2017-12-19 09:32:31 +00:00
} else {
if ( renamehost ( $device_id , $new_hostname , 'api' ) == '' ) {
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 200 , 'Device has been renamed' );
2017-12-19 09:32:31 +00:00
} else {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Device failed to be renamed' );
2017-12-19 09:32:31 +00:00
}
}
}
2021-04-07 00:25:08 +02:00
function add_port_group ( Illuminate\Http\Request $request )
{
$data = json_decode ( $request -> getContent (), true );
if ( json_last_error () || ! is_array ( $data )) {
return api_error ( 400 , "We couldn't parse the provided json. " . json_last_error_msg ());
}
$rules = [
'name' => 'required|string|unique:port_groups' ,
];
$v = Validator :: make ( $data , $rules );
if ( $v -> fails ()) {
return api_error ( 422 , $v -> messages ());
}
$portGroup = PortGroup :: make ([ 'name' => $data [ 'name' ], 'desc' => $data [ 'desc' ]]);
$portGroup -> save ();
return api_success ( $portGroup -> id , 'id' , 'Port group ' . $portGroup -> name . ' created' , 201 );
}
function get_port_groups ( Illuminate\Http\Request $request )
{
$query = PortGroup :: query ();
$groups = $query -> orderBy ( 'name' ) -> get ();
if ( $groups -> isEmpty ()) {
return api_error ( 404 , 'No port groups found' );
}
return api_success ( $groups -> makeHidden ( 'pivot' ) -> toArray (), 'groups' , 'Found ' . $groups -> count () . ' port groups' );
}
2021-10-19 09:47:37 +08:00
function get_ports_by_group ( Illuminate\Http\Request $request )
{
$name = $request -> route ( 'name' );
if ( ! $name ) {
return api_error ( 400 , 'No port group name provided' );
}
$port_group = ctype_digit ( $name ) ? PortGroup :: find ( $name ) : PortGroup :: where ( 'name' , $name ) -> first ();
if ( empty ( $port_group )) {
return api_error ( 404 , 'Port group not found' );
}
$ports = $port_group -> ports () -> get ( $request -> get ( 'full' ) ? [ '*' ] : [ 'ports.port_id' ]);
if ( $ports -> isEmpty ()) {
return api_error ( 404 , 'No ports found in group ' . $name );
}
return api_success ( $ports -> makeHidden ( 'pivot' ) -> toArray (), 'ports' );
}
2021-09-21 15:41:01 +02:00
function assign_port_group ( Illuminate\Http\Request $request )
{
$port_group_id = $request -> route ( 'port_group_id' );
$data = json_decode ( $request -> getContent (), true );
$port_id_list = $data [ 'port_ids' ];
if ( json_last_error () || ! is_array ( $data )) {
return api_error ( 400 , "We couldn't parse the provided json. " . json_last_error_msg ());
}
if ( ! isset ( $port_id_list )) {
return api_error ( 400 , "Missing data field 'port_ids' " . json_last_error_msg ());
}
$port_group = PortGroup :: find ( $port_group_id );
if ( ! isset ( $port_group )) {
return api_error ( 404 , 'Port Group ID ' . $port_group_id . ' not found' );
}
$port_group -> ports () -> attach ( $port_id_list );
return api_success ( 200 , 'Port Ids ' . implode ( ', ' , $port_id_list ) . ' have been added to Port Group Id ' . $port_group_id );
}
function remove_port_group ( Illuminate\Http\Request $request )
{
$port_group_id = $request -> route ( 'port_group_id' );
$data = json_decode ( $request -> getContent (), true );
$port_id_list = $data [ 'port_ids' ];
if ( json_last_error () || ! is_array ( $data )) {
return api_error ( 400 , "We couldn't parse the provided json. " . json_last_error_msg ());
}
if ( ! isset ( $port_id_list )) {
return api_error ( 400 , "Missing data field 'port_ids' " . json_last_error_msg ());
}
$port_group = PortGroup :: find ( $port_group_id );
if ( ! isset ( $port_group )) {
return api_error ( 404 , 'Port Group ID ' . $port_group_id . ' not found' );
}
$port_group -> ports () -> detach ( $port_id_list );
return api_success ( 200 , 'Port Ids ' . implode ( ', ' , $port_id_list ) . ' have been removed from Port Group Id ' . $port_group_id );
}
2020-09-22 02:52:01 +02:00
function add_device_group ( Illuminate\Http\Request $request )
2019-11-08 13:11:56 +00:00
{
$data = json_decode ( $request -> getContent (), true );
if ( json_last_error () || ! is_array ( $data )) {
return api_error ( 400 , "We couldn't parse the provided json. " . json_last_error_msg ());
}
$rules = [
'name' => 'required|string|unique:device_groups' ,
'type' => 'required|in:dynamic,static' ,
'devices' => 'array|required_if:type,static' ,
'devices.*' => 'integer' ,
'rules' => 'json|required_if:type,dynamic' ,
];
$v = Validator :: make ( $data , $rules );
if ( $v -> fails ()) {
return api_error ( 422 , $v -> messages ());
}
2021-10-12 13:08:16 +11:00
if ( ! empty ( $data [ 'rules' ])) {
// Only use the rules if they are able to be parsed by the QueryBuilder
$query = QueryBuilderParser :: fromJson ( $data [ 'rules' ]) -> toSql ();
if ( empty ( $query )) {
return api_error ( 500 , "We couldn't parse your rule" );
}
2019-11-08 13:11:56 +00:00
}
$deviceGroup = DeviceGroup :: make ([ 'name' => $data [ 'name' ], 'type' => $data [ 'type' ], 'desc' => $data [ 'desc' ]]);
2021-09-11 14:35:11 -05:00
if ( $data [ 'type' ] == 'dynamic' ) {
$deviceGroup -> rules = json_decode ( $data [ 'rules' ]);
}
2019-11-08 13:11:56 +00:00
$deviceGroup -> save ();
if ( $data [ 'type' ] == 'static' ) {
$deviceGroup -> devices () -> sync ( $data [ 'devices' ]);
}
return api_success ( $deviceGroup -> id , 'id' , 'Device group ' . $deviceGroup -> name . ' created' , 201 );
}
2024-02-05 19:02:36 +00:00
function update_device_group ( Illuminate\Http\Request $request )
{
$data = json_decode ( $request -> getContent (), true );
if ( json_last_error () || ! is_array ( $data )) {
return api_error ( 400 , "We couldn't parse the provided json. " . json_last_error_msg ());
}
$name = $request -> route ( 'name' );
if ( ! $name ) {
return api_error ( 400 , 'No device group name provided' );
}
$deviceGroup = ctype_digit ( $name ) ? DeviceGroup :: find ( $name ) : DeviceGroup :: where ( 'name' , $name ) -> first ();
if ( ! $deviceGroup ) {
return api_error ( 404 , "Device group $name not found" );
}
$rules = [
'name' => 'sometimes|string|unique:device_groups' ,
'desc' => 'sometimes|string' ,
'type' => 'sometimes|in:dynamic,static' ,
'devices' => 'array|required_if:type,static' ,
'devices.*' => 'integer' ,
'rules' => 'json|required_if:type,dynamic' ,
];
$v = Validator :: make ( $data , $rules );
if ( $v -> fails ()) {
return api_error ( 422 , $v -> messages ());
}
if ( ! empty ( $data [ 'rules' ])) {
// Only use the rules if they are able to be parsed by the QueryBuilder
$query = QueryBuilderParser :: fromJson ( $data [ 'rules' ]) -> toSql ();
if ( empty ( $query )) {
return api_error ( 500 , "We couldn't parse your rule" );
}
}
$validatedData = $v -> safe () -> only ([ 'name' , 'desc' , 'type' ]);
$deviceGroup -> fill ( $validatedData );
if ( $deviceGroup -> type == 'static' && array_key_exists ( 'devices' , $data )) {
$deviceGroup -> devices () -> sync ( $data [ 'devices' ]);
}
if ( $deviceGroup -> type == 'dynamic' && ! empty ( $data [ 'rules' ])) {
$deviceGroup -> rules = json_decode ( $data [ 'rules' ]);
}
try {
$deviceGroup -> save ();
} catch ( \Illuminate\Database\QueryException $e ) {
return api_error ( 500 , 'Failed to save changes device group' );
}
return api_success_noresult ( 200 , "Device group $name updated" );
}
function delete_device_group ( Illuminate\Http\Request $request )
{
$name = $request -> route ( 'name' );
if ( ! $name ) {
return api_error ( 400 , 'No device group name provided' );
}
$deviceGroup = ctype_digit ( $name ) ? DeviceGroup :: find ( $name ) : DeviceGroup :: where ( 'name' , $name ) -> first ();
if ( ! $deviceGroup ) {
return api_error ( 404 , "Device group $name not found" );
}
$deleted = $deviceGroup -> delete ();
if ( ! $deleted ) {
return api_error ( 500 , "Device group $name could not be removed" );
}
return api_success_noresult ( 200 , "Device group $name deleted" );
}
2024-01-31 19:09:14 +00:00
function update_device_group_add_devices ( Illuminate\Http\Request $request )
{
$data = json_decode ( $request -> getContent (), true );
if ( json_last_error () || ! is_array ( $data )) {
return api_error ( 400 , "We couldn't parse the provided json. " . json_last_error_msg ());
}
$name = $request -> route ( 'name' );
if ( ! $name ) {
return api_error ( 400 , 'No device group name provided' );
}
$deviceGroup = ctype_digit ( $name ) ? DeviceGroup :: find ( $name ) : DeviceGroup :: where ( 'name' , $name ) -> first ();
if ( ! $deviceGroup ) {
return api_error ( 404 , "Device group $name not found" );
}
if ( 'static' != $deviceGroup -> type ) {
return api_error ( 422 , 'Only static device group can have devices added' );
}
$rules = [
'devices' => 'array' ,
'devices.*' => 'integer' ,
];
$v = Validator :: make ( $data , $rules );
if ( $v -> fails ()) {
return api_error ( 422 , $v -> messages ());
}
$deviceGroup -> devices () -> syncWithoutDetaching ( $data [ 'devices' ]);
return api_success_noresult ( 200 , 'Devices added' );
}
function update_device_group_remove_devices ( Illuminate\Http\Request $request )
{
$data = json_decode ( $request -> getContent (), true );
if ( json_last_error () || ! is_array ( $data )) {
return api_error ( 400 , "We couldn't parse the provided json. " . json_last_error_msg ());
}
$name = $request -> route ( 'name' );
if ( ! $name ) {
return api_error ( 400 , 'No device group name provided' );
}
$deviceGroup = ctype_digit ( $name ) ? DeviceGroup :: find ( $name ) : DeviceGroup :: where ( 'name' , $name ) -> first ();
if ( ! $deviceGroup ) {
return api_error ( 404 , "Device group $name not found" );
}
if ( 'static' != $deviceGroup -> type ) {
return api_error ( 422 , 'Only static device group can have devices added' );
}
$rules = [
'devices' => 'array' ,
'devices.*' => 'integer' ,
];
$v = Validator :: make ( $data , $rules );
if ( $v -> fails ()) {
return api_error ( 422 , $v -> messages ());
}
$deviceGroup -> devices () -> detach ( $data [ 'devices' ]);
return api_success_noresult ( 200 , 'Devices removed' );
}
2020-09-22 02:52:01 +02:00
function get_device_groups ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2019-06-19 16:01:53 -05:00
2019-07-29 16:32:37 -05:00
if ( $hostname ) {
$device = ctype_digit ( $hostname ) ? Device :: find ( $hostname ) : Device :: findByHostname ( $hostname );
2019-06-19 16:01:53 -05:00
if ( is_null ( $device )) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'Device not found' );
2019-06-19 16:01:53 -05:00
}
$query = $device -> groups ();
2016-08-18 20:28:22 -05:00
} else {
2019-06-19 16:01:53 -05:00
$query = DeviceGroup :: query ();
2015-12-12 12:58:07 +00:00
}
2019-06-19 16:01:53 -05:00
2019-07-29 16:32:37 -05:00
$groups = $query -> hasAccess ( Auth :: user ()) -> orderBy ( 'name' ) -> get ();
2019-06-19 16:01:53 -05:00
if ( $groups -> isEmpty ()) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'No device groups found' );
2015-12-12 12:58:07 +00:00
}
2019-07-29 16:32:37 -05:00
return api_success ( $groups -> makeHidden ( 'pivot' ) -> toArray (), 'groups' , 'Found ' . $groups -> count () . ' device groups' );
2015-12-12 12:58:07 +00:00
}
2015-12-12 13:47:44 +00:00
2022-05-27 10:38:47 -05:00
function maintenance_devicegroup ( Illuminate\Http\Request $request )
{
if ( empty ( $request -> json ())) {
return api_error ( 400 , 'No information has been provided to set this device into maintenance' );
}
$name = $request -> route ( 'name' );
if ( ! $name ) {
return api_error ( 400 , 'No device group name provided' );
}
$device_group = ctype_digit ( $name ) ? DeviceGroup :: find ( $name ) : DeviceGroup :: where ( 'name' , $name ) -> first ();
if ( ! $device_group ) {
2022-07-29 00:38:46 +08:00
return api_error ( 404 , "Device group $name not found" );
}
if ( ! $request -> json ( 'duration' )) {
return api_error ( 400 , 'Duration not provided' );
2022-05-27 10:38:47 -05:00
}
$notes = $request -> json ( 'notes' );
$title = $request -> json ( 'title' ) ?? $device_group -> name ;
$alert_schedule = new \App\Models\AlertSchedule ([
'title' => $title ,
'notes' => $notes ,
'recurring' => 0 ,
]);
$start = $request -> json ( 'start' ) ?? \Carbon\Carbon :: now () -> format ( 'Y-m-d H:i:00' );
$alert_schedule -> start = $start ;
$duration = $request -> json ( 'duration' );
if ( Str :: contains ( $duration , ':' )) {
[ $duration_hour , $duration_min ] = explode ( ':' , $duration );
$alert_schedule -> end = \Carbon\Carbon :: createFromFormat ( 'Y-m-d H:i:s' , $start )
-> addHours ( $duration_hour ) -> addMinutes ( $duration_min )
-> format ( 'Y-m-d H:i:00' );
}
2022-07-21 07:07:44 -05:00
$alert_schedule -> save ();
$alert_schedule -> deviceGroups () -> attach ( $device_group );
2022-05-27 10:38:47 -05:00
2022-07-29 00:38:46 +08:00
if ( $request -> json ( 'start' )) {
return api_success_noresult ( 201 , "Device group { $device_group -> name } ( { $device_group -> id } ) will begin maintenance mode at $start " . ( $duration ? " for { $duration } h" : '' ));
} else {
return api_success_noresult ( 201 , "Device group { $device_group -> name } ( { $device_group -> id } ) moved into maintenance mode" . ( $duration ? " for { $duration } h" : '' ));
}
2022-05-27 10:38:47 -05:00
}
2020-09-22 02:52:01 +02:00
function get_devices_by_group ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$name = $request -> route ( 'name' );
if ( ! $name ) {
return api_error ( 400 , 'No device group name provided' );
2017-11-29 09:42:52 +00:00
}
2019-06-19 16:01:53 -05:00
$device_group = ctype_digit ( $name ) ? DeviceGroup :: find ( $name ) : DeviceGroup :: where ( 'name' , $name ) -> first ();
if ( empty ( $device_group )) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'Device group not found' );
2019-06-19 16:01:53 -05:00
}
2019-07-29 16:32:37 -05:00
$devices = $device_group -> devices () -> get ( $request -> get ( 'full' ) ? [ '*' ] : [ 'devices.device_id' ]);
2019-06-19 16:01:53 -05:00
if ( $devices -> isEmpty ()) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'No devices found in group ' . $name );
2015-12-12 13:47:44 +00:00
}
2019-07-29 16:32:37 -05:00
return api_success ( $devices -> makeHidden ( 'pivot' ) -> toArray (), 'devices' );
2015-12-12 13:47:44 +00:00
}
2016-04-22 13:41:38 +00:00
2020-09-22 02:52:01 +02:00
function list_vrf ( Illuminate\Http\Request $request )
2018-01-18 18:43:15 +03:00
{
$sql = '' ;
2019-07-29 16:32:37 -05:00
$sql_params = [];
$hostname = $request -> get ( 'hostname' );
$vrfname = $request -> get ( 'vrfname' );
2018-01-18 18:43:15 +03:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
if ( is_numeric ( $device_id )) {
2019-07-29 16:32:37 -05:00
$permission = check_device_permission ( $device_id );
if ( $permission !== true ) {
return $permission ;
}
2018-01-18 18:43:15 +03:00
$sql = ' AND `devices`.`device_id`=?' ;
2019-07-29 16:32:37 -05:00
$sql_params = [ $device_id ];
2018-01-18 18:43:15 +03:00
}
if ( ! empty ( $vrfname )) {
$sql = ' AND `vrfs`.`vrf_name`=?' ;
2019-07-29 16:32:37 -05:00
$sql_params = [ $vrfname ];
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
if ( ! Auth :: user () -> hasGlobalRead ()) {
2018-01-18 18:43:15 +03:00
$sql .= ' AND `vrfs`.`device_id` IN (SELECT device_id FROM devices_perms WHERE user_id = ?)' ;
2019-07-29 16:32:37 -05:00
$sql_params [] = Auth :: id ();
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
$vrfs = dbFetchRows ( "SELECT `vrfs`.* FROM `vrfs` LEFT JOIN `devices` ON `vrfs`.`device_id` = `devices`.`device_id` WHERE `vrfs`.`vrf_name` IS NOT NULL $sql " , $sql_params );
2018-01-18 18:43:15 +03:00
$total_vrfs = count ( $vrfs );
if ( $total_vrfs == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'VRFs do not exist' );
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
return api_success ( $vrfs , 'vrfs' );
2018-01-18 18:43:15 +03:00
}
2020-09-22 02:52:01 +02:00
function get_vrf ( Illuminate\Http\Request $request )
2018-01-18 18:43:15 +03:00
{
2019-07-29 16:32:37 -05:00
$vrfId = $request -> route ( 'id' );
2018-01-18 18:43:15 +03:00
if ( ! is_numeric ( $vrfId )) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Invalid id has been provided' );
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
$vrf = dbFetchRows ( 'SELECT * FROM `vrfs` WHERE `vrf_id` IS NOT NULL AND `vrf_id` = ?' , [ $vrfId ]);
2018-01-18 18:43:15 +03:00
$vrf_count = count ( $vrf );
if ( $vrf_count == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , "VRF $vrfId does not exist" );
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
return api_success ( $vrf , 'vrf' );
2018-01-18 18:43:15 +03:00
}
2022-01-20 15:15:23 +01:00
function list_mpls_services ( Illuminate\Http\Request $request )
{
$hostname = $request -> get ( 'hostname' );
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
$mpls_services = MplsService :: hasAccess ( Auth :: user ()) -> when ( $device_id , function ( $query , $device_id ) {
return $query -> where ( 'device_id' , $device_id );
}) -> get ();
if ( $mpls_services -> isEmpty ()) {
return api_error ( 404 , 'MPLS Services do not exist' );
}
return api_success ( $mpls_services , 'mpls_services' , null , 200 , $mpls_services -> count ());
}
function list_mpls_saps ( Illuminate\Http\Request $request )
{
$hostname = $request -> get ( 'hostname' );
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
$mpls_saps = MplsSap :: hasAccess ( Auth :: user ()) -> when ( $device_id , function ( $query , $device_id ) {
return $query -> where ( 'device_id' , $device_id );
}) -> get ();
if ( $mpls_saps -> isEmpty ()) {
return api_error ( 404 , 'SAPs do not exist' );
}
return api_success ( $mpls_saps , 'saps' , null , 200 , $mpls_saps -> count ());
}
2020-09-22 02:52:01 +02:00
function list_ipsec ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2016-04-22 13:41:38 +00:00
// use hostname as device_id if it's all digits
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
if ( ! is_numeric ( $device_id )) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'No valid hostname or device ID provided' );
2016-04-22 13:41:38 +00:00
}
2019-07-29 16:32:37 -05:00
$ipsec = dbFetchRows ( 'SELECT `D`.`hostname`, `I`.* FROM `ipsec_tunnels` AS `I`, `devices` AS `D` WHERE `I`.`device_id`=? AND `D`.`device_id` = `I`.`device_id`' , [ $device_id ]);
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $ipsec , 'ipsec' );
2016-04-22 13:41:38 +00:00
}
2016-06-27 14:48:07 +01:00
2020-09-22 02:52:01 +02:00
function list_vlans ( Illuminate\Http\Request $request )
2018-01-18 18:43:15 +03:00
{
$sql = '' ;
2019-07-29 16:32:37 -05:00
$sql_params = [];
$hostname = $request -> get ( 'hostname' );
2018-01-18 18:43:15 +03:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
if ( is_numeric ( $device_id )) {
2019-07-29 16:32:37 -05:00
$permission = check_device_permission ( $device_id );
if ( $permission !== true ) {
return $permission ;
}
2018-01-18 18:43:15 +03:00
$sql = ' AND `devices`.`device_id` = ?' ;
$sql_params [] = $device_id ;
}
2019-07-29 16:32:37 -05:00
if ( ! Auth :: user () -> hasGlobalRead ()) {
2018-01-18 18:43:15 +03:00
$sql .= ' AND `vlans`.`device_id` IN (SELECT device_id FROM devices_perms WHERE user_id = ?)' ;
2019-07-29 16:32:37 -05:00
$sql_params [] = Auth :: id ();
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
$vlans = dbFetchRows ( "SELECT `vlans`.* FROM `vlans` LEFT JOIN `devices` ON `vlans`.`device_id` = `devices`.`device_id` WHERE `vlans`.`vlan_vlan` IS NOT NULL $sql " , $sql_params );
2018-01-18 18:43:15 +03:00
$vlans_count = count ( $vlans );
if ( $vlans_count == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'VLANs do not exist' );
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
return api_success ( $vlans , 'vlans' );
2018-01-18 18:43:15 +03:00
}
2020-09-22 02:52:01 +02:00
function list_links ( Illuminate\Http\Request $request )
2018-11-19 17:36:23 +03:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
$sql = '' ;
$sql_params = [];
2018-11-19 17:36:23 +03:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
if ( is_numeric ( $device_id )) {
2019-07-29 16:32:37 -05:00
$permission = check_device_permission ( $device_id );
if ( $permission !== true ) {
return $permission ;
}
2018-11-19 17:36:23 +03:00
$sql = ' AND `links`.`local_device_id`=?' ;
2019-07-29 16:32:37 -05:00
$sql_params = [ $device_id ];
2018-11-19 17:36:23 +03:00
}
2019-07-29 16:32:37 -05:00
if ( ! Auth :: user () -> hasGlobalRead ()) {
2018-11-19 17:36:23 +03:00
$sql .= ' AND `links`.`local_device_id` IN (SELECT device_id FROM devices_perms WHERE user_id = ?)' ;
2019-07-29 16:32:37 -05:00
$sql_params [] = Auth :: id ();
2018-11-19 17:36:23 +03:00
}
2019-07-29 16:32:37 -05:00
$links = dbFetchRows ( "SELECT `links`.* FROM `links` LEFT JOIN `devices` ON `links`.`local_device_id` = `devices`.`device_id` WHERE `links`.`id` IS NOT NULL $sql " , $sql_params );
2018-11-19 17:36:23 +03:00
$total_links = count ( $links );
if ( $total_links == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'Links do not exist' );
2018-11-19 17:36:23 +03:00
}
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $links , 'links' );
2018-11-19 17:36:23 +03:00
}
2020-09-22 02:52:01 +02:00
function get_link ( Illuminate\Http\Request $request )
2018-11-19 17:36:23 +03:00
{
2019-07-29 16:32:37 -05:00
$linkId = $request -> route ( 'id' );
2018-11-19 17:36:23 +03:00
if ( ! is_numeric ( $linkId )) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Invalid id has been provided' );
2018-11-19 17:36:23 +03:00
}
2019-07-29 16:32:37 -05:00
$link = dbFetchRows ( 'SELECT * FROM `links` WHERE `id` IS NOT NULL AND `id` = ?' , [ $linkId ]);
2018-11-19 17:36:23 +03:00
$link_count = count ( $link );
if ( $link_count == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , "Link $linkId does not exist" );
2018-11-19 17:36:23 +03:00
}
2019-07-29 16:32:37 -05:00
return api_success ( $link , 'link' );
2018-11-19 17:36:23 +03:00
}
2020-09-22 02:52:01 +02:00
function get_fdb ( Illuminate\Http\Request $request )
2019-04-09 08:51:01 -04:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2019-04-09 08:51:01 -04:00
if ( empty ( $hostname )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'No hostname has been provided' );
2019-04-09 08:51:01 -04:00
}
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
$device = null ;
if ( $device_id ) {
// save the current details for returning to the client on successful delete
2019-07-29 16:32:37 -05:00
$device = Device :: find ( $device_id );
2019-04-09 08:51:01 -04:00
}
if ( ! $device ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , "Device $hostname not found" );
2019-04-09 08:51:01 -04:00
}
2019-07-29 16:32:37 -05:00
return check_device_permission ( $device_id , function () use ( $device ) {
if ( $device ) {
$fdb = $device -> portsFdb ;
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $fdb , 'ports_fdb' );
}
2019-05-13 08:35:24 -05:00
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'Device does not exist' );
});
2019-04-09 08:51:01 -04:00
}
2024-09-29 11:05:44 -05:00
function get_transceivers ( Illuminate\Http\Request $request )
{
$hostname = $request -> route ( 'hostname' );
if ( empty ( $hostname )) {
return api_error ( 500 , 'No hostname has been provided' );
}
$device = DeviceCache :: get ( $hostname );
if ( ! $device ) {
return api_error ( 404 , "Device $hostname not found" );
}
return api_success ( $device -> transceivers () -> hasAccess ( $request -> user ()) -> get (), 'transceivers' );
}
2020-09-22 02:52:01 +02:00
function list_fdb ( Illuminate\Http\Request $request )
2019-04-09 08:51:01 -04:00
{
2019-07-29 16:32:37 -05:00
$mac = $request -> route ( 'mac' );
2019-04-09 08:51:01 -04:00
2019-07-29 16:32:37 -05:00
$fdb = PortsFdb :: hasAccess ( Auth :: user ())
2021-08-10 02:33:04 +02:00
-> when ( ! empty ( $mac ), function ( Builder $query ) use ( $mac ) {
return $query -> where ( 'mac_address' , $mac );
})
-> get ();
2019-05-13 08:35:24 -05:00
if ( $fdb -> isEmpty ()) {
2023-07-07 21:24:50 -07:00
return api_error ( 404 , 'Fdb entry does not exist' );
2019-04-09 08:51:01 -04:00
}
2019-07-29 16:32:37 -05:00
return api_success ( $fdb , 'ports_fdb' );
2019-04-09 08:51:01 -04:00
}
2023-07-07 21:24:50 -07:00
function list_fdb_detail ( Illuminate\Http\Request $request )
{
2023-10-06 07:34:14 -05:00
$macAddress = Mac :: parse ( $request -> route ( 'mac' ));
2023-07-07 21:24:50 -07:00
2023-10-06 07:34:14 -05:00
if ( ! $macAddress -> isValid ()) {
return api_error ( 422 , 'Invalid MAC address' );
2023-07-07 21:24:50 -07:00
}
2023-10-06 07:34:14 -05:00
$extras = [ 'mac' => $macAddress -> readable (), 'mac_oui' => $macAddress -> vendor ()];
2023-07-07 21:24:50 -07:00
$fdb = PortsFdb :: hasAccess ( Auth :: user ())
2023-10-06 07:34:14 -05:00
-> leftJoin ( 'ports' , 'ports_fdb.port_id' , 'ports.port_id' )
-> leftJoin ( 'devices' , 'ports_fdb.device_id' , 'devices.device_id' )
-> where ( 'mac_address' , $macAddress -> hex ())
-> orderBy ( 'ports_fdb.updated_at' , 'desc' )
-> select ( 'devices.hostname' , 'ports.ifName' , 'ports_fdb.updated_at' )
-> limit ( 1000 ) -> get ();
2023-07-07 21:24:50 -07:00
2023-10-06 07:34:14 -05:00
if ( $fdb -> isEmpty ()) {
2023-07-07 21:24:50 -07:00
return api_error ( 404 , 'Fdb entry does not exist' );
}
foreach ( $fdb as $i => $fdb_entry ) {
if ( $fdb_entry [ 'updated_at' ]) {
$fdb [ $i ][ 'last_seen' ] = $fdb_entry [ 'updated_at' ] -> diffForHumans ();
$fdb [ $i ][ 'updated_at' ] = $fdb_entry [ 'updated_at' ] -> toDateTimeString ();
}
}
return api_success ( $fdb , 'ports_fdb' , null , 200 , count ( $fdb ), $extras );
}
2019-03-19 09:22:39 -04:00
function list_sensors ()
{
2019-07-29 16:32:37 -05:00
$sensors = Sensor :: hasAccess ( Auth :: user ()) -> get ();
2019-03-19 09:22:39 -04:00
$total_sensors = $sensors -> count ();
if ( $total_sensors == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'Sensors do not exist' );
2019-03-19 09:22:39 -04:00
}
2019-07-29 16:32:37 -05:00
return api_success ( $sensors , 'sensors' );
2019-03-19 09:22:39 -04:00
}
2018-01-18 18:43:15 +03:00
function list_ip_addresses ()
{
$ipv4_addresses = dbFetchRows ( 'SELECT * FROM `ipv4_addresses`' );
$ipv6_addresses = dbFetchRows ( 'SELECT * FROM `ipv6_addresses`' );
$ip_addresses_count = count ( array_merge ( $ipv4_addresses , $ipv6_addresses ));
if ( $ip_addresses_count == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'IP addresses do not exist' );
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
return api_success ( array_merge ( $ipv4_addresses , $ipv6_addresses ), 'ip_addresses' );
2018-01-18 18:43:15 +03:00
}
function list_ip_networks ()
{
$ipv4_networks = dbFetchRows ( 'SELECT * FROM `ipv4_networks`' );
$ipv6_networks = dbFetchRows ( 'SELECT * FROM `ipv6_networks`' );
$ip_networks_count = count ( array_merge ( $ipv4_networks , $ipv6_networks ));
if ( $ip_networks_count == 0 ) {
2019-07-29 16:32:37 -05:00
return api_error ( 404 , 'IP networks do not exist' );
2018-01-18 18:43:15 +03:00
}
2019-07-29 16:32:37 -05:00
return api_success ( array_merge ( $ipv4_networks , $ipv6_networks ), 'ip_networks' );
2018-01-18 18:43:15 +03:00
}
2020-09-22 02:52:01 +02:00
function list_arp ( Illuminate\Http\Request $request )
2016-08-18 20:28:22 -05:00
{
2019-11-13 02:21:07 +00:00
$query = $request -> route ( 'query' );
2019-11-05 15:16:29 -06:00
$cidr = $request -> route ( 'cidr' );
2019-07-29 16:32:37 -05:00
$hostname = $request -> get ( 'device' );
2019-11-13 02:21:07 +00:00
if ( empty ( $query )) {
return api_error ( 400 , 'No valid IP/MAC provided' );
2017-11-29 09:42:52 +00:00
}
2019-11-13 02:21:07 +00:00
if ( $query === 'all' ) {
2024-06-25 11:04:55 -05:00
$arp = $request -> has ( 'device' )
? \DeviceCache :: get ( $hostname ) -> macs
: Ipv4Mac :: all ();
2019-11-05 15:16:29 -06:00
} elseif ( $cidr ) {
2019-04-10 16:33:25 -05:00
try {
2019-11-13 02:21:07 +00:00
$ip = new IPv4 ( " $query / $cidr " );
2024-06-25 11:04:55 -05:00
$arp = Ipv4Mac :: whereRaw ( '(inet_aton(`ipv4_address`) & ?) = ?' , [ ip2long ( $ip -> getNetmask ()), ip2long ( $ip -> getNetworkAddress ())]) -> get ();
2019-04-10 16:33:25 -05:00
} catch ( InvalidIpException $e ) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'Invalid Network Address' );
2019-04-10 16:33:25 -05:00
}
2019-11-13 02:21:07 +00:00
} elseif ( filter_var ( $query , FILTER_VALIDATE_MAC )) {
2023-10-06 07:34:14 -05:00
$mac = Mac :: parse ( $query ) -> hex ();
2024-07-25 22:50:58 -05:00
$arp = Ipv4Mac :: where ( 'mac_address' , $mac ) -> get ();
2016-08-18 20:28:22 -05:00
} else {
2024-07-25 22:50:58 -05:00
$arp = Ipv4Mac :: where ( 'ipv4_address' , $query ) -> get ();
2016-06-27 14:48:07 +01:00
}
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success ( $arp , 'arp' );
2016-06-27 14:48:07 +01:00
}
2017-06-28 07:00:46 +01:00
2020-09-22 02:52:01 +02:00
function list_services ( Illuminate\Http\Request $request )
2016-08-26 09:19:05 +02:00
{
2019-07-29 16:32:37 -05:00
$where = [];
$params = [];
2017-02-07 02:46:09 -07:00
2017-06-28 07:00:46 +01:00
// Filter by State
2019-07-29 16:32:37 -05:00
if ( $request -> has ( 'state' )) {
2017-06-28 07:00:46 +01:00
$where [] = '`service_status`=?' ;
2019-07-29 16:32:37 -05:00
$params [] = $request -> get ( 'state' );
2017-06-28 07:00:46 +01:00
$where [] = "`service_disabled`='0'" ;
$where [] = "`service_ignore`='0'" ;
2017-02-07 02:46:09 -07:00
2019-07-29 16:32:37 -05:00
if ( ! is_numeric ( $request -> get ( 'state' ))) {
return api_error ( 400 , 'No valid service state provided, valid option is 0=Ok, 1=Warning, 2=Critical' );
2016-08-26 09:26:52 +02:00
}
}
2017-02-07 02:46:09 -07:00
2017-06-28 07:00:46 +01:00
//Filter by Type
2019-07-29 16:32:37 -05:00
if ( $request -> has ( 'type' )) {
2017-06-28 07:00:46 +01:00
$where [] = '`service_type` LIKE ?' ;
2019-07-29 16:32:37 -05:00
$params [] = $request -> get ( 'type' );
2017-06-28 07:00:46 +01:00
}
2017-08-08 14:14:58 -05:00
2017-06-28 07:00:46 +01:00
//GET by Host
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
if ( $hostname ) {
2016-08-26 09:26:52 +02:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2017-06-28 07:00:46 +01:00
$where [] = '`device_id` = ?' ;
$params [] = $device_id ;
2017-02-07 02:46:09 -07:00
2016-08-26 09:26:52 +02:00
if ( ! is_numeric ( $device_id )) {
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'No valid hostname or device id provided' );
2016-08-26 09:26:52 +02:00
}
}
2017-06-28 07:00:46 +01:00
$query = 'SELECT * FROM `services`' ;
2017-02-07 02:46:09 -07:00
2017-06-28 07:00:46 +01:00
if ( ! empty ( $where )) {
$query .= ' WHERE ' . implode ( ' AND ' , $where );
2016-08-26 09:26:52 +02:00
}
2017-06-28 07:00:46 +01:00
$query .= ' ORDER BY `service_ip`' ;
2019-07-29 16:32:37 -05:00
$services = [ dbFetchRows ( $query , $params )]; // double array for backwards compat :(
2017-06-28 07:00:46 +01:00
2019-07-29 16:32:37 -05:00
return api_success ( $services , 'services' );
2016-08-26 09:19:05 +02:00
}
2017-07-27 19:56:38 +01:00
2020-09-22 02:52:01 +02:00
function list_logs ( Illuminate\Http\Request $request , Router $router )
2017-07-27 19:56:38 +01:00
{
2019-07-29 16:32:37 -05:00
$type = $router -> current () -> getName ();
$hostname = $request -> route ( 'hostname' );
2017-07-27 19:56:38 +01:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2019-07-29 16:32:37 -05:00
$count_query = 'SELECT COUNT(*)' ;
$param = [];
2017-07-27 19:56:38 +01:00
if ( $type === 'list_eventlog' ) {
2019-07-29 16:32:37 -05:00
$query = ' FROM eventlog LEFT JOIN `devices` ON `eventlog`.`device_id`=`devices`.`device_id` WHERE 1' ;
$full_query = 'SELECT `devices`.`hostname`, `devices`.`sysName`, `eventlog`.`device_id` as `host`, `eventlog`.*' ; // inject host for backward compat
2017-07-27 19:56:38 +01:00
$timestamp = 'datetime' ;
2021-01-28 15:50:58 +01:00
$id_field = 'event_id' ;
2017-07-27 19:56:38 +01:00
} elseif ( $type === 'list_syslog' ) {
2019-07-29 16:32:37 -05:00
$query = ' FROM syslog LEFT JOIN `devices` ON `syslog`.`device_id`=`devices`.`device_id` WHERE 1' ;
$full_query = 'SELECT `devices`.`hostname`, `devices`.`sysName`, `syslog`.*' ;
2017-07-27 19:56:38 +01:00
$timestamp = 'timestamp' ;
2021-01-28 15:50:58 +01:00
$id_field = 'seq' ;
2017-07-27 19:56:38 +01:00
} elseif ( $type === 'list_alertlog' ) {
2019-07-29 16:32:37 -05:00
$query = ' FROM alert_log LEFT JOIN `devices` ON `alert_log`.`device_id`=`devices`.`device_id` WHERE 1' ;
$full_query = 'SELECT `devices`.`hostname`, `devices`.`sysName`, `alert_log`.*' ;
2017-07-27 19:56:38 +01:00
$timestamp = 'time_logged' ;
2021-01-28 15:50:58 +01:00
$id_field = 'id' ;
2017-07-27 19:56:38 +01:00
} elseif ( $type === 'list_authlog' ) {
2019-07-29 16:32:37 -05:00
$query = ' FROM authlog WHERE 1' ;
$full_query = 'SELECT `authlog`.*' ;
2017-07-27 19:56:38 +01:00
$timestamp = 'datetime' ;
2021-01-28 15:50:58 +01:00
$id_field = 'id' ;
2017-07-27 19:56:38 +01:00
} else {
2019-07-29 16:32:37 -05:00
$query = ' FROM eventlog LEFT JOIN `devices` ON `eventlog`.`device_id`=`devices`.`device_id` WHERE 1' ;
$full_query = 'SELECT `devices`.`hostname`, `devices`.`sysName`, `eventlog`.*' ;
2017-07-27 19:56:38 +01:00
$timestamp = 'datetime' ;
}
2019-07-29 16:32:37 -05:00
$start = ( int ) $request -> get ( 'start' , 0 );
$limit = ( int ) $request -> get ( 'limit' , 50 );
$from = $request -> get ( 'from' );
$to = $request -> get ( 'to' );
2017-07-27 19:56:38 +01:00
if ( is_numeric ( $device_id )) {
$query .= ' AND `devices`.`device_id` = ?' ;
$param [] = $device_id ;
}
if ( $from ) {
2021-01-28 15:50:58 +01:00
if ( is_numeric ( $from )) {
$query .= " AND $id_field >= ?" ;
} else {
$query .= " AND $timestamp >= ?" ;
}
2017-07-27 19:56:38 +01:00
$param [] = $from ;
}
if ( $to ) {
2021-01-28 15:50:58 +01:00
if ( is_numeric ( $to )) {
$query .= " AND $id_field <= ?" ;
} else {
$query .= " AND $timestamp <= ?" ;
}
2017-07-27 19:56:38 +01:00
$param [] = $to ;
}
2022-11-08 17:20:34 +00:00
$sort_order = $request -> get ( 'sortorder' ) === 'DESC' ? 'DESC' : 'ASC' ;
2017-07-27 19:56:38 +01:00
$count_query = $count_query . $query ;
$count = dbFetchCell ( $count_query , $param );
2022-11-08 17:20:34 +00:00
$full_query = $full_query . $query . " ORDER BY $timestamp $sort_order LIMIT $start , $limit " ;
2017-07-27 19:56:38 +01:00
$logs = dbFetchRows ( $full_query , $param );
2019-02-07 09:42:16 -06:00
if ( $type === 'list_alertlog' ) {
foreach ( $logs as $index => $log ) {
$logs [ $index ][ 'details' ] = json_decode ( gzuncompress ( $log [ 'details' ]), true );
}
}
2019-07-29 16:32:37 -05:00
return api_success ( $logs , 'logs' , null , 200 , null , [ 'total' => $count ]);
2017-07-27 19:56:38 +01:00
}
2017-11-14 15:15:12 +00:00
2022-11-18 16:27:56 -06:00
/**
* @throws \LibreNMS\Exceptions\ApiException
*/
function validate_column_list ( ? string $columns , string $table , array $default = []) : array
2017-11-14 15:15:12 +00:00
{
2022-11-18 16:27:56 -06:00
if ( $columns == '' ) { // no user input, return default
return $default ;
}
2019-07-29 16:32:37 -05:00
static $schema ;
if ( is_null ( $schema )) {
$schema = new \LibreNMS\DB\Schema ();
}
$column_names = is_array ( $columns ) ? $columns : explode ( ',' , $columns );
2022-11-18 16:27:56 -06:00
$valid_columns = $schema -> getColumns ( $table );
2017-11-14 15:15:12 +00:00
$invalid_columns = array_diff ( array_map ( 'trim' , $column_names ), $valid_columns );
if ( count ( $invalid_columns ) > 0 ) {
2022-11-18 16:27:56 -06:00
throw new InvalidTableColumnException ( $invalid_columns );
2017-11-14 15:15:12 +00:00
}
2019-07-29 16:32:37 -05:00
2022-11-18 16:27:56 -06:00
return $column_names ;
2017-11-14 15:15:12 +00:00
}
2018-01-21 20:56:57 +01:00
2020-02-26 06:12:36 -04:00
function missing_fields ( $required_fields , $data )
{
foreach ( $required_fields as $required ) {
if ( empty ( $data [ $required ])) {
return true ;
}
}
2020-09-21 15:40:17 +02:00
2020-02-26 06:12:36 -04:00
return false ;
}
2021-02-02 06:40:11 +00:00
function add_service_template_for_device_group ( Illuminate\Http\Request $request )
{
$data = json_decode ( $request -> getContent (), true );
if ( json_last_error () || ! is_array ( $data )) {
return api_error ( 400 , "We couldn't parse the provided json. " . json_last_error_msg ());
}
$rules = [
'name' => 'required|string|unique:service_templates' ,
'device_group_id' => 'integer' ,
'type' => 'string' ,
'param' => 'nullable|string' ,
'ip' => 'nullable|string' ,
'desc' => 'nullable|string' ,
'changed' => 'integer' ,
'disabled' => 'integer' ,
'ignore' => 'integer' ,
];
$v = Validator :: make ( $data , $rules );
if ( $v -> fails ()) {
return api_error ( 422 , $v -> messages ());
}
// Only use the rules if they are able to be parsed by the QueryBuilder
$query = QueryBuilderParser :: fromJson ( $data [ 'rules' ]) -> toSql ();
if ( empty ( $query )) {
return api_error ( 500 , "We couldn't parse your rule" );
}
$serviceTemplate = ServiceTemplate :: make ([ 'name' => $data [ 'name' ], 'device_group_id' => $data [ 'device_group_id' ], 'type' => $data [ 'type' ], 'param' => $data [ 'param' ], 'ip' => $data [ 'ip' ], 'desc' => $data [ 'desc' ], 'changed' => $data [ 'changed' ], 'disabled' => $data [ 'disabled' ], 'ignore' => $data [ 'ignore' ]]);
$serviceTemplate -> save ();
return api_success ( $serviceTemplate -> id , 'id' , 'Service Template ' . $serviceTemplate -> name . ' created' , 201 );
}
function get_service_templates ( Illuminate\Http\Request $request )
{
if ( $request -> user () -> cannot ( 'viewAny' , ServiceTemplate :: class )) {
return api_error ( 403 , 'Insufficient permissions to access service templates' );
}
$templates = ServiceTemplate :: query () -> orderBy ( 'name' ) -> get ();
if ( $templates -> isEmpty ()) {
return api_error ( 404 , 'No service templates found' );
}
return api_success ( $templates -> makeHidden ( 'pivot' ) -> toArray (), 'templates' , 'Found ' . $templates -> count () . ' service templates' );
}
2020-09-22 02:52:01 +02:00
function add_service_for_host ( Illuminate\Http\Request $request )
2018-01-21 20:56:57 +01:00
{
2019-07-29 16:32:37 -05:00
$hostname = $request -> route ( 'hostname' );
2018-01-21 20:56:57 +01:00
$device_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
2019-07-29 16:32:37 -05:00
$data = json_decode ( $request -> getContent (), true );
2020-02-26 06:12:36 -04:00
if ( missing_fields ([ 'type' ], $data )) {
return api_error ( 400 , 'Required fields missing (hostname and type needed)' );
2018-01-21 20:56:57 +01:00
}
if ( ! in_array ( $data [ 'type' ], list_available_services ())) {
2019-07-29 16:32:37 -05:00
return api_error ( 400 , 'The service ' . $data [ 'type' ] . " does not exist. \n Available service types: " . implode ( ', ' , list_available_services ()));
2018-01-21 20:56:57 +01:00
}
$service_type = $data [ 'type' ];
$service_ip = $data [ 'ip' ];
2019-07-29 16:32:37 -05:00
$service_desc = $data [ 'desc' ] ? $data [ 'desc' ] : '' ;
$service_param = $data [ 'param' ] ? $data [ 'param' ] : '' ;
2018-01-21 20:56:57 +01:00
$service_ignore = $data [ 'ignore' ] ? true : false ; // Default false
2021-02-02 06:40:11 +00:00
$service_disable = $data [ 'disable' ] ? true : false ; // Default false
$service_name = $data [ 'name' ];
$service_id = add_service ( $device_id , $service_type , $service_desc , $service_ip , $service_param , ( int ) $service_ignore , ( int ) $service_disable , 0 , $service_name );
2018-01-21 20:56:57 +01:00
if ( $service_id != false ) {
2019-07-29 16:32:37 -05:00
return api_success_noresult ( 201 , "Service $service_type has been added to device $hostname (# $service_id )" );
2018-01-21 20:56:57 +01:00
}
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_error ( 500 , 'Failed to add the service' );
2018-01-21 20:56:57 +01:00
}
2018-05-19 00:36:06 -04:00
2020-09-22 02:52:01 +02:00
function add_parents_to_host ( Illuminate\Http\Request $request )
2020-02-13 17:28:43 -04:00
{
$data = json_decode ( $request -> getContent (), true );
$device_id = $request -> route ( 'id' );
2020-11-19 03:23:07 +01:00
$device_id = ctype_digit ( $device_id ) ? $device_id : getidbyname ( $device_id );
$parent_ids = [];
foreach ( explode ( ',' , $data [ 'parent_ids' ]) as $hostname ) {
$hostname = trim ( $hostname );
$parent_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
if ( empty ( $parent_id )) {
return api_error ( 400 , 'Parent device IDs/Hostname does not exist: ' . $hostname );
}
$parent_ids [] = $parent_id ;
}
2020-02-13 17:28:43 -04:00
if ( validateDeviceIds ( $parent_ids ) && validateDeviceIds ([ $device_id ]) && ( ! in_array ( $device_id , $parent_ids ))) {
Device :: find ( $device_id ) -> parents () -> sync ( $parent_ids );
2020-09-21 15:40:17 +02:00
2020-02-13 17:28:43 -04:00
return api_success_noresult ( 201 , 'Device dependencies have been saved' );
}
2020-09-21 15:40:17 +02:00
2020-02-13 17:28:43 -04:00
return api_error ( 400 , 'Check your parent and device IDs' );
}
2020-09-22 02:52:01 +02:00
function del_parents_from_host ( Illuminate\Http\Request $request )
2020-02-13 17:28:43 -04:00
{
$device_id = $request -> route ( 'id' );
2020-11-19 03:23:07 +01:00
$device_id = ctype_digit ( $device_id ) ? $device_id : getidbyname ( $device_id );
2020-02-13 17:28:43 -04:00
$data = json_decode ( $request -> getContent (), true );
if ( ! validateDeviceIds ([ $device_id ])) {
return api_error ( 400 , 'Check your device ID!' );
}
$device = Device :: find ( $device_id );
if ( ! empty ( $data [ 'parent_ids' ])) {
2020-11-19 03:23:07 +01:00
foreach ( explode ( ',' , $data [ 'parent_ids' ]) as $hostname ) {
$hostname = trim ( $hostname );
$parent_id = ctype_digit ( $hostname ) ? $hostname : getidbyname ( $hostname );
if ( empty ( $parent_id )) {
return api_error ( 400 , 'Parent device IDs/Hostname does not exist: ' . $hostname );
}
$parent_ids [] = $parent_id ;
}
2020-02-13 17:28:43 -04:00
//remove parents included in the request if they are valid device ids
2020-11-19 03:23:07 +01:00
$result = validateDeviceIds ( $parent_ids ) ? $device -> parents () -> detach ( $parent_ids ) : false ;
2020-02-13 17:28:43 -04:00
}
if ( is_null ( $result )) {
//$result doesn't exist so $data['parent_ids'] is empty
$result = $device -> parents () -> detach (); //remove all parents
}
if ( $result ) {
return api_success_noresult ( 201 , 'All device dependencies have been removed' );
}
2020-09-21 15:40:17 +02:00
2020-02-13 17:28:43 -04:00
return api_error ( 400 , 'Device dependency cannot be deleted check device and parents ids' );
}
function validateDeviceIds ( $ids )
{
foreach ( $ids as $id ) {
$invalidId = ! is_numeric ( $id ) || $id < 1 || is_null ( Device :: find ( $id ));
if ( $invalidId ) {
return false ;
}
}
2020-09-21 15:40:17 +02:00
2020-02-13 17:28:43 -04:00
return true ;
}
2020-05-25 00:16:07 +02:00
2020-09-22 02:52:01 +02:00
function add_location ( Illuminate\Http\Request $request )
2020-02-26 06:12:36 -04:00
{
$data = json_decode ( $request -> getContent (), true );
if ( missing_fields ([ 'location' , 'lat' , 'lng' ], $data )) {
return api_error ( 400 , 'Required fields missing (location, lat and lng needed)' );
}
// Set the location
2021-12-27 17:32:50 -06:00
$location = new \App\Models\Location ( $data );
$location -> fixed_coordinates = $data [ 'fixed_coordinates' ] ?? $location -> coordinatesValid ();
if ( $location -> save ()) {
return api_success_noresult ( 201 , "Location added with id # $location->id " );
2020-02-26 06:12:36 -04:00
}
2020-09-21 15:40:17 +02:00
2020-02-26 06:12:36 -04:00
return api_error ( 500 , 'Failed to add the location' );
}
2020-09-22 02:52:01 +02:00
function edit_location ( Illuminate\Http\Request $request )
2020-02-26 06:12:36 -04:00
{
$location = $request -> route ( 'location_id_or_name' );
if ( empty ( $location )) {
return api_error ( 400 , 'No location has been provided to edit' );
}
$location_id = ctype_digit ( $location ) ? $location : get_location_id_by_name ( $location );
$data = json_decode ( $request -> getContent (), true );
if ( empty ( $location_id )) {
return api_error ( 400 , 'Failed to delete location' );
}
$result = dbUpdate ( $data , 'locations' , '`id` = ?' , [ $location_id ]);
if ( $result == 1 ) {
return api_success_noresult ( 201 , 'Location updated successfully' );
}
2020-09-21 15:40:17 +02:00
2020-02-26 06:12:36 -04:00
return api_error ( 500 , 'Failed to update location' );
}
2023-08-03 20:35:20 -04:00
function get_location ( Illuminate\Http\Request $request )
{
$location = $request -> route ( 'location_id_or_name' );
if ( empty ( $location )) {
return api_error ( 400 , 'No location has been provided to get' );
}
2023-10-25 13:05:04 -05:00
$data = ctype_digit ( $location ) ? Location :: find ( $location ) : Location :: where ( 'location' , $location ) -> first ();
2023-08-03 20:35:20 -04:00
if ( empty ( $data )) {
return api_error ( 404 , 'Location does not exist' );
}
return api_success ( $data , 'get_location' );
}
2020-02-26 06:12:36 -04:00
function get_location_id_by_name ( $location )
{
return dbFetchCell ( 'SELECT id FROM locations WHERE location = ?' , $location );
}
2020-09-22 02:52:01 +02:00
function del_location ( Illuminate\Http\Request $request )
2020-02-26 06:12:36 -04:00
{
$location = $request -> route ( 'location' );
if ( empty ( $location )) {
return api_error ( 400 , 'No location has been provided to delete' );
}
2022-09-13 09:03:55 -05:00
$location_id = ctype_digit ( $location ) ? $location : get_location_id_by_name ( $location );
2020-02-26 06:12:36 -04:00
if ( empty ( $location_id )) {
return api_error ( 400 , "Failed to delete $location (Does not exists)" );
}
$data = [
'location_id' => 0 ,
];
dbUpdate ( $data , 'devices' , '`location_id` = ?' , [ $location_id ]);
2024-07-02 01:50:56 +02:00
$result = dbDelete ( 'locations' , '`id` = ? ' , [ $location_id ]);
2020-02-26 06:12:36 -04:00
if ( $result == 1 ) {
return api_success_noresult ( 201 , "Location $location has been deleted successfully" );
}
2020-09-21 15:40:17 +02:00
2020-02-26 06:12:36 -04:00
return api_error ( 500 , "Failed to delete the location $location " );
}
2023-11-01 23:33:35 -04:00
function get_poller_group ( Illuminate\Http\Request $request )
{
$poller_group = $request -> route ( 'poller_group_id_or_name' );
if ( empty ( $poller_group )) {
return api_success ( PollerGroup :: get (), 'get_poller_group' );
}
$data = ctype_digit ( $poller_group ) ? PollerGroup :: find ( $poller_group ) : PollerGroup :: where ( 'group_name' , $poller_group ) -> first ();
if ( empty ( $data )) {
return api_error ( 404 , 'Poller Group does not exist' );
}
return api_success ( $data , 'get_poller_group' );
}
2020-09-22 02:52:01 +02:00
function del_service_from_host ( Illuminate\Http\Request $request )
2020-02-26 06:12:36 -04:00
{
$service_id = $request -> route ( 'id' );
if ( empty ( $service_id )) {
return api_error ( 400 , 'No service_id has been provided to delete' );
}
$result = delete_service ( $service_id );
if ( $result == 1 ) {
return api_success_noresult ( 201 , 'Service has been deleted successfully' );
}
2020-09-21 15:40:17 +02:00
2020-02-26 06:12:36 -04:00
return api_error ( 500 , 'Failed to delete the service' );
}
2021-08-10 02:33:04 +02:00
function search_by_mac ( Illuminate\Http\Request $request )
{
2023-10-06 07:34:14 -05:00
$macAddress = Mac :: parse (( string ) $request -> route ( 'search' )) -> hex ();
2021-08-10 02:33:04 +02:00
$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' );
}
2020-09-22 02:52:01 +02:00
function edit_service_for_host ( Illuminate\Http\Request $request )
2020-02-26 06:12:36 -04:00
{
$service_id = $request -> route ( 'id' );
$data = json_decode ( $request -> getContent (), true );
if ( edit_service ( $data , $service_id ) == 1 ) {
return api_success_noresult ( 201 , 'Service updated successfully' );
}
2020-09-21 15:40:17 +02:00
2020-02-26 06:12:36 -04:00
return api_error ( 500 , "Failed to update the service with id $service_id " );
}
2020-02-13 17:28:43 -04:00
2023-03-15 14:14:38 +01:00
/**
* recieve syslog messages via json https://github.com/librenms/librenms/pull/14424
*/
function post_syslogsink ( Illuminate\Http\Request $request )
{
$json = $request -> json () -> all ();
if ( is_null ( $json )) {
return api_success_noresult ( 400 , 'Not valid json' );
}
$logs = array_is_list ( $json ) ? $json : [ $json ];
foreach ( $logs as $entry ) {
process_syslog ( $entry , 1 );
}
return api_success_noresult ( 200 , 'Syslog received: ' . count ( $logs ));
}
2018-05-19 00:36:06 -04:00
/**
* Display Librenms Instance Info
*/
function server_info ()
{
2022-10-02 00:41:56 -05:00
$version = \LibreNMS\Util\Version :: get ();
$versions = [
'local_ver' => $version -> name (),
'local_sha' => $version -> git -> commitHash (),
'local_date' => $version -> date (),
'local_branch' => $version -> git -> branch (),
'db_schema' => $version -> database (),
'php_ver' => phpversion (),
'python_ver' => $version -> python (),
'database_ver' => $version -> databaseServer (),
'rrdtool_ver' => $version -> rrdtool (),
'netsnmp_ver' => $version -> netSnmp (),
];
2020-09-21 15:40:17 +02:00
2019-07-29 16:32:37 -05:00
return api_success ([
2018-05-19 00:36:06 -04:00
$versions ,
], 'system' );
}