diff --git a/doc/API/API-Docs.md b/doc/API/API-Docs.md index 538496c84d..09d3771b63 100644 --- a/doc/API/API-Docs.md +++ b/doc/API/API-Docs.md @@ -19,6 +19,10 @@ - [`add_device`](#api-route-11) - [`list_oxidized`](#api-route-21) - [`update_device_field`](#api-route-update_device_field) + - [`get_device_groups`](#api-route-get_device_groups) + - [`devicegroups`](#api-devicegroups) + - [`get_devicegroups`](#api-route-get_devicegroups) + - [`get_devices_by_group`](#api-route-get_devices_by_group) - [`routing`](#api-routing) - [`list_bgp`](#api-route-1) - [`switching`](#api-switching) @@ -470,6 +474,8 @@ Update devices field in the database. Route: /api/v0/devices/:hostname +- hostname can be either the device hostname or id + Input (JSON): - field: The column name within the database @@ -491,6 +497,154 @@ Output: ] ``` +### Function `get_device_groups` [`top`](#top) + +List the device groups that a device is matched on. + +Route: /api/v0/devices/:hostname/groups + +- hostname can be either the device hostname or id + +Input (JSON): + + - + +Examples: +```curl +curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/groups +``` + +Output: +```text +[ + { + "status": "ok", + "message": "Found 1 device groups", + "count": 1, + "groups": [ + { + "id": "1", + "name": "Testing", + "desc": "Testing", + "pattern": "%devices.status = \"1\" &&" + } + ] + } +] +``` + +## `Device Groups` [`top`](#top) + +### Function `get_devicegroups` [`top`](#top) + +List all device groups. + +Route: /api/v0/devicegroups + +Input (JSON): + + - + +Examples: +```curl +curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devicegroups +``` + +Output: +```text +[ + { + "status": "ok", + "message": "Found 1 device groups", + "count": 1, + "groups": [ + { + "id": "1", + "name": "Testing", + "desc": "Testing", + "pattern": "%devices.status = \"1\" &&" + } + ] + } +] +``` + +### Function `get_devices_by_group` [`top`](#top) + +List all devices matching the group provided. + +Route: /api/v0/devicegroups/:name + +- name Is the name of the device group which can be obtained using [`get_devicegroups`](#api-route-get_devicegroups). Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded. + +Input (JSON): + + - + +Examples: +```curl +curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devicegroups/LinuxServers +``` + +Output: +```text +[ + { + "status": "error", + "message": "Found 1 in group LinuxServers", + "count": 1, + "devices": [ + { + "device_id": "1", + "hostname": "localhost", + "sysName": "hostname", + "community": "librenms", + "authlevel": null, + "authname": null, + "authpass": null, + "authalgo": null, + "cryptopass": null, + "cryptoalgo": null, + "snmpver": "v2c", + "port": "161", + "transport": "udp", + "timeout": null, + "retries": null, + "bgpLocalAs": null, + "sysObjectID": ".1.3.6.1.4.1.8072.3.2.10", + "sysDescr": "Linux li1045-133.members.linode.com 4.1.5-x86_64-linode61 #7 SMP Mon Aug 24 13:46:31 EDT 2015 x86_64", + "sysContact": "", + "version": "4.1.5-x86_64-linode61", + "hardware": "Generic x86 64-bit", + "features": "CentOS 7.1.1503", + "location": "", + "os": "linux", + "status": "1", + "status_reason": "", + "ignore": "0", + "disabled": "0", + "uptime": "4615964", + "agent_uptime": "0", + "last_polled": "2015-12-12 13:20:04", + "last_poll_attempted": null, + "last_polled_timetaken": "1.90", + "last_discovered_timetaken": "79.53", + "last_discovered": "2015-12-12 12:34:21", + "last_ping": "2015-12-12 13:20:04", + "last_ping_timetaken": "0.08", + "purpose": null, + "type": "server", + "serial": null, + "icon": null, + "poller_group": "0", + "override_sysLocation": "0", + "notes": "Nope" + } + ] + } +] +``` + ## `Routing` [`top`](#top) ### Function: `list_bgp` [`top`](#top) diff --git a/html/api_v0.php b/html/api_v0.php index 426591162b..e46c0a3ea8 100644 --- a/html/api_v0.php +++ b/html/api_v0.php @@ -49,6 +49,7 @@ $app->group( // api/v0/devices/$hostname/graphs $app->get('/:hostname/ports', 'authToken', 'get_port_graphs')->name('get_port_graphs'); // api/v0/devices/$hostname/ports + $app->get('/:hostname/groups', 'authToken', 'get_device_groups')->name('get_device_groups'); $app->get('/:hostname/:type', 'authToken', 'get_graph_generic_by_hostname')->name('get_graph_generic_by_hostname'); // api/v0/devices/$hostname/$type $app->get('/:hostname/ports/:ifname', 'authToken', 'get_port_stats_by_port_hostname')->name('get_port_stats_by_port_hostname'); @@ -61,6 +62,13 @@ $app->group( // api/v0/devices $app->post('/devices', 'authToken', 'add_device')->name('add_device'); // api/v0/devices (json data needs to be passed) + $app->group( + '/devicegroups', + function () use ($app) { + $app->get('/:name', 'authToken', 'get_devices_by_group')->name('get_devices_by_group'); + } + ); + $app->get('/devicegroups', 'authToken', 'get_device_groups')->name('get_devicegroups'); $app->group( '/portgroups', function () use ($app) { diff --git a/html/includes/api_functions.inc.php b/html/includes/api_functions.inc.php index 5e9356022e..cbba6fbba5 100644 --- a/html/includes/api_functions.inc.php +++ b/html/includes/api_functions.inc.php @@ -13,7 +13,7 @@ */ require_once '../includes/functions.php'; - +require_once '../includes/device-groups.inc.php'; function authToken(\Slim\Route $route) { $app = \Slim\Slim::getInstance(); @@ -1021,3 +1021,73 @@ function update_device() { $app->response->headers->set('Content-Type', 'application/json'); echo _json_encode($output); } + +function get_device_groups() { + $app = \Slim\Slim::getInstance(); + $router = $app->router()->getCurrentRoute()->getParams(); + $status = 'error'; + $code = 404; + $hostname = $router['hostname']; + // use hostname as device_id if it's all digits + $device_id = ctype_digit($hostname) ? $hostname : getidbyname($hostname); + if (is_numeric($device_id)) { + $groups = GetGroupsFromDevice($device_id,1); + } + else { + $groups = GetDeviceGroups(); + } + if (empty($groups)) { + $message = 'No device groups found'; + } + else { + $status = 'ok'; + $code = 200; + $message = 'Found ' . count($groups) . ' device groups'; + } + + $output = array( + 'status' => $status, + 'message' => $message, + 'count' => count($groups), + 'groups' => $groups, + ); + $app->response->setStatus($code); + $app->response->headers->set('Content-Type', 'application/json'); + echo _json_encode($output); +} + +function get_devices_by_group() { + $app = \Slim\Slim::getInstance(); + $router = $app->router()->getCurrentRoute()->getParams(); + $status = 'error'; + $code = 404; + $count = 0; + $name = urldecode($router['name']); + $devices = array(); + if (empty($name)) { + $message = 'No device group name provided'; + } + else { + $group_id = dbFetchCell("SELECT `id` FROM `device_groups` WHERE `name`=?",array($name)); + $devices = GetDevicesFromGroup($group_id); + $count = count($devices); + if (empty($devices)) { + $message = 'No devices found in group ' . $name; + } + else { + $message = "Found $count in group $name"; + $code = 200; + } + } + $output = array( + 'status' => $status, + 'message' => $message, + 'count' => $count, + 'devices' => $devices, + ); + + $app->response->setStatus($code); + $app->response->headers->set('Content-Type', 'application/json'); + echo _json_encode($output); + +} diff --git a/includes/device-groups.inc.php b/includes/device-groups.inc.php index 45d5afcd21..3624db490c 100644 --- a/includes/device-groups.inc.php +++ b/includes/device-groups.inc.php @@ -31,7 +31,7 @@ * @param string $search What to searchid for * @return string */ -function GenGroupSQL($pattern, $search='') { +function GenGroupSQL($pattern, $search='',$extra=0) { $pattern = RunGroupMacros($pattern); if ($pattern === false) { return false; @@ -66,7 +66,11 @@ function GenGroupSQL($pattern, $search='') { $search .= ' &&'; } - $sql = 'SELECT DISTINCT('.str_replace('(', '', $tables[0]).'.device_id) FROM '.implode(',', $tables).' WHERE '.$search.' ('.str_replace(array('%', '@', '!~', '~'), array('', '.*', 'NOT REGEXP', 'REGEXP'), $pattern).')'; + $sql_extra = ''; + if ($extra === 1) { + $sql_extra = ",`devices`.*"; + } + $sql = 'SELECT DISTINCT('.str_replace('(', '', $tables[0]).'.device_id)'.$sql_extra.' FROM '.implode(',', $tables).' WHERE '.$search.' ('.str_replace(array('%', '@', '!~', '~'), array('', '.*', 'NOT REGEXP', 'REGEXP'), $pattern).')'; return $sql; }//end GenGroupSQL() @@ -99,17 +103,21 @@ function GetDeviceGroups() { }//end GetDeviceGroups() - /** * Get all groups of Device * @param integer $device Device-ID * @return array */ -function GetGroupsFromDevice($device) { +function GetGroupsFromDevice($device,$extra=0) { $ret = array(); foreach (GetDeviceGroups() as $group) { - if (dbFetchCell(GenGroupSQL($group['pattern'], 'device_id=?').' LIMIT 1', array($device)) == $device) { - $ret[] = $group['id']; + if (dbFetchCell(GenGroupSQL($group['pattern'], 'device_id=?',$extra).' LIMIT 1', array($device)) == $device) { + if ($extra === 0) { + $ret[] = $group['id']; + } + else { + $ret[] = $group; + } } }