diff --git a/doc/API/API-Docs.md b/doc/API/API-Docs.md
index eacdcfada..185349b95 100644
--- a/doc/API/API-Docs.md
+++ b/doc/API/API-Docs.md
@@ -14,6 +14,9 @@
- [`get_graph_generic_by_hostname`](#api-route-6)
- [`get_port_graphs`](#api-route-7)
- [`get_components`](#api-route-25)
+ - [`add_components`](#api-route-26)
+ - [`edit_components`](#api-route-27)
+ - [`delete_components`](#api-route-28)
- [`get_port_stats_by_port_hostname`](#api-route-8)
- [`get_graph_by_port_hostname`](#api-route-9)
- [`list_devices`](#api-route-10)
@@ -336,6 +339,88 @@ Output:
}
```
+### Function: `add_components` [`top`](#top)
+
+Create a new component of a type on a particular device.
+
+Route: /api/v0/devices/:hostname/components/:type
+
+- hostname can be either the device hostname or id
+- type is the type of component to add
+
+Example:
+```curl
+curl -X POST -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/components/APITEST
+```
+
+Output:
+
+```text
+{
+ "status": "ok",
+ "err-msg": "",
+ "count": 1,
+ "components": {
+ "4459": {
+ "type": "APITEST",
+ "label": "",
+ "status": 1,
+ "ignore": 0,
+ "disabled": 0,
+ "error": ""
+ }
+ }
+}
+```
+
+### Function: `edit_components` [`top`](#top)
+
+Edit an existing component on a particular device.
+
+Route: /api/v0/devices/:hostname/components
+
+- hostname can be either the device hostname or id
+
+In this example we set the label and add a new field: TestField:
+```curl
+curl -X PUT -d '{"4459": {"type": "APITEST","label": "This is a test label","status": 1,"ignore": 0,"disabled": 0,"error": "","TestField": "TestData"}}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/components
+```
+
+Output:
+
+```text
+{
+ "status": "ok",
+ "err-msg": "",
+ "count": 1
+}
+```
+
+Just take the JSON array from add_components or edit_components, edit as you wish and submit it back to edit_components.
+
+### Function: `delete_components` [`top`](#top)
+
+Delete an existing component on a particular device.
+
+Route: /api/v0/devices/:hostname/components/:component
+
+- hostname can be either the device hostname or id
+- component is the component ID to be deleted.
+
+Example:
+```curl
+curl -X DELETE -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/components/4459
+```
+
+Output:
+
+```text
+{
+ "status": "ok",
+ "err-msg": ""
+}
+```
+
### Function: `get_port_stats_by_port_hostname` [`top`](#top)
Get information about a particular port for a device.
diff --git a/html/api_v0.php b/html/api_v0.php
index 389ac1db6..883b4609d 100644
--- a/html/api_v0.php
+++ b/html/api_v0.php
@@ -50,7 +50,9 @@ $app->group(
$app->get('/:hostname/ports', 'authToken', 'get_port_graphs')->name('get_port_graphs');
// api/v0/devices/$hostname/ports
$app->get('/:hostname/components', 'authToken', 'get_components')->name('get_components');
- // api/v0/devices/$hostname/components
+ $app->post('/:hostname/components/:type', 'authToken', 'add_components')->name('add_components');
+ $app->put('/:hostname/components', 'authToken', 'edit_components')->name('edit_components');
+ $app->delete('/:hostname/components/:component', 'authToken', 'delete_components')->name('delete_components');
$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
diff --git a/html/includes/api_functions.inc.php b/html/includes/api_functions.inc.php
index 1a857869d..834904fff 100644
--- a/html/includes/api_functions.inc.php
+++ b/html/includes/api_functions.inc.php
@@ -535,8 +535,8 @@ function get_components() {
unset ($_GET['label']);
}
// Add the rest of the options with an equals query
- foreach ($_GET as $k) {
- $options['filter'][$k] = array('=',$_GET[$k]);
+ foreach ($_GET as $k => $v) {
+ $options['filter'][$k] = array('=',$v);
}
// use hostname as device_id if it's all digits
@@ -556,6 +556,100 @@ function get_components() {
}
+function add_components() {
+ global $config;
+ $code = 200;
+ $status = 'ok';
+ $message = '';
+ $app = \Slim\Slim::getInstance();
+ $router = $app->router()->getCurrentRoute()->getParams();
+ $hostname = $router['hostname'];
+ $ctype = $router['type'];
+
+ // use hostname as device_id if it's all digits
+ $device_id = ctype_digit($hostname) ? $hostname : getidbyname($hostname);
+ $COMPONENT = new component();
+ $component = $COMPONENT->createComponent($device_id,$ctype);
+
+ $output = array(
+ 'status' => "$status",
+ 'err-msg' => $message,
+ 'count' => count($component),
+ 'components' => $component,
+ );
+ $app->response->setStatus($code);
+ $app->response->headers->set('Content-Type', 'application/json');
+ echo _json_encode($output);
+}
+
+
+function edit_components() {
+ global $config;
+ $app = \Slim\Slim::getInstance();
+ $router = $app->router()->getCurrentRoute()->getParams();
+ $hostname = $router['hostname'];
+ $data = json_decode(file_get_contents('php://input'), true);
+
+ // use hostname as device_id if it's all digits
+ $device_id = ctype_digit($hostname) ? $hostname : getidbyname($hostname);
+ $COMPONENT = new component();
+
+ if ($COMPONENT->setComponentPrefs($device_id,$data)) {
+ // Edit Success.
+ $code = 200;
+ $status = 'ok';
+ $message = '';
+ }
+ else {
+ // Edit Failure.
+ $code = 500;
+ $status = 'error';
+ $message = 'Components could not be edited.';
+ }
+
+ $output = array(
+ 'status' => "$status",
+ 'err-msg' => $message,
+ 'count' => count($data),
+ );
+
+ $app->response->setStatus($code);
+ $app->response->headers->set('Content-Type', 'application/json');
+ echo _json_encode($output);
+}
+
+
+function delete_components() {
+ global $config;
+ $app = \Slim\Slim::getInstance();
+ $router = $app->router()->getCurrentRoute()->getParams();
+ $cid = $router['component'];
+
+ $COMPONENT = new component();
+ if ($COMPONENT->deleteComponent($cid)) {
+ // Edit Success.
+ $code = 200;
+ $status = 'ok';
+ $message = '';
+ }
+ else {
+ // Edit Failure.
+ $code = 500;
+ $status = 'error';
+ $message = 'Components could not be deleted.';
+ }
+
+ $output = array(
+ 'status' => "$status",
+ 'err-msg' => $message,
+ );
+
+ $app->response->setStatus($code);
+ $app->response->headers->set('Content-Type', 'application/json');
+ echo _json_encode($output);
+}
+
+
function get_graphs() {
global $config;
$code = 200;