mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-06 17:15:38 -08:00
docs
This commit is contained in:
353
docs/API.md
353
docs/API.md
@@ -1,6 +1,6 @@
|
|||||||
# API endpoints
|
# NetAlertX API Documentation
|
||||||
|
|
||||||
NetAlertX comes with a couple of API endpoints. All requests need to be authorized (executed in a logged in browser session) or you have to pass the value of the `API_TOKEN` settings as authorization bearer, for example:
|
This API provides programmatic access to **devices, events, sessions, metrics, network tools, and sync** in NetAlertX. It is implemented as a **REST and GraphQL server**. All requests require authentication via **API Token** (`API_TOKEN` setting) unless explicitly noted.
|
||||||
|
|
||||||
```graphql
|
```graphql
|
||||||
curl 'http://host:GRAPHQL_PORT/graphql' \
|
curl 'http://host:GRAPHQL_PORT/graphql' \
|
||||||
@@ -21,347 +21,56 @@ curl 'http://host:GRAPHQL_PORT/graphql' \
|
|||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
## API Endpoint: GraphQL
|
It runs on `0.0.0.0:<graphql_port>` with **CORS enabled** for all main endpoints.
|
||||||
|
|
||||||
- Endpoint URL: `php/server/query_graphql.php`
|
---
|
||||||
- Host: `same as front end (web ui)`
|
|
||||||
- Port: `20212` or as defined by the `GRAPHQL_PORT` setting
|
|
||||||
|
|
||||||
### Example Query to Fetch Devices
|
## Authentication
|
||||||
|
|
||||||
First, let's define the GraphQL query to fetch devices with pagination and sorting options.
|
All endpoints require an API token provided in the HTTP headers:
|
||||||
|
|
||||||
```graphql
|
```http
|
||||||
query GetDevices($options: PageQueryOptionsInput) {
|
Authorization: Bearer <API_TOKEN>
|
||||||
devices(options: $options) {
|
|
||||||
devices {
|
|
||||||
rowid
|
|
||||||
devMac
|
|
||||||
devName
|
|
||||||
devOwner
|
|
||||||
devType
|
|
||||||
devVendor
|
|
||||||
devLastConnection
|
|
||||||
devStatus
|
|
||||||
}
|
|
||||||
count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
See also: [Debugging GraphQL issues](./DEBUG_GRAPHQL.md)
|
If the token is missing or invalid, the server will return:
|
||||||
|
|
||||||
### `curl` Command
|
|
||||||
|
|
||||||
You can use the following `curl` command to execute the query.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
curl 'http://host:GRAPHQL_PORT/graphql' -X POST -H 'Authorization: Bearer API_TOKEN' -H 'Content-Type: application/json' --data '{
|
|
||||||
"query": "query GetDevices($options: PageQueryOptionsInput) { devices(options: $options) { devices { rowid devMac devName devOwner devType devVendor devLastConnection devStatus } count } }",
|
|
||||||
"variables": {
|
|
||||||
"options": {
|
|
||||||
"page": 1,
|
|
||||||
"limit": 10,
|
|
||||||
"sort": [{ "field": "devName", "order": "asc" }],
|
|
||||||
"search": "",
|
|
||||||
"status": "connected"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Explanation:
|
|
||||||
|
|
||||||
1. **GraphQL Query**:
|
|
||||||
- The `query` parameter contains the GraphQL query as a string.
|
|
||||||
- The `variables` parameter contains the input variables for the query.
|
|
||||||
|
|
||||||
2. **Query Variables**:
|
|
||||||
- `page`: Specifies the page number of results to fetch.
|
|
||||||
- `limit`: Specifies the number of results per page.
|
|
||||||
- `sort`: Specifies the sorting options, with `field` being the field to sort by and `order` being the sort order (`asc` for ascending or `desc` for descending).
|
|
||||||
- `search`: A search term to filter the devices.
|
|
||||||
- `status`: The status filter to apply (valid values are `my_devices` (determined by the `UI_MY_DEVICES` setting), `connected`, `favorites`, `new`, `down`, `archived`, `offline`).
|
|
||||||
|
|
||||||
3. **`curl` Command**:
|
|
||||||
- The `-X POST` option specifies that we are making a POST request.
|
|
||||||
- The `-H "Content-Type: application/json"` option sets the content type of the request to JSON.
|
|
||||||
- The `-d` option provides the request payload, which includes the GraphQL query and variables.
|
|
||||||
|
|
||||||
### Sample Response
|
|
||||||
|
|
||||||
The response will be in JSON format, similar to the following:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{ "error": "Forbidden" }
|
||||||
"data": {
|
|
||||||
"devices": {
|
|
||||||
"devices": [
|
|
||||||
{
|
|
||||||
"rowid": 1,
|
|
||||||
"devMac": "00:11:22:33:44:55",
|
|
||||||
"devName": "Device 1",
|
|
||||||
"devOwner": "Owner 1",
|
|
||||||
"devType": "Type 1",
|
|
||||||
"devVendor": "Vendor 1",
|
|
||||||
"devLastConnection": "2025-01-01T00:00:00Z",
|
|
||||||
"devStatus": "connected"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rowid": 2,
|
|
||||||
"devMac": "66:77:88:99:AA:BB",
|
|
||||||
"devName": "Device 2",
|
|
||||||
"devOwner": "Owner 2",
|
|
||||||
"devType": "Type 2",
|
|
||||||
"devVendor": "Vendor 2",
|
|
||||||
"devLastConnection": "2025-01-02T00:00:00Z",
|
|
||||||
"devStatus": "connected"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"count": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## API Endpoint: JSON files
|
|
||||||
|
|
||||||
This API endpoint retrieves static files, that are periodically updated.
|
|
||||||
|
|
||||||
- Endpoint URL: `php/server/query_json.php?file=<file name>`
|
|
||||||
- Host: `same as front end (web ui)`
|
|
||||||
- Port: `20211` or as defined by the $PORT docker environment variable (same as the port for the web ui)
|
|
||||||
|
|
||||||
### When are the endpoints updated
|
|
||||||
|
|
||||||
The endpoints are updated when objects in the API endpoints are changed.
|
|
||||||
|
|
||||||
### Location of the endpoints
|
|
||||||
|
|
||||||
In the container, these files are located under the `/app/api/` folder. You can access them via the `/php/server/query_json.php?file=user_notifications.json` endpoint.
|
|
||||||
|
|
||||||
### Available endpoints
|
|
||||||
|
|
||||||
You can access the following files:
|
|
||||||
|
|
||||||
| File name | Description |
|
|
||||||
|----------------------|----------------------|
|
|
||||||
| `notification_json_final.json` | The json version of the last notification (e.g. used for webhooks - [sample JSON](https://github.com/jokob-sk/NetAlertX/blob/main/front/report_templates/webhook_json_sample.json)). |
|
|
||||||
| `table_devices.json` | All of the available Devices detected by the app. |
|
|
||||||
| `table_plugins_events.json` | The list of the unprocessed (pending) notification events (plugins_events DB table). |
|
|
||||||
| `table_plugins_history.json` | The list of notification events history. |
|
|
||||||
| `table_plugins_objects.json` | The content of the plugins_objects table. Find more info on the [Plugin system here](https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md)|
|
|
||||||
| `language_strings.json` | The content of the language_strings table, which in turn is loaded from the plugins `config.json` definitions. |
|
|
||||||
| `table_custom_endpoint.json` | A custom endpoint generated by the SQL query specified by the `API_CUSTOM_SQL` setting. |
|
|
||||||
| `table_settings.json` | The content of the settings table. |
|
|
||||||
| `app_state.json` | Contains the current application state. |
|
|
||||||
|
|
||||||
|
|
||||||
### JSON Data format
|
|
||||||
|
|
||||||
The endpoints starting with the `table_` prefix contain most, if not all, data contained in the corresponding database table. The common format for those is:
|
|
||||||
|
|
||||||
```JSON
|
|
||||||
{
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"db_column_name": "data",
|
|
||||||
"db_column_name2": "data2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"db_column_name": "data3",
|
|
||||||
"db_column_name2": "data4"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Example JSON of the `table_devices.json` endpoint with two Devices (database rows):
|
|
||||||
|
|
||||||
```JSON
|
|
||||||
{
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"devMac": "Internet",
|
|
||||||
"devName": "Net - Huawei",
|
|
||||||
"devType": "Router",
|
|
||||||
"devVendor": null,
|
|
||||||
"devGroup": "Always on",
|
|
||||||
"devFirstConnection": "2021-01-01 00:00:00",
|
|
||||||
"devLastConnection": "2021-01-28 22:22:11",
|
|
||||||
"devLastIP": "192.168.1.24",
|
|
||||||
"devStaticIP": 0,
|
|
||||||
"devPresentLastScan": 1,
|
|
||||||
"devLastNotification": "2023-01-28 22:22:28.998715",
|
|
||||||
"devIsNew": 0,
|
|
||||||
"devParentMAC": "",
|
|
||||||
"devParentPort": "",
|
|
||||||
"devIcon": "globe"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"devMac": "a4:8f:ff:aa:ba:1f",
|
|
||||||
"devName": "Net - USG",
|
|
||||||
"devType": "Firewall",
|
|
||||||
"devVendor": "Ubiquiti Inc",
|
|
||||||
"devGroup": "",
|
|
||||||
"devFirstConnection": "2021-02-12 22:05:00",
|
|
||||||
"devLastConnection": "2021-07-17 15:40:00",
|
|
||||||
"devLastIP": "192.168.1.1",
|
|
||||||
"devStaticIP": 1,
|
|
||||||
"devPresentLastScan": 1,
|
|
||||||
"devLastNotification": "2021-07-17 15:40:10.667717",
|
|
||||||
"devIsNew": 0,
|
|
||||||
"devParentMAC": "Internet",
|
|
||||||
"devParentPort": 1,
|
|
||||||
"devIcon": "shield-halved"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## API Endpoint: Prometheus Exporter
|
|
||||||
|
|
||||||
* **Endpoint URL**: `/metrics`
|
|
||||||
* **Host**: (where NetAlertX exporter is running)
|
|
||||||
* **Port**: as configured in the `GRAPHQL_PORT` setting (`20212` by default)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Example Output of the `/metrics` Endpoint
|
|
||||||
|
|
||||||
Below is a representative snippet of the metrics you may find when querying the `/metrics` endpoint for `netalertx`. It includes both aggregate counters and `device_status` labels per device.
|
|
||||||
|
|
||||||
```
|
|
||||||
netalertx_connected_devices 31
|
|
||||||
netalertx_offline_devices 54
|
|
||||||
netalertx_down_devices 0
|
|
||||||
netalertx_new_devices 0
|
|
||||||
netalertx_archived_devices 31
|
|
||||||
netalertx_favorite_devices 2
|
|
||||||
netalertx_my_devices 54
|
|
||||||
|
|
||||||
netalertx_device_status{device="Net - Huawei", mac="Internet", ip="1111.111.111.111", vendor="None", first_connection="2021-01-01 00:00:00", last_connection="2025-08-04 17:57:00", dev_type="Router", device_status="Online"} 1
|
|
||||||
netalertx_device_status{device="Net - USG", mac="74:ac:74:ac:74:ac", ip="192.168.1.1", vendor="Ubiquiti Networks Inc.", first_connection="2022-02-12 22:05:00", last_connection="2025-06-07 08:16:49", dev_type="Firewall", device_status="Archived"} 1
|
|
||||||
netalertx_device_status{device="Raspberry Pi 4 LAN", mac="74:ac:74:ac:74:74", ip="192.168.1.9", vendor="Raspberry Pi Trading Ltd", first_connection="2022-02-12 22:05:00", last_connection="2025-08-04 17:57:00", dev_type="Singleboard Computer (SBC)", device_status="Online"} 1
|
|
||||||
...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Metrics Explanation
|
## Base URL
|
||||||
|
|
||||||
#### 1. Aggregate Device Counts
|
```
|
||||||
|
http://<server>:<GRAPHQL_PORT>/
|
||||||
Metric names prefixed with `netalertx_` provide aggregated counts by device status:
|
```
|
||||||
|
|
||||||
* `netalertx_connected_devices`: number of devices currently connected
|
|
||||||
* `netalertx_offline_devices`: devices currently offline
|
|
||||||
* `netalertx_down_devices`: down/unreachable devices
|
|
||||||
* `netalertx_new_devices`: devices recently detected
|
|
||||||
* `netalertx_archived_devices`: archived devices
|
|
||||||
* `netalertx_favorite_devices`: user-marked favorite devices
|
|
||||||
* `netalertx_my_devices`: devices associated with the current user context
|
|
||||||
|
|
||||||
These numeric values give a high-level overview of device distribution.
|
|
||||||
|
|
||||||
#### 2. Per‑Device Status with Labels
|
|
||||||
|
|
||||||
Each individual device is represented by a `netalertx_device_status` metric, with descriptive labels:
|
|
||||||
|
|
||||||
* `device`: friendly name of the device
|
|
||||||
* `mac`: MAC address (or placeholder)
|
|
||||||
* `ip`: last recorded IP address
|
|
||||||
* `vendor`: manufacturer or "None" if unknown
|
|
||||||
* `first_connection`: timestamp when the device was first observed
|
|
||||||
* `last_connection`: most recent contact timestamp
|
|
||||||
* `dev_type`: device category or type
|
|
||||||
* `device_status`: current status (Online / Offline / Archived / Down / ...)
|
|
||||||
|
|
||||||
The metric value is always `1` (indicating presence or active state) and the combination of labels identifies the device.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### How to Query with `curl`
|
## Endpoints
|
||||||
|
|
||||||
To fetch the metrics from the NetAlertX exporter:
|
* [Device API Endpoints](API_DEVICE.md) – Manage individual devices
|
||||||
|
* [Devices Collection](API_DEVICES.md) – Bulk operations on multiple devices
|
||||||
|
* [Events](API_EVENTS.md) – Device event logging and management
|
||||||
|
* [Sessions](API_SESSIONS.md) – Connection sessions and history
|
||||||
|
* [Metrics](API_METRICS.md) – Prometheus metrics and per-device status
|
||||||
|
* [Network Tools](API_NETTOOLS.md) – Utilities like Wake-on-LAN, traceroute, nslookup, nmap, and internet info
|
||||||
|
* [Online History](API_ONLINEHISTORY.md) – Online/offline device records
|
||||||
|
* [GraphQL](API_GRAPHQL.md) – Advanced queries and filtering
|
||||||
|
* [Sync](API_SYNC.md) – Synchronization between multiple NetAlertX instances
|
||||||
|
|
||||||
```sh
|
See [Testing](API_TESTS.md) for example requests and usage.
|
||||||
curl 'http://<server_ip>:<GRAPHQL_PORT>/metrics' \
|
|
||||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
|
||||||
-H 'Accept: text/plain'
|
|
||||||
```
|
|
||||||
|
|
||||||
Replace:
|
|
||||||
|
|
||||||
* `<server_ip>`: IP or hostname of the NetAlertX server
|
|
||||||
* `<GRAPHQL_PORT>`: port specified in your `GRAPHQL_PORT` setting (default: `20212`)
|
|
||||||
* `<API_TOKEN>` your Bearer token from the `API_TOKEN` setting
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Summary
|
## Notes
|
||||||
|
|
||||||
* **Endpoint**: `/metrics` provides both summary counters and per-device status entries.
|
* All endpoints enforce **Bearer token authentication**.
|
||||||
* **Aggregate metrics** help monitor overall device states.
|
* Errors return JSON with `success: False` and an error message.
|
||||||
* **Detailed metrics** expose each device’s metadata via labels.
|
* GraphQL is available for advanced queries, while REST endpoints cover structured use cases.
|
||||||
* **Use case**: feed into Prometheus for scraping, monitoring, alerting, or charting dashboard views.
|
* Endpoints run on `0.0.0.0:<GRAPHQL_PORT>` with **CORS enabled**.
|
||||||
|
* Use consistent API tokens and node/plugin names when interacting with `/sync` to ensure data integrity.
|
||||||
### Prometheus Scraping Configuration
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
scrape_configs:
|
|
||||||
- job_name: 'netalertx'
|
|
||||||
metrics_path: /metrics
|
|
||||||
scheme: http
|
|
||||||
scrape_interval: 60s
|
|
||||||
static_configs:
|
|
||||||
- targets: ['<server_ip>:<GRAPHQL_PORT>']
|
|
||||||
authorization:
|
|
||||||
type: Bearer
|
|
||||||
credentials: <API_TOKEN>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Grafana template
|
|
||||||
|
|
||||||
Grafana template sample: [Download json](./samples/API/Grafana_Dashboard.json)
|
|
||||||
|
|
||||||
## API Endpoint: /log files
|
|
||||||
|
|
||||||
This API endpoint retrieves files from the `/app/log` folder.
|
|
||||||
|
|
||||||
- Endpoint URL: `php/server/query_logs.php?file=<file name>`
|
|
||||||
- Host: `same as front end (web ui)`
|
|
||||||
- Port: `20211` or as defined by the $PORT docker environment variable (same as the port for the web ui)
|
|
||||||
|
|
||||||
| File | Description |
|
|
||||||
|--------------------------|---------------------------------------------------------------|
|
|
||||||
| `IP_changes.log` | Logs of IP address changes |
|
|
||||||
| `app.log` | Main application log |
|
|
||||||
| `app.php_errors.log` | PHP error log |
|
|
||||||
| `app_front.log` | Frontend application log |
|
|
||||||
| `app_nmap.log` | Logs of Nmap scan results |
|
|
||||||
| `db_is_locked.log` | Logs when the database is locked |
|
|
||||||
| `execution_queue.log` | Logs of execution queue activities |
|
|
||||||
| `plugins/` | Directory for temporary plugin-related files (not accessible) |
|
|
||||||
| `report_output.html` | HTML report output |
|
|
||||||
| `report_output.json` | JSON format report output |
|
|
||||||
| `report_output.txt` | Text format report output |
|
|
||||||
| `stderr.log` | Logs of standard error output |
|
|
||||||
| `stdout.log` | Logs of standard output |
|
|
||||||
|
|
||||||
|
|
||||||
## API Endpoint: /config files
|
|
||||||
|
|
||||||
To retrieve files from the `/app/config` folder.
|
|
||||||
|
|
||||||
- Endpoint URL: `php/server/query_config.php?file=<file name>`
|
|
||||||
- Host: `same as front end (web ui)`
|
|
||||||
- Port: `20211` or as defined by the $PORT docker environment variable (same as the port for the web ui)
|
|
||||||
|
|
||||||
| File | Description |
|
|
||||||
|--------------------------|--------------------------------------------------|
|
|
||||||
| `devices.csv` | Devices csv file |
|
|
||||||
| `app.conf` | Application config file |
|
|
||||||
|
|
||||||
|
|||||||
233
docs/API_DEVICE.md
Executable file
233
docs/API_DEVICE.md
Executable file
@@ -0,0 +1,233 @@
|
|||||||
|
# Device API Endpoints
|
||||||
|
|
||||||
|
Manage a **single device** by its MAC address. Operations include retrieval, updates, deletion, resetting properties, and copying data between devices. All endpoints require **authorization** via Bearer token.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Retrieve Device Details
|
||||||
|
|
||||||
|
* **GET** `/device/<mac>`
|
||||||
|
Fetch all details for a single device, including:
|
||||||
|
|
||||||
|
* Computed status (`devStatus`) → `On-line`, `Off-line`, or `Down`
|
||||||
|
* Session and event counts (`devSessions`, `devEvents`, `devDownAlerts`)
|
||||||
|
* Presence hours (`devPresenceHours`)
|
||||||
|
* Children devices (`devChildrenDynamic`) and NIC children (`devChildrenNicsDynamic`)
|
||||||
|
|
||||||
|
**Special case**: `mac=new` returns a template for a new device with default values.
|
||||||
|
|
||||||
|
**Response** (success):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"devMac": "AA:BB:CC:DD:EE:FF",
|
||||||
|
"devName": "Net - Huawei",
|
||||||
|
"devOwner": "Admin",
|
||||||
|
"devType": "Router",
|
||||||
|
"devVendor": "Huawei",
|
||||||
|
"devStatus": "On-line",
|
||||||
|
"devSessions": 12,
|
||||||
|
"devEvents": 5,
|
||||||
|
"devDownAlerts": 1,
|
||||||
|
"devPresenceHours": 32,
|
||||||
|
"devChildrenDynamic": [...],
|
||||||
|
"devChildrenNicsDynamic": [...],
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Device not found → HTTP 404
|
||||||
|
* Unauthorized → HTTP 403
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Update Device Fields
|
||||||
|
|
||||||
|
* **POST** `/device/<mac>`
|
||||||
|
Create or update a device record.
|
||||||
|
|
||||||
|
**Request Body**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"devName": "New Device",
|
||||||
|
"devOwner": "Admin",
|
||||||
|
"createNew": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Behavior**:
|
||||||
|
|
||||||
|
* If `createNew=true` → creates a new device
|
||||||
|
* Otherwise → updates existing device fields
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Unauthorized → HTTP 403
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Delete a Device
|
||||||
|
|
||||||
|
* **DELETE** `/device/<mac>/delete`
|
||||||
|
Deletes the device with the given MAC.
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Unauthorized → HTTP 403
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Delete All Events for a Device
|
||||||
|
|
||||||
|
* **DELETE** `/device/<mac>/events/delete`
|
||||||
|
Removes all events associated with a device.
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Reset Device Properties
|
||||||
|
|
||||||
|
* **POST** `/device/<mac>/reset-props`
|
||||||
|
Resets the device's custom properties to default values.
|
||||||
|
|
||||||
|
**Request Body**: Optional JSON for additional parameters.
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Copy Device Data
|
||||||
|
|
||||||
|
* **POST** `/device/copy`
|
||||||
|
Copy all data from one device to another. If a device exists with `macTo`, it is replaced.
|
||||||
|
|
||||||
|
**Request Body**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"macFrom": "AA:BB:CC:DD:EE:FF",
|
||||||
|
"macTo": "11:22:33:44:55:66"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"message": "Device copied from AA:BB:CC:DD:EE:FF to 11:22:33:44:55:66"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Missing `macFrom` or `macTo` → HTTP 400
|
||||||
|
* Unauthorized → HTTP 403
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Update a Single Column
|
||||||
|
|
||||||
|
* **POST** `/device/<mac>/update-column`
|
||||||
|
Update one specific column for a device.
|
||||||
|
|
||||||
|
**Request Body**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"columnName": "devName",
|
||||||
|
"columnValue": "Updated Device Name"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response** (success):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Device not found → HTTP 404
|
||||||
|
* Missing `columnName` or `columnValue` → HTTP 400
|
||||||
|
* Unauthorized → HTTP 403
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example `curl` Requests
|
||||||
|
|
||||||
|
**Get Device Details**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://<server_ip>:<GRAPHQL_PORT>/device/AA:BB:CC:DD:EE:FF" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Update Device Fields**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://<server_ip>:<GRAPHQL_PORT>/device/AA:BB:CC:DD:EE:FF" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"devName": "New Device Name"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Delete Device**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X DELETE "http://<server_ip>:<GRAPHQL_PORT>/device/AA:BB:CC:DD:EE:FF/delete" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Copy Device Data**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://<server_ip>:<GRAPHQL_PORT>/device/copy" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"macFrom":"AA:BB:CC:DD:EE:FF","macTo":"11:22:33:44:55:66"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Update Single Column**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://<server_ip>:<GRAPHQL_PORT>/device/AA:BB:CC:DD:EE:FF/update-column" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"columnName":"devName","columnValue":"Updated Device"}'
|
||||||
|
```
|
||||||
|
|
||||||
249
docs/API_DEVICES.md
Executable file
249
docs/API_DEVICES.md
Executable file
@@ -0,0 +1,249 @@
|
|||||||
|
# Devices Collection API Endpoints
|
||||||
|
|
||||||
|
The Devices Collection API provides operations to **retrieve, manage, import/export, and filter devices** in bulk. All endpoints require **authorization** via Bearer token.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Endpoints
|
||||||
|
|
||||||
|
### 1. Get All Devices
|
||||||
|
|
||||||
|
* **GET** `/devices`
|
||||||
|
Retrieves all devices from the database.
|
||||||
|
|
||||||
|
**Response** (success):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"devName": "Net - Huawei",
|
||||||
|
"devMAC": "AA:BB:CC:DD:EE:FF",
|
||||||
|
"devIP": "192.168.1.1",
|
||||||
|
"devType": "Router",
|
||||||
|
"devFavorite": 0,
|
||||||
|
"devStatus": "online"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Unauthorized → HTTP 403
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Delete Devices by MAC
|
||||||
|
|
||||||
|
* **DELETE** `/devices`
|
||||||
|
Deletes devices by MAC address. Supports exact matches or wildcard `*`.
|
||||||
|
|
||||||
|
**Request Body**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"macs": ["AA:BB:CC:DD:EE:FF", "11:22:33:*"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Behavior**:
|
||||||
|
|
||||||
|
* If `macs` is omitted or `null` → deletes **all devices**.
|
||||||
|
* Wildcards `*` match multiple devices.
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"deleted_count": 5
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Unauthorized → HTTP 403
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Delete Devices with Empty MACs
|
||||||
|
|
||||||
|
* **DELETE** `/devices/empty-macs`
|
||||||
|
Removes all devices where MAC address is null or empty.
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"deleted": 3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. Delete Unknown Devices
|
||||||
|
|
||||||
|
* **DELETE** `/devices/unknown`
|
||||||
|
Deletes devices with names marked as `(unknown)` or `(name not found)`.
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"deleted": 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Export Devices
|
||||||
|
|
||||||
|
* **GET** `/devices/export` or `/devices/export/<format>`
|
||||||
|
Exports all devices in **CSV** (default) or **JSON** format.
|
||||||
|
|
||||||
|
**Query Parameter / URL Parameter**:
|
||||||
|
|
||||||
|
* `format` (optional) → `csv` (default) or `json`
|
||||||
|
|
||||||
|
**CSV Response**:
|
||||||
|
|
||||||
|
* Returns as a downloadable CSV file: `Content-Disposition: attachment; filename=devices.csv`
|
||||||
|
|
||||||
|
**JSON Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{ "devName": "Net - Huawei", "devMAC": "AA:BB:CC:DD:EE:FF", ... },
|
||||||
|
...
|
||||||
|
],
|
||||||
|
"columns": ["devName", "devMAC", "devIP", "devType", "devFavorite", "devStatus"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Unsupported format → HTTP 400
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. Import Devices from CSV
|
||||||
|
|
||||||
|
* **POST** `/devices/import`
|
||||||
|
Imports devices from an uploaded CSV or base64-encoded CSV content.
|
||||||
|
|
||||||
|
**Request Body** (multipart file or JSON with `content` field):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"content": "<base64-encoded CSV content>"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"inserted": 25,
|
||||||
|
"skipped_lines": [3, 7]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Missing file or content → HTTP 400 / 404
|
||||||
|
* CSV malformed → HTTP 400
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 7. Get Device Totals
|
||||||
|
|
||||||
|
* **GET** `/devices/totals`
|
||||||
|
Returns counts of devices by various categories.
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
120, // Total devices
|
||||||
|
85, // Connected
|
||||||
|
5, // Favorites
|
||||||
|
10, // New
|
||||||
|
8, // Down
|
||||||
|
12 // Archived
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
*Order: `[all, connected, favorites, new, down, archived]`*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 8. Get Devices by Status
|
||||||
|
|
||||||
|
* **GET** `/devices/by-status?status=<status>`
|
||||||
|
Returns devices filtered by status.
|
||||||
|
|
||||||
|
**Query Parameter**:
|
||||||
|
|
||||||
|
* `status` → Supported values: `online`, `offline`, `down`, `archived`, `favorites`, `new`, `my`
|
||||||
|
* If omitted, returns **all devices**.
|
||||||
|
|
||||||
|
**Response** (success):
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{ "id": "AA:BB:CC:DD:EE:FF", "title": "Net - Huawei", "favorite": 0 },
|
||||||
|
{ "id": "11:22:33:44:55:66", "title": "★ USG Firewall", "favorite": 1 }
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
*If `devFavorite=1`, the title is prepended with a star `★`.*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example `curl` Requests
|
||||||
|
|
||||||
|
**Get All Devices**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X GET "http://<server_ip>:<GRAPHQL_PORT>/devices" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Delete Devices by MAC**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X DELETE "http://<server_ip>:<GRAPHQL_PORT>/devices" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"macs":["AA:BB:CC:DD:EE:FF","11:22:33:*"]}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Export Devices CSV**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X GET "http://<server_ip>:<GRAPHQL_PORT>/devices/export?format=csv" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Import Devices from CSV**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "http://<server_ip>:<GRAPHQL_PORT>/devices/import" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>" \
|
||||||
|
-F "file=@devices.csv"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Get Devices by Status**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X GET "http://<server_ip>:<GRAPHQL_PORT>/devices/by-status?status=online" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>"
|
||||||
|
```
|
||||||
|
|
||||||
169
docs/API_EVENTS.md
Executable file
169
docs/API_EVENTS.md
Executable file
@@ -0,0 +1,169 @@
|
|||||||
|
# Events API Endpoints
|
||||||
|
|
||||||
|
The Events API provides access to **device event logs**, allowing creation, retrieval, deletion, and summary of events over time.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Endpoints
|
||||||
|
|
||||||
|
### 1. Create Event
|
||||||
|
|
||||||
|
* **POST** `/events/create/<mac>`
|
||||||
|
Create an event for a device identified by its MAC address.
|
||||||
|
|
||||||
|
**Request Body** (JSON):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ip": "192.168.1.10",
|
||||||
|
"event_type": "Device Down",
|
||||||
|
"additional_info": "Optional info about the event",
|
||||||
|
"pending_alert": 1,
|
||||||
|
"event_time": "2025-08-24T12:00:00Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* **Parameters**:
|
||||||
|
|
||||||
|
* `ip` (string, optional): IP address of the device
|
||||||
|
* `event_type` (string, optional): Type of event (default `"Device Down"`)
|
||||||
|
* `additional_info` (string, optional): Extra information
|
||||||
|
* `pending_alert` (int, optional): 1 if alert email is pending (default 1)
|
||||||
|
* `event_time` (ISO datetime, optional): Event timestamp; defaults to current time
|
||||||
|
|
||||||
|
**Response** (JSON):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"message": "Event created for 00:11:22:33:44:55"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Get Events
|
||||||
|
|
||||||
|
* **GET** `/events`
|
||||||
|
Retrieve all events, optionally filtered by MAC address:
|
||||||
|
|
||||||
|
```
|
||||||
|
/events?mac=<mac>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"eve_MAC": "00:11:22:33:44:55",
|
||||||
|
"eve_IP": "192.168.1.10",
|
||||||
|
"eve_DateTime": "2025-08-24T12:00:00Z",
|
||||||
|
"eve_EventType": "Device Down",
|
||||||
|
"eve_AdditionalInfo": "",
|
||||||
|
"eve_PendingAlertEmail": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Delete Events
|
||||||
|
|
||||||
|
* **DELETE** `/events/<mac>` → Delete events for a specific MAC
|
||||||
|
* **DELETE** `/events` → Delete **all** events
|
||||||
|
* **DELETE** `/events/<days>` → Delete events older than N days
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"message": "Deleted events older than 30 days"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. Event Totals Over a Period
|
||||||
|
|
||||||
|
* **GET** `/sessions/totals?period=<period>`
|
||||||
|
Return event and session totals over a given period.
|
||||||
|
|
||||||
|
**Query Parameters**:
|
||||||
|
|
||||||
|
| Parameter | Description |
|
||||||
|
| --------- | -------------------------------------------------------------------------------- |
|
||||||
|
| `period` | Time period for totals, e.g., `"7 days"`, `"1 month"`, `"1 year"`, `"100 years"` |
|
||||||
|
|
||||||
|
**Sample Response** (JSON Array):
|
||||||
|
|
||||||
|
```json
|
||||||
|
[120, 85, 5, 10, 3, 7]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Meaning of Values**:
|
||||||
|
|
||||||
|
1. Total events in the period
|
||||||
|
2. Total sessions
|
||||||
|
3. Missing sessions
|
||||||
|
4. Voided events (`eve_EventType LIKE 'VOIDED%'`)
|
||||||
|
5. New device events (`eve_EventType LIKE 'New Device'`)
|
||||||
|
6. Device down events (`eve_EventType LIKE 'Device Down'`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
* All endpoints require **authorization** (Bearer token). Unauthorized requests return:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "error": "Forbidden" }
|
||||||
|
```
|
||||||
|
|
||||||
|
* Events are stored in the **Events table** with the following fields:
|
||||||
|
`eve_MAC`, `eve_IP`, `eve_DateTime`, `eve_EventType`, `eve_AdditionalInfo`, `eve_PendingAlertEmail`.
|
||||||
|
|
||||||
|
* Event creation automatically logs activity for debugging.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example `curl` Requests
|
||||||
|
|
||||||
|
**Create Event**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "http://<server_ip>:<GRAPHQL_PORT>/events/create/00:11:22:33:44:55" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{
|
||||||
|
"ip": "192.168.1.10",
|
||||||
|
"event_type": "Device Down",
|
||||||
|
"additional_info": "Power outage",
|
||||||
|
"pending_alert": 1
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Get Events for a Device**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl "http://<server_ip>:<GRAPHQL_PORT>/events?mac=00:11:22:33:44:55" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Delete Events Older Than 30 Days**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X DELETE "http://<server_ip>:<GRAPHQL_PORT>/events/30" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Get Event Totals for 7 Days**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl "http://<server_ip>:<GRAPHQL_PORT>/sessions/totals?period=7 days" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>"
|
||||||
|
```
|
||||||
114
docs/API_GRAPHQL.md
Executable file
114
docs/API_GRAPHQL.md
Executable file
@@ -0,0 +1,114 @@
|
|||||||
|
# GraphQL API Endpoint
|
||||||
|
|
||||||
|
GraphQL queries are read-optimized for speed. Data may be slightly out of date until the file system cache refreshes.
|
||||||
|
|
||||||
|
## Endpoints
|
||||||
|
|
||||||
|
* **GET** `/graphql`
|
||||||
|
Returns a simple status message (useful for browser or debugging).
|
||||||
|
|
||||||
|
* **POST** `/graphql`
|
||||||
|
Execute GraphQL queries against the `devicesSchema`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sample Query
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
query GetDevices($options: PageQueryOptionsInput) {
|
||||||
|
devices(options: $options) {
|
||||||
|
devices {
|
||||||
|
rowid
|
||||||
|
devMac
|
||||||
|
devName
|
||||||
|
devOwner
|
||||||
|
devType
|
||||||
|
devVendor
|
||||||
|
devLastConnection
|
||||||
|
devStatus
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
See also: [Debugging GraphQL issues](./DEBUG_GRAPHQL.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `curl` Example
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl 'http://host:GRAPHQL_PORT/graphql' \
|
||||||
|
-X POST \
|
||||||
|
-H 'Authorization: Bearer API_TOKEN' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
--data '{
|
||||||
|
"query": "query GetDevices($options: PageQueryOptionsInput) { devices(options: $options) { devices { rowid devMac devName devOwner devType devVendor devLastConnection devStatus } count } }",
|
||||||
|
"variables": {
|
||||||
|
"options": {
|
||||||
|
"page": 1,
|
||||||
|
"limit": 10,
|
||||||
|
"sort": [{ "field": "devName", "order": "asc" }],
|
||||||
|
"search": "",
|
||||||
|
"status": "connected"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Query Parameters
|
||||||
|
|
||||||
|
| Parameter | Description |
|
||||||
|
| --------- | ------------------------------------------------------------------------------------------------------- |
|
||||||
|
| `page` | Page number of results to fetch. |
|
||||||
|
| `limit` | Number of results per page. |
|
||||||
|
| `sort` | Sorting options (`field` = field name, `order` = `asc` or `desc`). |
|
||||||
|
| `search` | Term to filter devices. |
|
||||||
|
| `status` | Filter devices by status: `my_devices`, `connected`, `favorites`, `new`, `down`, `archived`, `offline`. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes on `curl`
|
||||||
|
|
||||||
|
* `-X POST` specifies a POST request.
|
||||||
|
* `-H 'Content-Type: application/json'` sets JSON content type.
|
||||||
|
* `--data` provides the request payload (GraphQL query + variables).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sample Response
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"devices": {
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"rowid": 1,
|
||||||
|
"devMac": "00:11:22:33:44:55",
|
||||||
|
"devName": "Device 1",
|
||||||
|
"devOwner": "Owner 1",
|
||||||
|
"devType": "Type 1",
|
||||||
|
"devVendor": "Vendor 1",
|
||||||
|
"devLastConnection": "2025-01-01T00:00:00Z",
|
||||||
|
"devStatus": "connected"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rowid": 2,
|
||||||
|
"devMac": "66:77:88:99:AA:BB",
|
||||||
|
"devName": "Device 2",
|
||||||
|
"devOwner": "Owner 2",
|
||||||
|
"devType": "Type 2",
|
||||||
|
"devVendor": "Vendor 2",
|
||||||
|
"devLastConnection": "2025-01-02T00:00:00Z",
|
||||||
|
"devStatus": "connected"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"count": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
103
docs/API_METRICS.md
Executable file
103
docs/API_METRICS.md
Executable file
@@ -0,0 +1,103 @@
|
|||||||
|
# Metrics API Endpoint
|
||||||
|
|
||||||
|
The `/metrics` endpoint exposes **Prometheus-compatible metrics** for NetAlertX, including aggregate device counts and per-device status.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Endpoint Details
|
||||||
|
|
||||||
|
* **GET** `/metrics` → Returns metrics in plain text.
|
||||||
|
* **Host**: NetAlertX server
|
||||||
|
* **Port**: As configured in `GRAPHQL_PORT` (default: `20212`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
|
||||||
|
```text
|
||||||
|
netalertx_connected_devices 31
|
||||||
|
netalertx_offline_devices 54
|
||||||
|
netalertx_down_devices 0
|
||||||
|
netalertx_new_devices 0
|
||||||
|
netalertx_archived_devices 31
|
||||||
|
netalertx_favorite_devices 2
|
||||||
|
netalertx_my_devices 54
|
||||||
|
|
||||||
|
netalertx_device_status{device="Net - Huawei", mac="Internet", ip="1111.111.111.111", vendor="None", first_connection="2021-01-01 00:00:00", last_connection="2025-08-04 17:57:00", dev_type="Router", device_status="Online"} 1
|
||||||
|
netalertx_device_status{device="Net - USG", mac="74:ac:74:ac:74:ac", ip="192.168.1.1", vendor="Ubiquiti Networks Inc.", first_connection="2022-02-12 22:05:00", last_connection="2025-06-07 08:16:49", dev_type="Firewall", device_status="Archived"} 1
|
||||||
|
netalertx_device_status{device="Raspberry Pi 4 LAN", mac="74:ac:74:ac:74:74", ip="192.168.1.9", vendor="Raspberry Pi Trading Ltd", first_connection="2022-02-12 22:05:00", last_connection="2025-08-04 17:57:00", dev_type="Singleboard Computer (SBC)", device_status="Online"} 1
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Metrics Overview
|
||||||
|
|
||||||
|
### 1. Aggregate Device Counts
|
||||||
|
|
||||||
|
| Metric | Description |
|
||||||
|
| ----------------------------- | ---------------------------------------- |
|
||||||
|
| `netalertx_connected_devices` | Devices currently connected |
|
||||||
|
| `netalertx_offline_devices` | Devices currently offline |
|
||||||
|
| `netalertx_down_devices` | Down/unreachable devices |
|
||||||
|
| `netalertx_new_devices` | Recently detected devices |
|
||||||
|
| `netalertx_archived_devices` | Archived devices |
|
||||||
|
| `netalertx_favorite_devices` | User-marked favorites |
|
||||||
|
| `netalertx_my_devices` | Devices associated with the current user |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Per-Device Status
|
||||||
|
|
||||||
|
Metric: `netalertx_device_status`
|
||||||
|
Each device has labels:
|
||||||
|
|
||||||
|
* `device`: friendly name
|
||||||
|
* `mac`: MAC address (or placeholder)
|
||||||
|
* `ip`: last recorded IP
|
||||||
|
* `vendor`: manufacturer or "None"
|
||||||
|
* `first_connection`: timestamp of first detection
|
||||||
|
* `last_connection`: most recent contact
|
||||||
|
* `dev_type`: device type/category
|
||||||
|
* `device_status`: current status (`Online`, `Offline`, `Archived`, `Down`, …)
|
||||||
|
|
||||||
|
Metric value is always `1` (presence indicator).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Querying with `curl`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl 'http://<server_ip>:<GRAPHQL_PORT>/metrics' \
|
||||||
|
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||||
|
-H 'Accept: text/plain'
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace placeholders:
|
||||||
|
|
||||||
|
* `<server_ip>` – NetAlertX host IP/hostname
|
||||||
|
* `<GRAPHQL_PORT>` – configured port (default `20212`)
|
||||||
|
* `<API_TOKEN>` – your API token
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prometheus Scraping Configuration
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: 'netalertx'
|
||||||
|
metrics_path: /metrics
|
||||||
|
scheme: http
|
||||||
|
scrape_interval: 60s
|
||||||
|
static_configs:
|
||||||
|
- targets: ['<server_ip>:<GRAPHQL_PORT>']
|
||||||
|
authorization:
|
||||||
|
type: Bearer
|
||||||
|
credentials: <API_TOKEN>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Grafana Dashboard Template
|
||||||
|
|
||||||
|
Sample template JSON: [Download](./samples/API/Grafana_Dashboard.json)
|
||||||
243
docs/API_NETTOOLS.md
Executable file
243
docs/API_NETTOOLS.md
Executable file
@@ -0,0 +1,243 @@
|
|||||||
|
# Net Tools API Endpoints
|
||||||
|
|
||||||
|
The Net Tools API provides **network diagnostic utilities**, including Wake-on-LAN, traceroute, speed testing, DNS resolution, nmap scanning, and internet connection information.
|
||||||
|
|
||||||
|
All endpoints require **authorization** via Bearer token.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Endpoints
|
||||||
|
|
||||||
|
### 1. Wake-on-LAN
|
||||||
|
|
||||||
|
* **POST** `/nettools/wakeonlan`
|
||||||
|
Sends a Wake-on-LAN packet to wake a device.
|
||||||
|
|
||||||
|
**Request Body** (JSON):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"devMac": "AA:BB:CC:DD:EE:FF"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response** (success):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"message": "WOL packet sent",
|
||||||
|
"output": "Sent magic packet to AA:BB:CC:DD:EE:FF"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Invalid MAC address → HTTP 400
|
||||||
|
* Command failure → HTTP 500
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Traceroute
|
||||||
|
|
||||||
|
* **POST** `/nettools/traceroute`
|
||||||
|
Performs a traceroute to a specified IP address.
|
||||||
|
|
||||||
|
**Request Body**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"devLastIP": "192.168.1.1"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response** (success):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"output": "traceroute output as string"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Invalid IP → HTTP 400
|
||||||
|
* Traceroute command failure → HTTP 500
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Speedtest
|
||||||
|
|
||||||
|
* **GET** `/nettools/speedtest`
|
||||||
|
Runs an internet speed test using `speedtest-cli`.
|
||||||
|
|
||||||
|
**Response** (success):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"output": [
|
||||||
|
"Ping: 15 ms",
|
||||||
|
"Download: 120.5 Mbit/s",
|
||||||
|
"Upload: 22.4 Mbit/s"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Command failure → HTTP 500
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. DNS Lookup (nslookup)
|
||||||
|
|
||||||
|
* **POST** `/nettools/nslookup`
|
||||||
|
Resolves an IP address or hostname using `nslookup`.
|
||||||
|
|
||||||
|
**Request Body**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"devLastIP": "8.8.8.8"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response** (success):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"output": [
|
||||||
|
"Server: 8.8.8.8",
|
||||||
|
"Address: 8.8.8.8#53",
|
||||||
|
"Name: google-public-dns-a.google.com"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Missing or invalid `devLastIP` → HTTP 400
|
||||||
|
* Command failure → HTTP 500
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Nmap Scan
|
||||||
|
|
||||||
|
* **POST** `/nettools/nmap`
|
||||||
|
Runs an nmap scan on a target IP address or range.
|
||||||
|
|
||||||
|
**Request Body**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scan": "192.168.1.0/24",
|
||||||
|
"mode": "fast"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Supported Modes**:
|
||||||
|
|
||||||
|
| Mode | nmap Arguments |
|
||||||
|
| --------------- | -------------- |
|
||||||
|
| `fast` | `-F` |
|
||||||
|
| `normal` | default |
|
||||||
|
| `detail` | `-A` |
|
||||||
|
| `skipdiscovery` | `-Pn` |
|
||||||
|
|
||||||
|
**Response** (success):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"mode": "fast",
|
||||||
|
"ip": "192.168.1.0/24",
|
||||||
|
"output": [
|
||||||
|
"Starting Nmap 7.91",
|
||||||
|
"Host 192.168.1.1 is up",
|
||||||
|
"... scan results ..."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Invalid IP → HTTP 400
|
||||||
|
* Invalid mode → HTTP 400
|
||||||
|
* Command failure → HTTP 500
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. Internet Connection Info
|
||||||
|
|
||||||
|
* **GET** `/nettools/internetinfo`
|
||||||
|
Fetches public internet connection information using `ipinfo.io`.
|
||||||
|
|
||||||
|
**Response** (success):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"output": "IP: 203.0.113.5 City: Sydney Country: AU Org: Example ISP"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Failed request or empty response → HTTP 500
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example `curl` Requests
|
||||||
|
|
||||||
|
**Wake-on-LAN**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "http://<server_ip>:<GRAPHQL_PORT>/nettools/wakeonlan" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"devMac":"AA:BB:CC:DD:EE:FF"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Traceroute**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "http://<server_ip>:<GRAPHQL_PORT>/nettools/traceroute" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"devLastIP":"192.168.1.1"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Speedtest**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl "http://<server_ip>:<GRAPHQL_PORT>/nettools/speedtest" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Nslookup**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "http://<server_ip>:<GRAPHQL_PORT>/nettools/nslookup" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"devLastIP":"8.8.8.8"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Nmap Scan**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "http://<server_ip>:<GRAPHQL_PORT>/nettools/nmap" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"scan":"192.168.1.0/24","mode":"fast"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Internet Info**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl "http://<server_ip>:<GRAPHQL_PORT>/nettools/internetinfo" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>"
|
||||||
|
```
|
||||||
370
docs/API_OLD.md
Executable file
370
docs/API_OLD.md
Executable file
@@ -0,0 +1,370 @@
|
|||||||
|
# API endpoints
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Some of these endpoints will be deprecated soon. Please refere to the new [API](API.md) endpoints docs for details on the new API layer.
|
||||||
|
|
||||||
|
NetAlertX comes with a couple of API endpoints. All requests need to be authorized (executed in a logged in browser session) or you have to pass the value of the `API_TOKEN` settings as authorization bearer, for example:
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
curl 'http://host:GRAPHQL_PORT/graphql' \
|
||||||
|
-X POST \
|
||||||
|
-H 'Authorization: Bearer API_TOKEN' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
--data '{
|
||||||
|
"query": "query GetDevices($options: PageQueryOptionsInput) { devices(options: $options) { devices { rowid devMac devName devOwner devType devVendor devLastConnection devStatus } count } }",
|
||||||
|
"variables": {
|
||||||
|
"options": {
|
||||||
|
"page": 1,
|
||||||
|
"limit": 10,
|
||||||
|
"sort": [{ "field": "devName", "order": "asc" }],
|
||||||
|
"search": "",
|
||||||
|
"status": "connected"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Endpoint: GraphQL
|
||||||
|
|
||||||
|
- Endpoint URL: `php/server/query_graphql.php`
|
||||||
|
- Host: `same as front end (web ui)`
|
||||||
|
- Port: `20212` or as defined by the `GRAPHQL_PORT` setting
|
||||||
|
|
||||||
|
### Example Query to Fetch Devices
|
||||||
|
|
||||||
|
First, let's define the GraphQL query to fetch devices with pagination and sorting options.
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
query GetDevices($options: PageQueryOptionsInput) {
|
||||||
|
devices(options: $options) {
|
||||||
|
devices {
|
||||||
|
rowid
|
||||||
|
devMac
|
||||||
|
devName
|
||||||
|
devOwner
|
||||||
|
devType
|
||||||
|
devVendor
|
||||||
|
devLastConnection
|
||||||
|
devStatus
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
See also: [Debugging GraphQL issues](./DEBUG_GRAPHQL.md)
|
||||||
|
|
||||||
|
### `curl` Command
|
||||||
|
|
||||||
|
You can use the following `curl` command to execute the query.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl 'http://host:GRAPHQL_PORT/graphql' -X POST -H 'Authorization: Bearer API_TOKEN' -H 'Content-Type: application/json' --data '{
|
||||||
|
"query": "query GetDevices($options: PageQueryOptionsInput) { devices(options: $options) { devices { rowid devMac devName devOwner devType devVendor devLastConnection devStatus } count } }",
|
||||||
|
"variables": {
|
||||||
|
"options": {
|
||||||
|
"page": 1,
|
||||||
|
"limit": 10,
|
||||||
|
"sort": [{ "field": "devName", "order": "asc" }],
|
||||||
|
"search": "",
|
||||||
|
"status": "connected"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Explanation:
|
||||||
|
|
||||||
|
1. **GraphQL Query**:
|
||||||
|
- The `query` parameter contains the GraphQL query as a string.
|
||||||
|
- The `variables` parameter contains the input variables for the query.
|
||||||
|
|
||||||
|
2. **Query Variables**:
|
||||||
|
- `page`: Specifies the page number of results to fetch.
|
||||||
|
- `limit`: Specifies the number of results per page.
|
||||||
|
- `sort`: Specifies the sorting options, with `field` being the field to sort by and `order` being the sort order (`asc` for ascending or `desc` for descending).
|
||||||
|
- `search`: A search term to filter the devices.
|
||||||
|
- `status`: The status filter to apply (valid values are `my_devices` (determined by the `UI_MY_DEVICES` setting), `connected`, `favorites`, `new`, `down`, `archived`, `offline`).
|
||||||
|
|
||||||
|
3. **`curl` Command**:
|
||||||
|
- The `-X POST` option specifies that we are making a POST request.
|
||||||
|
- The `-H "Content-Type: application/json"` option sets the content type of the request to JSON.
|
||||||
|
- The `-d` option provides the request payload, which includes the GraphQL query and variables.
|
||||||
|
|
||||||
|
### Sample Response
|
||||||
|
|
||||||
|
The response will be in JSON format, similar to the following:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"devices": {
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"rowid": 1,
|
||||||
|
"devMac": "00:11:22:33:44:55",
|
||||||
|
"devName": "Device 1",
|
||||||
|
"devOwner": "Owner 1",
|
||||||
|
"devType": "Type 1",
|
||||||
|
"devVendor": "Vendor 1",
|
||||||
|
"devLastConnection": "2025-01-01T00:00:00Z",
|
||||||
|
"devStatus": "connected"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rowid": 2,
|
||||||
|
"devMac": "66:77:88:99:AA:BB",
|
||||||
|
"devName": "Device 2",
|
||||||
|
"devOwner": "Owner 2",
|
||||||
|
"devType": "Type 2",
|
||||||
|
"devVendor": "Vendor 2",
|
||||||
|
"devLastConnection": "2025-01-02T00:00:00Z",
|
||||||
|
"devStatus": "connected"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"count": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Endpoint: JSON files
|
||||||
|
|
||||||
|
This API endpoint retrieves static files, that are periodically updated.
|
||||||
|
|
||||||
|
- Endpoint URL: `php/server/query_json.php?file=<file name>`
|
||||||
|
- Host: `same as front end (web ui)`
|
||||||
|
- Port: `20211` or as defined by the $PORT docker environment variable (same as the port for the web ui)
|
||||||
|
|
||||||
|
### When are the endpoints updated
|
||||||
|
|
||||||
|
The endpoints are updated when objects in the API endpoints are changed.
|
||||||
|
|
||||||
|
### Location of the endpoints
|
||||||
|
|
||||||
|
In the container, these files are located under the `/app/api/` folder. You can access them via the `/php/server/query_json.php?file=user_notifications.json` endpoint.
|
||||||
|
|
||||||
|
### Available endpoints
|
||||||
|
|
||||||
|
You can access the following files:
|
||||||
|
|
||||||
|
| File name | Description |
|
||||||
|
|----------------------|----------------------|
|
||||||
|
| `notification_json_final.json` | The json version of the last notification (e.g. used for webhooks - [sample JSON](https://github.com/jokob-sk/NetAlertX/blob/main/front/report_templates/webhook_json_sample.json)). |
|
||||||
|
| `table_devices.json` | All of the available Devices detected by the app. |
|
||||||
|
| `table_plugins_events.json` | The list of the unprocessed (pending) notification events (plugins_events DB table). |
|
||||||
|
| `table_plugins_history.json` | The list of notification events history. |
|
||||||
|
| `table_plugins_objects.json` | The content of the plugins_objects table. Find more info on the [Plugin system here](https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md)|
|
||||||
|
| `language_strings.json` | The content of the language_strings table, which in turn is loaded from the plugins `config.json` definitions. |
|
||||||
|
| `table_custom_endpoint.json` | A custom endpoint generated by the SQL query specified by the `API_CUSTOM_SQL` setting. |
|
||||||
|
| `table_settings.json` | The content of the settings table. |
|
||||||
|
| `app_state.json` | Contains the current application state. |
|
||||||
|
|
||||||
|
|
||||||
|
### JSON Data format
|
||||||
|
|
||||||
|
The endpoints starting with the `table_` prefix contain most, if not all, data contained in the corresponding database table. The common format for those is:
|
||||||
|
|
||||||
|
```JSON
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"db_column_name": "data",
|
||||||
|
"db_column_name2": "data2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"db_column_name": "data3",
|
||||||
|
"db_column_name2": "data4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Example JSON of the `table_devices.json` endpoint with two Devices (database rows):
|
||||||
|
|
||||||
|
```JSON
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"devMac": "Internet",
|
||||||
|
"devName": "Net - Huawei",
|
||||||
|
"devType": "Router",
|
||||||
|
"devVendor": null,
|
||||||
|
"devGroup": "Always on",
|
||||||
|
"devFirstConnection": "2021-01-01 00:00:00",
|
||||||
|
"devLastConnection": "2021-01-28 22:22:11",
|
||||||
|
"devLastIP": "192.168.1.24",
|
||||||
|
"devStaticIP": 0,
|
||||||
|
"devPresentLastScan": 1,
|
||||||
|
"devLastNotification": "2023-01-28 22:22:28.998715",
|
||||||
|
"devIsNew": 0,
|
||||||
|
"devParentMAC": "",
|
||||||
|
"devParentPort": "",
|
||||||
|
"devIcon": "globe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"devMac": "a4:8f:ff:aa:ba:1f",
|
||||||
|
"devName": "Net - USG",
|
||||||
|
"devType": "Firewall",
|
||||||
|
"devVendor": "Ubiquiti Inc",
|
||||||
|
"devGroup": "",
|
||||||
|
"devFirstConnection": "2021-02-12 22:05:00",
|
||||||
|
"devLastConnection": "2021-07-17 15:40:00",
|
||||||
|
"devLastIP": "192.168.1.1",
|
||||||
|
"devStaticIP": 1,
|
||||||
|
"devPresentLastScan": 1,
|
||||||
|
"devLastNotification": "2021-07-17 15:40:10.667717",
|
||||||
|
"devIsNew": 0,
|
||||||
|
"devParentMAC": "Internet",
|
||||||
|
"devParentPort": 1,
|
||||||
|
"devIcon": "shield-halved"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Endpoint: Prometheus Exporter
|
||||||
|
|
||||||
|
* **Endpoint URL**: `/metrics`
|
||||||
|
* **Host**: (where NetAlertX exporter is running)
|
||||||
|
* **Port**: as configured in the `GRAPHQL_PORT` setting (`20212` by default)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example Output of the `/metrics` Endpoint
|
||||||
|
|
||||||
|
Below is a representative snippet of the metrics you may find when querying the `/metrics` endpoint for `netalertx`. It includes both aggregate counters and `device_status` labels per device.
|
||||||
|
|
||||||
|
```
|
||||||
|
netalertx_connected_devices 31
|
||||||
|
netalertx_offline_devices 54
|
||||||
|
netalertx_down_devices 0
|
||||||
|
netalertx_new_devices 0
|
||||||
|
netalertx_archived_devices 31
|
||||||
|
netalertx_favorite_devices 2
|
||||||
|
netalertx_my_devices 54
|
||||||
|
|
||||||
|
netalertx_device_status{device="Net - Huawei", mac="Internet", ip="1111.111.111.111", vendor="None", first_connection="2021-01-01 00:00:00", last_connection="2025-08-04 17:57:00", dev_type="Router", device_status="Online"} 1
|
||||||
|
netalertx_device_status{device="Net - USG", mac="74:ac:74:ac:74:ac", ip="192.168.1.1", vendor="Ubiquiti Networks Inc.", first_connection="2022-02-12 22:05:00", last_connection="2025-06-07 08:16:49", dev_type="Firewall", device_status="Archived"} 1
|
||||||
|
netalertx_device_status{device="Raspberry Pi 4 LAN", mac="74:ac:74:ac:74:74", ip="192.168.1.9", vendor="Raspberry Pi Trading Ltd", first_connection="2022-02-12 22:05:00", last_connection="2025-08-04 17:57:00", dev_type="Singleboard Computer (SBC)", device_status="Online"} 1
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Metrics Explanation
|
||||||
|
|
||||||
|
#### 1. Aggregate Device Counts
|
||||||
|
|
||||||
|
Metric names prefixed with `netalertx_` provide aggregated counts by device status:
|
||||||
|
|
||||||
|
* `netalertx_connected_devices`: number of devices currently connected
|
||||||
|
* `netalertx_offline_devices`: devices currently offline
|
||||||
|
* `netalertx_down_devices`: down/unreachable devices
|
||||||
|
* `netalertx_new_devices`: devices recently detected
|
||||||
|
* `netalertx_archived_devices`: archived devices
|
||||||
|
* `netalertx_favorite_devices`: user-marked favorite devices
|
||||||
|
* `netalertx_my_devices`: devices associated with the current user context
|
||||||
|
|
||||||
|
These numeric values give a high-level overview of device distribution.
|
||||||
|
|
||||||
|
#### 2. Per‑Device Status with Labels
|
||||||
|
|
||||||
|
Each individual device is represented by a `netalertx_device_status` metric, with descriptive labels:
|
||||||
|
|
||||||
|
* `device`: friendly name of the device
|
||||||
|
* `mac`: MAC address (or placeholder)
|
||||||
|
* `ip`: last recorded IP address
|
||||||
|
* `vendor`: manufacturer or "None" if unknown
|
||||||
|
* `first_connection`: timestamp when the device was first observed
|
||||||
|
* `last_connection`: most recent contact timestamp
|
||||||
|
* `dev_type`: device category or type
|
||||||
|
* `device_status`: current status (Online / Offline / Archived / Down / ...)
|
||||||
|
|
||||||
|
The metric value is always `1` (indicating presence or active state) and the combination of labels identifies the device.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### How to Query with `curl`
|
||||||
|
|
||||||
|
To fetch the metrics from the NetAlertX exporter:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl 'http://<server_ip>:<GRAPHQL_PORT>/metrics' \
|
||||||
|
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||||
|
-H 'Accept: text/plain'
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace:
|
||||||
|
|
||||||
|
* `<server_ip>`: IP or hostname of the NetAlertX server
|
||||||
|
* `<GRAPHQL_PORT>`: port specified in your `GRAPHQL_PORT` setting (default: `20212`)
|
||||||
|
* `<API_TOKEN>` your Bearer token from the `API_TOKEN` setting
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
* **Endpoint**: `/metrics` provides both summary counters and per-device status entries.
|
||||||
|
* **Aggregate metrics** help monitor overall device states.
|
||||||
|
* **Detailed metrics** expose each device’s metadata via labels.
|
||||||
|
* **Use case**: feed into Prometheus for scraping, monitoring, alerting, or charting dashboard views.
|
||||||
|
|
||||||
|
### Prometheus Scraping Configuration
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: 'netalertx'
|
||||||
|
metrics_path: /metrics
|
||||||
|
scheme: http
|
||||||
|
scrape_interval: 60s
|
||||||
|
static_configs:
|
||||||
|
- targets: ['<server_ip>:<GRAPHQL_PORT>']
|
||||||
|
authorization:
|
||||||
|
type: Bearer
|
||||||
|
credentials: <API_TOKEN>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Grafana template
|
||||||
|
|
||||||
|
Grafana template sample: [Download json](./samples/API/Grafana_Dashboard.json)
|
||||||
|
|
||||||
|
## API Endpoint: /log files
|
||||||
|
|
||||||
|
This API endpoint retrieves files from the `/app/log` folder.
|
||||||
|
|
||||||
|
- Endpoint URL: `php/server/query_logs.php?file=<file name>`
|
||||||
|
- Host: `same as front end (web ui)`
|
||||||
|
- Port: `20211` or as defined by the $PORT docker environment variable (same as the port for the web ui)
|
||||||
|
|
||||||
|
| File | Description |
|
||||||
|
|--------------------------|---------------------------------------------------------------|
|
||||||
|
| `IP_changes.log` | Logs of IP address changes |
|
||||||
|
| `app.log` | Main application log |
|
||||||
|
| `app.php_errors.log` | PHP error log |
|
||||||
|
| `app_front.log` | Frontend application log |
|
||||||
|
| `app_nmap.log` | Logs of Nmap scan results |
|
||||||
|
| `db_is_locked.log` | Logs when the database is locked |
|
||||||
|
| `execution_queue.log` | Logs of execution queue activities |
|
||||||
|
| `plugins/` | Directory for temporary plugin-related files (not accessible) |
|
||||||
|
| `report_output.html` | HTML report output |
|
||||||
|
| `report_output.json` | JSON format report output |
|
||||||
|
| `report_output.txt` | Text format report output |
|
||||||
|
| `stderr.log` | Logs of standard error output |
|
||||||
|
| `stdout.log` | Logs of standard output |
|
||||||
|
|
||||||
|
|
||||||
|
## API Endpoint: /config files
|
||||||
|
|
||||||
|
To retrieve files from the `/app/config` folder.
|
||||||
|
|
||||||
|
- Endpoint URL: `php/server/query_config.php?file=<file name>`
|
||||||
|
- Host: `same as front end (web ui)`
|
||||||
|
- Port: `20211` or as defined by the $PORT docker environment variable (same as the port for the web ui)
|
||||||
|
|
||||||
|
| File | Description |
|
||||||
|
|--------------------------|--------------------------------------------------|
|
||||||
|
| `devices.csv` | Devices csv file |
|
||||||
|
| `app.conf` | Application config file |
|
||||||
|
|
||||||
59
docs/API_ONLINEHISTORY.md
Executable file
59
docs/API_ONLINEHISTORY.md
Executable file
@@ -0,0 +1,59 @@
|
|||||||
|
# Online History API Endpoints
|
||||||
|
|
||||||
|
Manage the **online history records** of devices. Currently, the API supports deletion of all history entries. All endpoints require **authorization**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Delete Online History
|
||||||
|
|
||||||
|
* **DELETE** `/history`
|
||||||
|
Remove **all records** from the online history table (`Online_History`). This operation **cannot be undone**.
|
||||||
|
|
||||||
|
**Response** (success):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"message": "Deleted online history"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
|
||||||
|
* Unauthorized → HTTP 403
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example `curl` Request
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X DELETE "http://<server_ip>:<GRAPHQL_PORT>/history" \
|
||||||
|
-H "Authorization: Bearer <API_TOKEN>"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Implementation Details
|
||||||
|
|
||||||
|
The endpoint calls the helper function `delete_online_history()`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def delete_online_history():
|
||||||
|
"""Delete all online history activity"""
|
||||||
|
|
||||||
|
conn = get_temp_db_connection()
|
||||||
|
cur = conn.cursor()
|
||||||
|
|
||||||
|
# Remove all entries from Online_History table
|
||||||
|
cur.execute("DELETE FROM Online_History")
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return jsonify({"success": True, "message": "Deleted online history"})
|
||||||
|
```
|
||||||
|
|
||||||
|
* Opens a temporary database connection for the request.
|
||||||
|
* Executes a **full table delete** (`DELETE FROM Online_History`).
|
||||||
|
* Commits the transaction and closes the connection.
|
||||||
|
* Returns a JSON confirmation message.
|
||||||
18
docs/API_SESSIONS.md
Executable file
18
docs/API_SESSIONS.md
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
# SEssions API Endpoints
|
||||||
|
|
||||||
|
Track device connection sessions.
|
||||||
|
|
||||||
|
* **POST** `/sessions/create` → Create a new session
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "mac": "AA:BB:CC:DD:EE:FF", "ip": "192.168.1.10", "start_time": "2025-08-01T10:00:00" }
|
||||||
|
```
|
||||||
|
* **DELETE** `/sessions/delete` → Delete session by MAC
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "mac": "AA:BB:CC:DD:EE:FF" }
|
||||||
|
```
|
||||||
|
* **GET** `/sessions/list?mac=<mac>&start_date=2025-08-01&end_date=2025-08-21` → List sessions
|
||||||
|
* **GET** `/sessions/calendar?start=2025-08-01&end=2025-08-21` → Calendar view of sessions
|
||||||
|
* **GET** `/sessions/<mac>?period=1 day` → Sessions for a device
|
||||||
|
* **GET** `/sessions/session-events?type=all&period=7 days` → Session events summary
|
||||||
87
docs/API_SYNC.md
Executable file
87
docs/API_SYNC.md
Executable file
@@ -0,0 +1,87 @@
|
|||||||
|
# Sync API Endpoint
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
The `/sync` endpoint is used by the **SYNC plugin** to synchronize data between multiple NetAlertX instances (e.g., from a node to a hub). It supports both **GET** and **POST** requests.
|
||||||
|
|
||||||
|
#### 9.1 GET `/sync`
|
||||||
|
|
||||||
|
Fetches data from a node to the hub. The data is returned as a **base64-encoded JSON file**.
|
||||||
|
|
||||||
|
**Example Request:**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl 'http://<server>:<GRAPHQL_PORT>/sync' \
|
||||||
|
-H 'Authorization: Bearer <API_TOKEN>'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response Example:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"node_name": "NODE-01",
|
||||||
|
"status": 200,
|
||||||
|
"message": "OK",
|
||||||
|
"data_base64": "eyJkZXZpY2VzIjogW3siZGV2TWFjIjogIjAwOjExOjIyOjMzOjQ0OjU1IiwiZGV2TmFtZSI6ICJEZXZpY2UgMSJ9XSwgImNvdW50Ijog1fQ==",
|
||||||
|
"timestamp": "2025-08-24T10:15:00+10:00"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
* `data_base64` contains the full JSON data encoded in Base64.
|
||||||
|
* `node_name` corresponds to the `SYNC_node_name` setting on the node.
|
||||||
|
* Errors (e.g., missing file) return HTTP 500 with an error message.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 9.2 POST `/sync`
|
||||||
|
|
||||||
|
Used by a node to send data to the hub. The hub receives **form-encoded data** and stores it for processing.
|
||||||
|
|
||||||
|
**Required Form Fields:**
|
||||||
|
|
||||||
|
| Field | Description |
|
||||||
|
| ----------- | ----------------------------------- |
|
||||||
|
| `data` | The payload (plain text or JSON) |
|
||||||
|
| `node_name` | Name of the node sending the data |
|
||||||
|
| `plugin` | The plugin name generating the data |
|
||||||
|
|
||||||
|
**Example Request (cURL):**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST 'http://<server>:<GRAPHQL_PORT>/sync' \
|
||||||
|
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||||
|
-F 'data=<payload here>' \
|
||||||
|
-F 'node_name=NODE-01' \
|
||||||
|
-F 'plugin=SYNC'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response Example:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "Data received and stored successfully"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Storage Details:**
|
||||||
|
|
||||||
|
* Data is stored under `INSTALL_PATH/log/plugins` with filenames following the pattern:
|
||||||
|
|
||||||
|
```
|
||||||
|
last_result.<plugin>.encoded.<node_name>.<sequence>.log
|
||||||
|
```
|
||||||
|
|
||||||
|
* Both encoded and decoded files are tracked, and new submissions increment the sequence number.
|
||||||
|
* If storing fails, the API returns HTTP 500 with an error message.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 9.3 Notes and Best Practices
|
||||||
|
|
||||||
|
* **Authorization Required** – Both GET and POST require a valid API token.
|
||||||
|
* **Data Integrity** – Ensure that `node_name` and `plugin` are consistent to avoid overwriting files.
|
||||||
|
* **Monitoring** – Notifications are generated whenever data is sent or received (`write_notification`), which can be used for alerting or auditing.
|
||||||
|
* **Use Case** – Typically used in multi-node deployments to consolidate device and event data on a central hub.
|
||||||
|
|
||||||
12
docs/API_TESTS.md
Executable file
12
docs/API_TESTS.md
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
### Unit Tests
|
||||||
|
|
||||||
|
>[!WARNING]
|
||||||
|
> Please note these test modify data in the database.
|
||||||
|
|
||||||
|
1. See the `/test` directory for available test cases. These are not exhaustive but cover the main API endpoints.
|
||||||
|
2. To run a test case, SSH into the container:
|
||||||
|
`sudo docker exec -it netalertx /bin/bash`
|
||||||
|
3. Inside the container, install pytest (if not already installed):
|
||||||
|
`pip install pytest`
|
||||||
|
4. Run a specific test case:
|
||||||
|
`pytest /app/test/TESTFILE.py`
|
||||||
15
mkdocs.yml
15
mkdocs.yml
@@ -77,9 +77,22 @@ nav:
|
|||||||
- Settings: SETTINGS_SYSTEM.md
|
- Settings: SETTINGS_SYSTEM.md
|
||||||
- Versions: VERSIONS.md
|
- Versions: VERSIONS.md
|
||||||
- Icon and Type guessing: DEVICE_HEURISTICS.md
|
- Icon and Type guessing: DEVICE_HEURISTICS.md
|
||||||
|
- API:
|
||||||
|
- Overview: API.md
|
||||||
|
- OLD API Overview: API_OLD.md
|
||||||
|
- Devices Collection: API_DEVICES.md
|
||||||
|
- Device: API_DEVICE.md
|
||||||
|
- Sessions: API_SESSIONS.md
|
||||||
|
- Events: API_EVENTS.md
|
||||||
|
- Metrics: API_METRICS.md
|
||||||
|
- Net Tools: API_NETTOOLS.md
|
||||||
|
- Online History: API_ONLINEHISTORY.md
|
||||||
|
- Sync: API_SYNC.md
|
||||||
|
- GraphQL: API_GRAPHQL.md
|
||||||
|
- New Device: API_NEW.md
|
||||||
|
- Tests: API_TESTS.md
|
||||||
- Integrations:
|
- Integrations:
|
||||||
- Webhook Secret: WEBHOOK_SECRET.md
|
- Webhook Secret: WEBHOOK_SECRET.md
|
||||||
- API: API.md
|
|
||||||
- Helper scripts: HELPER_SCRIPTS.md
|
- Helper scripts: HELPER_SCRIPTS.md
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user