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;
+ }
}
}