This commit is contained in:
jokob-sk
2025-03-29 17:03:59 +11:00
parent f2e218230e
commit a0561b2016
7 changed files with 264 additions and 31 deletions

View File

@@ -5,7 +5,50 @@
The MAC address is used as a foreign key in most cases.
## 🔍Tables overview
## Devices database table
| Field Name | Description |
|-------------------------|-------------|
| `devMac` | MAC address of the device. |
| `devName` | Name of the device. |
| `devOwner` | Owner of the device. |
| `devType` | Type of the device (e.g., phone, laptop, etc.). If set to a network type (e.g.: switch), it will become selectable as a Network Parent Node |
| `devVendor` | Vendor/manufacturer of the device. |
| `devFavorite` | Whether the device is marked as a favorite. |
| `devGroup` | Group the device belongs to. |
| `devComments` | User comments or notes about the device. |
| `devFirstConnection` | Timestamp of the device's first connection. |
| `devLastConnection` | Timestamp of the device's last connection. |
| `devLastIP` | Last known IP address of the device. |
| `devStaticIP` | Whether the device has a static IP address. |
| `devScan` | Whether the device should be scanned. |
| `devLogEvents` | Whether events related to the device should be logged. |
| `devAlertEvents` | Whether alerts should be generated for events. |
| `devAlertDown` | Whether an alert should be sent when the device goes down. |
| `devSkipRepeated` | Whether to skip repeated alerts for this device. |
| `devLastNotification` | Timestamp of the last notification sent for this device. |
| `devPresentLastScan` | Whether the device was present during the last scan. |
| `devIsNew` | Whether the device is marked as new. |
| `devLocation` | Physical or logical location of the device. |
| `devIsArchived` | Whether the device is archived. |
| `devParentMAC` | MAC address of the parent device (if applicable). |
| `devParentPort` | Port of the parent device to which this device is connected. |
| `devIcon` | Icon representing the device. |
| `devGUID` | Unique identifier for the device. |
| `devSite` | Site or location where the device is registered. |
| `devSSID` | SSID of the Wi-Fi network the device is connected to. |
| `devSyncHubNode` | The NetAlertX node ID used for synchronization between NetAlertX instances. |
| `devSourcePlugin` | Source plugin that discovered the device. |
To understand how values of these fields influuence application behavior, such as Notifications or Network topology, see also:
- [Device Management](./DEVICE_MANAGEMENT.md)
- [Network Tree Topology Setup](./NETWORK_TREE.md)
- [Notifications](./NOTIFICATIONS.md)
## Other Tables overview
| Table name | Description | Sample data |
|----------------------|----------------------| ----------------------|

116
docs/WORKFLOWS.md Executable file
View File

@@ -0,0 +1,116 @@
# Workflows Overview
The workflows module in NetAlertX allows you to automate repetitive tasks, making network management more efficient. Whether you need to assign newly discovered devices to a specific Network Node, auto-group devices from a given vendor, unarchive a device if detected online, or automatically delete or archive devices, this module provides the flexibility to tailor the automations to your needs.
![Workflow example](./img/WORKFLOWS/workflows.png)
Below are a few examples that demonstrate how this module can be used to simplify network management tasks.
> [!NOTE]
> In order to apply a workflow change, you must first **Save** the changes and then reload the application by clicking **Restart server**.
## Triggers
Triggers define the event that activates a workflow. They monitor changes to objects within the system, such as updates to devices or the insertion of new entries. When the specified event occurs, the workflow is executed.
### Example Trigger:
- **Object Type**: `Devices`
- **Event Type**: `update`
This trigger will activate when a `Device` object is updated.
## Conditions
Conditions determine whether a workflow should proceed based on certain criteria. These criteria can be set for specific fields, such as whether a device is from a certain vendor, or whether it is new or archived. You can combine conditions using logical operators (`AND`, `OR`).
> [!TIP]
> To better understand how to use specific Device fields, please read through the [Database overview](./DATABASE.md) guide.
### Example Condition:
- **Logic**: `AND`
- **Field**: `devVendor`
- **Operator**: `contains`
- **Value**: `Google`
This condition checks if the device's vendor is `Google`. The workflow will only proceed if the condition is true.
## Actions
Actions define the tasks that the workflow will perform once the conditions are met. Actions can include updating fields or deleting devices.
### Example Action:
- **Action Type**: `update_field`
- **Field**: `devIsNew`
- **Value**: `0`
This action updates the `devIsNew` field to `0`, marking the device as no longer new.
# Examples
Below you can find a couple of configuration examples.
---
## Example 1: Assign Device to Network Node Based on IP
### Trigger:
- **Object Type**: `Devices`
- **Event Type**: `insert`
### Conditions:
- **Logic**: `AND`
- `Field`: `devLastIP`
- `Operator`: `contains`
- `Value`: `192.168.1.`
This condition ensures that the workflow only applies to devices with an IP address in the `192.168.1.*` range.
### Actions:
- **Action Type**: `update_field`
- **Field**: `devNetworkNode`
- **Value**: `6c:6d:6d:6c:6c:6c`
This workflow assigns newly added devices with IP addresses in the `192.168.1.*` range to the device with the MAC address `6c:6d:6d:6c:6c:6c`.
---
## Example 2: Mark Device as Not New and Delete If from Google Vendor
### Trigger:
- **Object Type**: `Devices`
- **Event Type**: `update`
### Conditions:
- **Logic**: `AND`
- `Field`: `devVendor`
- `Operator`: `contains`
- `Value`: `Google`
This condition checks if the device's vendor is `Google`.
- **Logic**: `AND`
- `Field`: `devIsNew`
- `Operator`: `equals`
- `Value`: `1`
This ensures the workflow applies only to new devices.
### Actions:
1. **Action Type**: `update_field`
- **Field**: `devIsNew`
- **Value**: `0`
This action marks the device as no longer new.
2. **Action Type**: `delete_device`
This action deletes the device after it is marked as not new.
This workflow automates the process of marking Google devices as not new and deleting them if they meet the criteria.
---
### Conclusion
With workflows, NetAlertX can automatically adjust to network changes, saving time and reducing the manual overhead involved in maintaining your devices. You can create highly tailored automation rules to handle everything from basic updates to more complex device management.

BIN
docs/img/WORKFLOWS/workflows.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

@@ -1884,6 +1884,7 @@ input[readonly] {
margin-bottom: 7px;
z-index: 1;
display: flex;
opacity: 0.7;
}
.workflows .section-title
@@ -1905,18 +1906,18 @@ input[readonly] {
.workflows .button-container
{
display: contents;
/* display: contents; */
text-align: center;
width: 100%;
/* width: 100%; */
}
.workflows .panel:hover{
/* .workflows .panel:hover{
opacity: 1;
}
.workflows .panel{
opacity: 0.8;
}
} */
.workflows .bottom-buttons button
{
@@ -1939,6 +1940,48 @@ input[readonly] {
width:100%;
} */
.red-hover-text:hover
{
color: var(--color-red) !important;
}
.green-hover-text:hover
{
color: var(--color-green) !important;
}
.workflows .bckg-icon-1-line
{
font-size: 3em;
display: block;
position: absolute;
opacity: 0.1;
right: 0.1em;
}
.workflows .bckg-icon-2-line
{
font-size: 6em;
display: block;
position: absolute;
opacity: 0.1;
right: 0.1em;
}
.workflows .bckg-icon-3-line
{
font-size: 9em;
display: block;
position: absolute;
opacity: 0.1;
right: 0.1em;
}
.workflows .remove-condition
{
z-index: 1;
}
.workflows .workflow-card
{
display: block;

View File

@@ -34,12 +34,12 @@
let workflows = [];
let fieldOptions = [
"devMac", "devName", "devOwner", "devType", "devVendor", "devFavorite",
"devName", "devOwner", "devType", "devVendor", "devFavorite",
"devGroup", "devComments", "devFirstConnection", "devLastConnection",
"devLastIP", "devStaticIP", "devScan", "devLogEvents", "devAlertEvents",
"devAlertDown", "devSkipRepeated", "devLastNotification", "devPresentLastScan",
"devIsNew", "devLocation", "devIsArchived", "devParentMAC", "devParentPort",
"devIcon", "devGUID", "devSite", "devSSID", "devSyncHubNode", "devSourcePlugin"
"devIcon", "devSite", "devSSID", "devSyncHubNode", "devSourcePlugin"
];
let triggerTypes = [
@@ -160,11 +160,15 @@ function generateWorkflowUI(wf, wfIndex) {
$wfCollapsiblePanel.append($wfNameInput)
let $triggersIcon = $("<i>", {
class: "fa-solid fa-bolt"
});
let $triggerTitle = $("<div>",
{
class:"section-title"
}
).text("Trigger:")
).append($triggersIcon).append(" Trigger:")
// Trigger Section with dropdowns
let $triggerSection = $("<div>",
@@ -189,32 +193,43 @@ function generateWorkflowUI(wf, wfIndex) {
`wf-${wfIndex}-trigger-event-type`
);
let $triggerIcon = $("<i>", {
class: "fa-solid fa-bolt bckg-icon-2-line"
});
$triggerSection.append($triggerTypeDropdown);
$triggerSection.append($eventTypeDropdown);
$triggerSection.append($triggerIcon);
$wfCollapsiblePanel.append($triggerSection);
// Conditions
let $conditionsTitle = $("<div>",
{
class:"section-title"
}
).text("Conditions:")
let $conditionsContainer = $("<div>",
{
class: "col-sm-12 col-sx-12"
}
).append($conditionsTitle);
let $conditionsIcon = $("<i>", {
class: "fa-solid fa-arrows-split-up-and-left fa-rotate-270"
});
let $conditionsTitle = $("<div>", {
class: "section-title"
}).append($conditionsIcon).append(" Conditions:");
let $conditionsContainer = $("<div>", {
class: "col-sm-12 col-sx-12"
}).append($conditionsTitle);
$conditionsContainer.append(renderConditions(wfIndex, `[${wfIndex}]`, 0, wf.conditions));
$wfCollapsiblePanel.append($conditionsContainer);
let $actionsIcon = $("<i>", {
class: "fa-solid fa-person-running fa-flip-horizontal"
});
let $actionsTitle = $("<div>",
{
class:"section-title"
}
).text("Actions:")
).append($actionsIcon).append(" Actions:")
// Actions with action.field as dropdown
let $actionsContainer = $("<div>",
@@ -233,6 +248,7 @@ function generateWorkflowUI(wf, wfIndex) {
class: "panel col-sm-12 col-sx-12"
});
// Dropdown for action.type
let $actionDropdown= createEditableDropdown(
`[${wfIndex}].actions[${actionIndex}].type`,
@@ -242,10 +258,16 @@ function generateWorkflowUI(wf, wfIndex) {
`wf-${wfIndex}-actionIndex-${actionIndex}-type`
);
$actionEl.append($actionDropdown);
// how big should the background icon be
let numberOfLines = 1
if(action.type == "update_field")
{
numberOfLines = 3
// Dropdown for action.field
let $fieldDropdown = createEditableDropdown(
`[${wfIndex}].actions[${actionIndex}].field`,
@@ -279,7 +301,7 @@ function generateWorkflowUI(wf, wfIndex) {
});
let $actionRemoveButton = $("<div>", {
class: "pointer remove-action ",
class: "pointer remove-action red-hover-text",
actionIndex: actionIndex,
wfIndex: wfIndex
})
@@ -287,7 +309,12 @@ function generateWorkflowUI(wf, wfIndex) {
$actionRemoveButtonWrap.append($actionRemoveButton);
let $actionIcon = $("<i>", {
class: `fa-solid fa-person-running fa-flip-horizontal bckg-icon-${numberOfLines}-line `
});
$actionElWrap.append($actionEl)
$actionElWrap.append($actionIcon)
$actionElWrap.append($actionRemoveButtonWrap)
$actionsContainer.append($actionElWrap);
@@ -301,7 +328,7 @@ function generateWorkflowUI(wf, wfIndex) {
class: "fa-solid fa-plus"
});
let $actionAddButton = $("<div>", {
class : "pointer add-action",
class : "pointer add-action green-hover-text",
lastActionIndex : lastActionIndex,
wfIndex: wfIndex
}).append($actionAddIcon).append("Add Action")
@@ -317,7 +344,7 @@ function generateWorkflowUI(wf, wfIndex) {
});
let $wfRemoveButton = $("<div>", {
class: "pointer remove-wf",
class: "pointer remove-wf red-hover-text",
wfIndex: wfIndex
})
.append($wfRemoveIcon) // Add icon
@@ -381,6 +408,10 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
} else {
// INDIVIDUAL CONDITIONS
let $conditionIcon = $("<i>", {
class: "fa-solid fa-arrows-split-up-and-left fa-rotate-270 bckg-icon-3-line "
});
let $conditionItem = $("<div>",
{
class: "panel col-sm-12 col-sx-12",
@@ -388,6 +419,8 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
wfIndex: wfIndex
});
$conditionItem.append($conditionIcon); // Append background icon
let $conditionItemsWrap = $("<div>",
{
class: "conditionItemsWrap col-sm-11 col-sx-12"
@@ -419,6 +452,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
"condition-value-input"
);
$conditionItemsWrap.append($fieldDropdown); // Append field dropdown
$conditionItemsWrap.append($operatorDropdown); // Append operator dropdown
$conditionItemsWrap.append($editableInput); // Append editable input for condition value
@@ -428,7 +462,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
class: "fa-solid fa-trash"
});
let $conditionRemoveButton = $("<div>", {
class : "pointer remove-condition ",
class : "pointer remove-condition red-hover-text",
conditionIndex : conditionIndex,
wfIndex: wfIndex,
parentIndexPath: parentIndexPath
@@ -455,7 +489,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
class: "fa-solid fa-plus"
});
let $conditionAddButton = $("<div>", {
class: "pointer add-condition col-sx-12",
class: "pointer add-condition green-hover-text col-sx-12",
wfIndex: wfIndex,
parentIndexPath: parentIndexPath
}).append($conditionAddIcon).append("Add Condition");
@@ -467,7 +501,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
class: "fa-solid fa-trash"
});
let $conditionGroupRemoveButton = $("<div>", {
class: "pointer remove-condition-group col-sx-12",
class: "pointer remove-condition-group red-hover-text col-sx-12",
lastConditionIndex: lastConditionIndex,
wfIndex: wfIndex,
parentIndexPath: parentIndexPath
@@ -485,7 +519,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
class: "fa-solid fa-plus"
});
let $conditionsGroupAddButton = $("<div>", {
class: "pointer add-condition-group col-sx-12",
class: "pointer add-condition-group green-hover-text col-sx-12",
wfIndex: wfIndex,
parentIndexPath: parentIndexPath
}).append($conditionsGroupAddIcon).append("Add Group");

View File

@@ -41,6 +41,7 @@ nav:
- Reverse DNS: REVERSE_DNS.md
- Reverse Proxy: REVERSE_PROXY.md
- Webhooks (n8n): WEBHOOK_N8N.md
- Workflows: WORKFLOWS.md
- Help:
- Common issues: COMMON_ISSUES.md
- Random MAC: RANDOM_MAC.md

View File

@@ -44,11 +44,7 @@
"value": "0"
},
{
"type": "run_plugin",
"plugin": "SMTP",
"params": {
"message": "New device from Google detected."
}
"type": "delete_device"
}
]
}