Files
NetAlertX/docs/PLUGINS_DEV_CONFIG.md
2026-01-19 11:28:37 +00:00

274 lines
8.2 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Plugins Implementation Details
Plugins provide data to the NetAlertX core, which processes it to detect changes, discover new devices, raise alerts, and apply heuristics.
---
## Overview: Plugin Data Flow
1. Each plugin runs on a defined schedule.
2. Aligning all plugin schedules is recommended so they execute in the same loop.
3. During execution, all plugins write their collected data into the **`CurrentScan`** table.
4. After all plugins complete, the `CurrentScan` table is evaluated to detect **new devices**, **changes**, and **triggers**.
Although plugins run independently, they contribute to the shared `CurrentScan` table.
To inspect its contents, set `LOG_LEVEL=trace` and check for the log section:
```
================ CurrentScan table content ================
```
---
## `config.json` Lifecycle
This section outlines how each plugins `config.json` manifest is read, validated, and used by the core and plugins.
It also describes plugin output expectations and the main plugin categories.
> [!TIP]
> For detailed schema and examples, see the [Plugin Development Guide](PLUGINS_DEV.md).
---
### 1. Loading
* On startup, the core loads `config.json` for each plugin.
* The file acts as a **plugin manifest**, defining metadata, runtime configuration, and database mappings.
---
### 2. Validation
* The core validates required keys (for example, `RUN`).
* Missing or invalid entries may be replaced with defaults or cause the plugin to be disabled.
---
### 3. Preparation
* Plugin parameters (paths, commands, and options) are prepared for execution.
* Database mappings (`mapped_to_table`, `database_column_definitions`) are parsed to define how data integrates with the main app.
---
### 4. Execution
* Plugins may run:
* On a fixed schedule.
* Once at startup.
* After a notification or other trigger.
* The scheduler executes plugins according to their `interval`.
---
### 5. Parsing
* Plugin output must be **pipe-delimited (`|`)**.
* The core parses each output line following the **Plugin Interface Contract**, splitting and mapping fields accordingly.
---
### 6. Mapping
* Parsed fields are inserted into the plugins `Plugins_*` table.
* Data can be mapped into other tables (e.g., `Devices`, `CurrentScan`) as defined by:
* `database_column_definitions`
* `mapped_to_table`
**Example:** `Object_PrimaryID → devMAC`
---
### 6a. Plugin Output Contract
All plugins must follow the **Plugin Interface Contract** defined in `PLUGINS_DEV.md`.
Output values are pipe-delimited in a fixed order.
#### Identifiers
* `Object_PrimaryID` and `Object_SecondaryID` uniquely identify records (for example, `MAC|IP`).
#### Watched Values (`Watched_Value14`)
* Used by the core to detect changes between runs.
* Changes in these fields can trigger notifications.
#### Extra Field (`Extra`)
* Optional additional value.
* Stored in the database but not used for alerts.
#### Helper Values (`Helper_Value13`)
* Optional auxiliary data (for display or plugin logic).
* Stored but not alert-triggering.
#### Mapping
* While the output format is flexible, the plugins manifest determines the destination and type of each field.
---
### 7. Persistence
* Parsed data is **upserted** into the database.
* Conflicts are resolved using the combined key: `Object_PrimaryID + Object_SecondaryID`.
---
## Plugin Categories
Plugins fall into several functional categories depending on their purpose and expected outputs.
### 1. Device Discovery Plugins
* **Inputs:** None, subnet, or discovery API.
* **Outputs:** `MAC` and `IP` for new or updated device records in `Devices`.
* **Mapping:** Required usually into `CurrentScan`.
* **Examples:** `ARPSCAN`, `NMAPDEV`.
---
### 2. Device Data Enrichment Plugins
* **Inputs:** Device identifiers (`MAC`, `IP`).
* **Outputs:** Additional metadata (for example, open ports or sensors).
* **Mapping:** Controlled via manifest definitions.
* **Examples:** `NMAP`, `MQTT`.
---
### 3. Name Resolver Plugins
* **Inputs:** Device identifiers (`MAC`, `IP`, hostname`).
* **Outputs:** Updated `devName` and `devFQDN`.
* **Mapping:** Typically none.
* **Note:** Adding new resolvers currently requires a core change.
* **Examples:** `NBTSCAN`, `NSLOOKUP`.
---
### 4. Generic Plugins
* **Inputs:** Custom, based on the plugin logic or script.
* **Outputs:** Data displayed under **Integrations → Plugins** only.
* **Mapping:** Not required.
* **Examples:** `INTRSPD`, custom monitoring scripts.
---
### 5. Configuration-Only Plugins
* **Inputs/Outputs:** None at runtime.
* **Purpose:** Used for configuration or maintenance tasks.
* **Examples:** `MAINT`, `CSVBCKP`.
---
## Post-Processing
After persistence:
* The core generates notifications for any watched value changes.
* The UI updates with new or modified data.
* Plugins with UI-enabled data display under **Integrations → Plugins**.
---
## Field Update Authorization (SET_ALWAYS / SET_EMPTY)
For tracked fields (devMac, devName, devLastIP, devVendor, devFQDN, devSSID, devParentMAC, devParentPort, devParentRelType, devVlan), plugins can configure how they interact with the authoritative field update system.
### SET_ALWAYS
**Mandatory when field is tracked.**
Controls whether a plugin field is enabled:
- `"1"` - Plugin can always overwrite this field when authorized (subject to source-based permissions)
- `"0"` - Plugin doesn't use this field
**Authorization logic:** Even with `SET_ALWAYS: "1"`, the plugin respects source-based permissions:
- Cannot overwrite `USER` source (user manually edited)
- Cannot overwrite `LOCKED` source (user locked field)
- Can overwrite `NEWDEV` or plugin-owned sources (if plugin has SET_ALWAYS enabled)
**Example in config.json:**
```json
{
"setKey": "NEWDEV_devName",
"displayName": "Device Name",
"SET_ALWAYS": "1"
}
```
### SET_EMPTY
**Optional field override.**
Restricts when a plugin can update a field:
- `"1"` - Overwrite only if current value is empty OR source is NEWDEV (conservative mode)
- `"0"` - No extra restriction; respect authorization logic (default)
**Use case:** Some plugins discover optional enrichment data (like vendor/hostname) that shouldn't override user-set or existing values. Use `SET_EMPTY: "1"` to be less aggressive.
**Example in config.json:**
```json
{
"setKey": "NEWDEV_devVendor",
"displayName": "Device Vendor",
"SET_ALWAYS": "1",
"SET_EMPTY": "1"
}
```
### Authorization Decision Flow
1. **Source check:** Is field LOCKED or USER? → REJECT (protected)
2. **SET_ALWAYS check:** Is SET_ALWAYS enabled for this plugin+field? → YES: ALLOW (can overwrite empty values, NEWDEV, plugin sources, etc.) | NO: Continue to step 3
3. **SET_EMPTY check:** Is SET_EMPTY enabled AND field non-empty+non-NEWDEV? → REJECT
4. **Default behavior:** Allow overwrite if field empty or NEWDEV source
### Plugin Field Mappings Reference
This table shows all device discovery and enrichment plugins and their tracked field configuration:
| Plugin | Tracked Fields | Behavior |
|--------|---|---|
| ARPSCAN | devMac, devLastIP | SET_ALWAYS for both |
| IPNEIGH | devMac, devLastIP | SET_ALWAYS for both |
| DHCPLSS | devMac, devLastIP | SET_ALWAYS for both |
| ASUSWRT | devMac, devLastIP | SET_ALWAYS for both |
| LUCIRPC | devMac, devLastIP | SET_ALWAYS for both |
| PIHOLE | devMac, devLastIP, devName, devVendor | SET_ALWAYS for MAC/IP |
| PIHOLEAPI | devMac, devLastIP, devName, devVendor | SET_ALWAYS for MAC/IP, SET_EMPTY for name/vendor |
| NBTSCAN | devName | SET_ALWAYS |
| DIGSCAN | devName, devFQDN | SET_ALWAYS |
| NSLOOKUP | devName, devFQDN | SET_ALWAYS |
| AVAHISCAN | devName | SET_ALWAYS |
| VNDRPDT | devMac, devVendor | SET_ALWAYS for both |
| SNMPDSC | devMac, devLastIP | SET_ALWAYS for both |
| UNIFIMP | devMac, devLastIP, devName, devVendor, devSSID, devParentMAC, devParentPort | SET_ALWAYS for MAC/IP |
| UNIFIAPI | devMac, devLastIP, devName, devParentMAC | SET_ALWAYS for MAC/IP |
**Note:** Check each plugin's `config.json` manifest for its specific SET_ALWAYS/SET_EMPTY configuration.
---
## Summary
The lifecycle of a plugin configuration is:
**Load → Validate → Prepare → Execute → Parse → Map → Persist → Post-process**
Each plugin must:
* Follow the **output contract**.
* Declare its type and expected output structure.
* Define mappings and watched values clearly in `config.json`.