Plugins 0.3 - SQL support, UI CSS tweks, Lang fixes

This commit is contained in:
Jokob-sk
2023-02-26 12:28:15 +11:00
parent f04cd7e28b
commit 99f522e625
10 changed files with 451 additions and 70 deletions

View File

@@ -40,14 +40,12 @@ jobs:
jokobsk/pi.alert jokobsk/pi.alert
# generate Docker tags based on the following events/attributes # generate Docker tags based on the following events/attributes
tags: | tags: |
type=raw,value=latest type=semver,pattern={{version}},value=${{ inputs.version }}
type=schedule type=semver,pattern={{major}}.{{minor}},value=${{ inputs.version }}
type=ref,event=branch type=semver,pattern={{major}},value=${{ inputs.version }}
type=ref,event=branch,suffix=-{{ sha }}
type=ref,event=pr type=ref,event=pr
type=semver,pattern={{version}} type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Login to DockerHub - name: Login to DockerHub
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
uses: docker/login-action@v2 uses: docker/login-action@v2

View File

@@ -52,8 +52,9 @@ sql_pholus_scan_all = "SELECT * FROM Pholus_Scan"
sql_events_pending_alert = "SELECT * FROM Events where eve_PendingAlertEmail is not 0" sql_events_pending_alert = "SELECT * FROM Events where eve_PendingAlertEmail is not 0"
sql_settings = "SELECT * FROM Settings" sql_settings = "SELECT * FROM Settings"
sql_plugins_objects = "SELECT * FROM Plugins_Objects" sql_plugins_objects = "SELECT * FROM Plugins_Objects"
sql_language_strings = "SELECT * FROM Language_Strings" sql_language_strings = "SELECT * FROM Plugins_Language_Strings"
sql_plugins_events = "SELECT * FROM Plugins_Events" sql_plugins_events = "SELECT * FROM Plugins_Events"
sql_plugins_history = "SELECT * FROM Plugins_History ORDER BY 'Index' DESC LIMIT 50"
sql_new_devices = """SELECT * FROM ( SELECT eve_IP as dev_LastIP, eve_MAC as dev_MAC FROM Events_Devices sql_new_devices = """SELECT * FROM ( SELECT eve_IP as dev_LastIP, eve_MAC as dev_MAC FROM Events_Devices
WHERE eve_PendingAlertEmail = 1 WHERE eve_PendingAlertEmail = 1
AND eve_EventType = 'New Device' AND eve_EventType = 'New Device'
@@ -879,6 +880,10 @@ def cleanup_database ():
mylog('verbose', [' Events: Delete all older than '+str(DAYS_TO_KEEP_EVENTS)+' days']) mylog('verbose', [' Events: Delete all older than '+str(DAYS_TO_KEEP_EVENTS)+' days'])
sql.execute ("DELETE FROM Events WHERE eve_DateTime <= date('now', '-"+str(DAYS_TO_KEEP_EVENTS)+" day')") sql.execute ("DELETE FROM Events WHERE eve_DateTime <= date('now', '-"+str(DAYS_TO_KEEP_EVENTS)+" day')")
# Cleanup Plugin Events History
mylog('verbose', [' Plugin Events History: Delete all older than '+str(DAYS_TO_KEEP_EVENTS)+' days'])
sql.execute ("DELETE FROM Plugins_History WHERE DateTimeChanged <= date('now', '-"+str(DAYS_TO_KEEP_EVENTS)+" day')")
# Cleanup Pholus_Scan # Cleanup Pholus_Scan
if PHOLUS_DAYS_DATA != 0: if PHOLUS_DAYS_DATA != 0:
mylog('verbose', [' Pholus_Scan: Delete all older than ' + str(PHOLUS_DAYS_DATA) + ' days']) mylog('verbose', [' Pholus_Scan: Delete all older than ' + str(PHOLUS_DAYS_DATA) + ' days'])
@@ -2201,6 +2206,7 @@ def send_notifications ():
global mail_text, mail_html, json_final, changedPorts_json_struc, partial_html, partial_txt, partial_json global mail_text, mail_html, json_final, changedPorts_json_struc, partial_html, partial_txt, partial_json
deviceUrl = REPORT_DASHBOARD_URL + '/deviceDetails.php?mac=' deviceUrl = REPORT_DASHBOARD_URL + '/deviceDetails.php?mac='
plugins_report = False
# Reporting section # Reporting section
mylog('verbose', [' Check if something to report']) mylog('verbose', [' Check if something to report'])
@@ -3168,6 +3174,25 @@ def upgradeDB ():
); """ ); """
sql.execute(sql_Plugins_Events) sql.execute(sql_Plugins_Events)
# Plugin execution history
sql_Plugins_History = """ CREATE TABLE IF NOT EXISTS Plugins_History(
"Index" INTEGER,
Plugin TEXT NOT NULL,
Object_PrimaryID TEXT NOT NULL,
Object_SecondaryID TEXT NOT NULL,
DateTimeCreated TEXT NOT NULL,
DateTimeChanged TEXT NOT NULL,
Watched_Value1 TEXT NOT NULL,
Watched_Value2 TEXT NOT NULL,
Watched_Value3 TEXT NOT NULL,
Watched_Value4 TEXT NOT NULL,
Status TEXT NOT NULL,
Extra TEXT NOT NULL,
UserData TEXT NOT NULL,
PRIMARY KEY("Index" AUTOINCREMENT)
); """
sql.execute(sql_Plugins_History)
# Dynamically generated language strings # Dynamically generated language strings
# indicates, if Language_Strings table is available # indicates, if Language_Strings table is available
languageStringsMissing = sql.execute(""" languageStringsMissing = sql.execute("""
@@ -3252,6 +3277,7 @@ def update_api(isNotification = False, updateOnlyDataSources = []):
["events_pending_alert", sql_events_pending_alert], ["events_pending_alert", sql_events_pending_alert],
["settings", sql_settings], ["settings", sql_settings],
["plugins_events", sql_plugins_events], ["plugins_events", sql_plugins_events],
["plugins_history", sql_plugins_history],
["plugins_objects", sql_plugins_objects], ["plugins_objects", sql_plugins_objects],
["language_strings", sql_language_strings], ["language_strings", sql_language_strings],
["custom_endpoint", API_CUSTOM_SQL], ["custom_endpoint", API_CUSTOM_SQL],
@@ -3758,6 +3784,9 @@ def execute_plugin(plugin):
# Execute command # Execute command
mylog('verbose', [' [Plugins] Executing: ', set_CMD]) mylog('verbose', [' [Plugins] Executing: ', set_CMD])
# python-script
if plugin['data_source'] == 'python-script':
try: try:
# try runnning a subprocess with a forced timeout in case the subprocess hangs # try runnning a subprocess with a forced timeout in case the subprocess hangs
output = subprocess.check_output (command, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(set_RUN_TIMEOUT)) output = subprocess.check_output (command, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(set_RUN_TIMEOUT))
@@ -3798,9 +3827,26 @@ def execute_plugin(plugin):
else: else:
mylog('none', [' [Plugins]: Skipped invalid line in the output: ', line]) mylog('none', [' [Plugins]: Skipped invalid line in the output: ', line])
# pialert-db-query
if plugin['data_source'] == 'pialert-db-query':
# build SQL query parameters to insert into the DB
sqlParams = []
# set_CMD should contain a SQL query
arr = get_sql_array (set_CMD)
for row in arr:
# There has to be always 8 columns
if len(row) == 8:
sqlParams.append((plugin["unique_prefix"], row[0], row[1], 'null', row[2], row[3], row[4], row[5], row[6], 0, row[7], 'null'))
else:
mylog('none', [' [Plugins]: Skipped invalid sql result'])
if len(sqlParams) > 0: if len(sqlParams) > 0:
sql.executemany ("""INSERT INTO Plugins_Events ("Plugin", "Object_PrimaryID", "Object_SecondaryID", "DateTimeCreated", "DateTimeChanged", "Watched_Value1", "Watched_Value2", "Watched_Value3", "Watched_Value4", "Status" ,"Extra", "UserData") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", sqlParams) sql.executemany ("""INSERT INTO Plugins_Events ("Plugin", "Object_PrimaryID", "Object_SecondaryID", "DateTimeCreated", "DateTimeChanged", "Watched_Value1", "Watched_Value2", "Watched_Value3", "Watched_Value4", "Status" ,"Extra", "UserData") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", sqlParams)
commitDB () commitDB ()
sql.executemany ("""INSERT INTO Plugins_History ("Plugin", "Object_PrimaryID", "Object_SecondaryID", "DateTimeCreated", "DateTimeChanged", "Watched_Value1", "Watched_Value2", "Watched_Value3", "Watched_Value4", "Status" ,"Extra", "UserData") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", sqlParams)
commitDB ()
process_plugin_events(plugin) process_plugin_events(plugin)
@@ -3828,6 +3874,7 @@ def process_plugin_events(plugin):
existingPluginObjectsCount = len(pluginObjects) existingPluginObjectsCount = len(pluginObjects)
mylog('debug', [' [Plugins] Existing objects: ', existingPluginObjectsCount]) mylog('debug', [' [Plugins] Existing objects: ', existingPluginObjectsCount])
mylog('debug', [' [Plugins] Events objects: ', len(plugEventsArr)])
# set status as new - will be changed later if conditions are fulfilled, e.g. entry found # set status as new - will be changed later if conditions are fulfilled, e.g. entry found
for eve in plugEventsArr: for eve in plugEventsArr:
@@ -3844,9 +3891,6 @@ def process_plugin_events(plugin):
if any(x.idsHash == tmpObject.idsHash for x in pluginObjects): if any(x.idsHash == tmpObject.idsHash for x in pluginObjects):
mylog('debug', [' [Plugins] Found existing object']) mylog('debug', [' [Plugins] Found existing object'])
pluginEvents[index].status = "exists" pluginEvents[index].status = "exists"
# plugEventsArr.pop(index) # remove processed entry
index += 1 index += 1
# Loop thru events and update the one that exist to determine if watched columns changed # Loop thru events and update the one that exist to determine if watched columns changed
@@ -3858,11 +3902,8 @@ def process_plugin_events(plugin):
# compare hash of the changed watched columns for uniqueness # compare hash of the changed watched columns for uniqueness
if any(x.watchedHash != tmpObject.watchedHash for x in pluginObjects): if any(x.watchedHash != tmpObject.watchedHash for x in pluginObjects):
pluginEvents[index].status = "watched-changed" pluginEvents[index].status = "watched-changed"
# plugEventsArr.pop(index) # remove processed entry
else: else:
pluginEvents[index].status = "watched-not-changed" pluginEvents[index].status = "watched-not-changed"
index += 1 index += 1
# Merge existing plugin objects with newly discovered ones and update existin ones with new values # Merge existing plugin objects with newly discovered ones and update existin ones with new values
@@ -3882,20 +3923,21 @@ def process_plugin_events(plugin):
# ---------------------------- # ----------------------------
# Update the Plugin_Objects # Update the Plugin_Objects
for plugObj in pluginObjects: for plugObj in pluginObjects:
createdTime = plugObj.created createdTime = plugObj.created
if plugObj.status == 'new': if plugObj.status == 'new':
createdTime = plugObj.changed createdTime = plugObj.changed
sql.execute ("INSERT INTO Plugins_Objects (Plugin, Object_PrimaryID, Object_SecondaryID, DateTimeCreated, DateTimeChanged, Watched_Value1, Watched_Value2, Watched_Value3, Watched_Value4, Status, Extra, UserData) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", (plugObj.pluginPref, plugObj.primaryId , plugObj.secondaryId , createdTime, plugObj.changed , plugObj.watched1 , plugObj.watched2 , plugObj.watched3 , plugObj.watched4 , plugObj.status , plugObj.extra, plugObj.userData ))
else:
q = f"UPDATE Plugins_Objects set Plugin = '{plugObj.pluginPref}', DateTimeChanged = '{plugObj.changed}', Watched_Value1 = '{plugObj.watched1}', Watched_Value2 = '{plugObj.watched2}', Watched_Value3 = '{plugObj.watched3}', Watched_Value4 = '{plugObj.watched4}', Status = '{plugObj.status}', Extra = '{plugObj.extra}' WHERE 'Index' = {plugObj.index}" q = f"UPDATE Plugins_Objects set Plugin = '{plugObj.pluginPref}', DateTimeChanged = '{plugObj.changed}', Watched_Value1 = '{plugObj.watched1}', Watched_Value2 = '{plugObj.watched2}', Watched_Value3 = '{plugObj.watched3}', Watched_Value4 = '{plugObj.watched4}', Status = '{plugObj.status}', Extra = '{plugObj.extra}' WHERE 'Index' = {plugObj.index}"
sql.execute (q) sql.execute (q)
# Update the Plugins_Events with the new statuses # Update the Plugins_Events with the new statuses
sql.execute ("DELETE FROM Plugins_Events") sql.execute ("DELETE FROM Plugins_Events")
for plugObj in pluginEvents: for plugObj in pluginEvents:

View File

@@ -7,9 +7,9 @@ services:
network_mode: "host" network_mode: "host"
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- ${APP_DATA_LOCATION}/pialert/config:/home/pi/pialert/config - ${APP_DATA_LOCATION}/pialert/config2:/home/pi/pialert/config
# - ${APP_DATA_LOCATION}/pialert/db/pialert.db:/home/pi/pialert/db/pialert.db # - ${APP_DATA_LOCATION}/pialert/db/pialert.db:/home/pi/pialert/db/pialert.db
- ${APP_DATA_LOCATION}/pialert/db:/home/pi/pialert/db - ${APP_DATA_LOCATION}/pialert/db2:/home/pi/pialert/db
# (optional) useful for debugging if you have issues setting up the container # (optional) useful for debugging if you have issues setting up the container
- ${LOGS_LOCATION}:/home/pi/pialert/front/log - ${LOGS_LOCATION}:/home/pi/pialert/front/log
# DELETE START anyone trying to use this file: comment out / delete BELOW lines, they are only for development purposes # DELETE START anyone trying to use this file: comment out / delete BELOW lines, they are only for development purposes

View File

@@ -806,5 +806,18 @@ height: 50px;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.plugin-content
{
padding-bottom: 7px;
}
.plugin-content #tabs-content-location
{
margin-top: 20px;
margin-left: 7px;
margin-right: 7px;
margin-bottom: 9px;
padding-bottom: 8px;
}

View File

@@ -478,6 +478,7 @@ $lang['en_us'] = array(
'Plugins_Unprocessed_Events' => 'Unprocessed Events', 'Plugins_Unprocessed_Events' => 'Unprocessed Events',
'Plugins_Objects' => 'Plugin Objects', 'Plugins_Objects' => 'Plugin Objects',
'Plugins_History' => 'Events History',
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// Settings // Settings
@@ -513,7 +514,7 @@ The arp-scan time itself depends on the number of IP addresses to check so set t
'SCAN_CYCLE_MINUTES_name' => 'Scan cycle delay', 'SCAN_CYCLE_MINUTES_name' => 'Scan cycle delay',
'SCAN_CYCLE_MINUTES_description' => 'The delay between scans in minutes. If using arp-scan, the scan time itself depends on the number of IP addresses to check. This is influenced by the network mask set in the <a href="#SCAN_SUBNETS"><code>SCAN_SUBNETS</code> setting</a> at the top. Every IP takes a couple seconds to scan.', 'SCAN_CYCLE_MINUTES_description' => 'The delay between scans in minutes. If using arp-scan, the scan time itself depends on the number of IP addresses to check. This is influenced by the network mask set in the <a href="#SCAN_SUBNETS"><code>SCAN_SUBNETS</code> setting</a> at the top. Every IP takes a couple seconds to scan.',
'DAYS_TO_KEEP_EVENTS_name' => 'Delete events older than', 'DAYS_TO_KEEP_EVENTS_name' => 'Delete events older than',
'DAYS_TO_KEEP_EVENTS_description' => 'This is a maintenance setting. This specifies the number of days worth of event entries that will be kept. All older events will be deleted periodically.', 'DAYS_TO_KEEP_EVENTS_description' => 'This is a maintenance setting. This specifies the number of days worth of event entries that will be kept. All older events will be deleted periodically. Also applies on Plugin Events History.',
'REPORT_DASHBOARD_URL_name' => 'Pi.Alert URL', 'REPORT_DASHBOARD_URL_name' => 'Pi.Alert URL',
'REPORT_DASHBOARD_URL_description' => 'This URL is used as the base for generating links in the emails. Enter full URL starting with <code>http://</code> including the port number (no trailig slash <code>/</code>).', 'REPORT_DASHBOARD_URL_description' => 'This URL is used as the base for generating links in the emails. Enter full URL starting with <code>http://</code> including the port number (no trailig slash <code>/</code>).',
'DIG_GET_IP_ARG_name' => 'Internet IP discovery', 'DIG_GET_IP_ARG_name' => 'Internet IP discovery',

View File

@@ -19,7 +19,7 @@ switch($result){
if (isset($pia_lang_selected) == FALSE or (strlen($pia_lang_selected) == 0)) {$pia_lang_selected = $defaultLang;} if (isset($pia_lang_selected) == FALSE or (strlen($pia_lang_selected) == 0)) {$pia_lang_selected = $defaultLang;}
//Language_Strings ("Language_Code", "String_Key", "String_Value", "Extra") //Language_Strings ("Language_Code", "String_Key", "String_Value", "Extra")
$result = $db->query("SELECT * FROM Language_Strings"); $result = $db->query("SELECT * FROM Plugins_Language_Strings");
// array // array
$strings = array(); $strings = array();

View File

@@ -19,7 +19,7 @@
<!-- Main content ---------------------------------------------------------- --> <!-- Main content ---------------------------------------------------------- -->
<section class="content"> <section class="content">
<div class="nav-tabs-custom" style="margin-bottom: 0px;"> <div class="nav-tabs-custom plugin-content" style="margin-bottom: 0px;">
<ul id="tabs-location" class="nav nav-tabs"> <ul id="tabs-location" class="nav nav-tabs">
<!-- PLACEHOLDER --> <!-- PLACEHOLDER -->
</ul> </ul>
@@ -146,6 +146,7 @@ function localize (obj, key) {
pluginDefinitions = [] pluginDefinitions = []
pluginUnprocessedEvents = [] pluginUnprocessedEvents = []
pluginObjects = [] pluginObjects = []
pluginHistory = []
function getData(){ function getData(){
@@ -161,10 +162,15 @@ function getData(){
pluginObjects = res["data"]; pluginObjects = res["data"];
$.get('api/table_plugins_history.json', function(res) {
pluginHistory = res["data"];
generateTabs() generateTabs()
}); });
}); });
});
}); });
} }
@@ -194,6 +200,7 @@ function generateTabs()
colDefinitions = [] colDefinitions = []
evRows = "" evRows = ""
obRows = "" obRows = ""
hiRows = ""
// Generate the header // Generate the header
$.each(obj["database_column_definitions"], function(index, colDef){ $.each(obj["database_column_definitions"], function(index, colDef){
@@ -221,7 +228,20 @@ function generateTabs()
} }
} }
// Generate the history rows
for(i=0;i<pluginHistory.length;i++)
{
if(pluginHistory[i].Plugin == obj.unique_prefix)
{
clm = ""
for(j=0;j<colDefinitions.length;j++)
{
clm += '<td>'+ pluginHistory[i][colDefinitions[j].column] +'</td>'
}
hiRows += '<tr>' + clm + '</tr>'
}
}
// Generate the object rows // Generate the object rows
for(i=0;i<pluginObjects.length;i++) for(i=0;i<pluginObjects.length;i++)
@@ -261,6 +281,14 @@ function generateTabs()
</a> </a>
</li> </li>
<li>
<a href="#historyTarget" data-toggle="tab" >
<i class="fa fa-clock"></i> <?= lang('Plugins_History');?> (${pluginHistory.length})
</a>
</li>
<ul> <ul>
</div> </div>
@@ -288,6 +316,17 @@ function generateTabs()
</tbody> </tbody>
</table> </table>
</div> </div>
<div id="historyTarget" class="tab-pane">
<table class="table table-striped">
<tbody>
<tr>
${headersHtml}
</tr>
${hiRows}
</tbody>
</table>
</div>
</div> </div>

View File

@@ -0,0 +1,12 @@
## Overview
A simple sample plugin allowing for monitoring web services or urls. The status code corresponds to the commonly used [HTTP response status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status).
### Usage
- The user can specify which services (websites) to monitor via the `WEBMON_urls_to_check` setting.
### Notes
- Setting `(WEBMON_)SQL_internet_ip` is not used and specified for demonstration purposes only.
- Parameters `macs` and `internet_ip` in the `config.json` file are not used and specified for demonstration purposes only.

View File

@@ -0,0 +1,275 @@
{
"code_name": "nmap_services",
"unique_prefix": "NMAPSRV",
"data_source": "pialert-db-query",
"localized": ["display_name", "description", "icon"],
"display_name" : [{
"language_code":"en_us",
"string" : "Services"
}],
"icon":[{
"language_code":"en_us",
"string" : "<i class=\"fa-solid fa-search\"></i>"
}],
"description": [{
"language_code":"en_us",
"string" : "This plugin shows all services discovered by NMAP scans."
}],
"params" : [],
"database_column_definitions":
[
{
"column": "Index",
"show": false,
"type": "label",
"default_value":"",
"options": [],
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "N/A"
}]
} ,
{
"column": "Plugin",
"show": false,
"type": "label",
"default_value":"",
"options": [],
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "N/A"
}]
},
{
"column": "Object_PrimaryID",
"show": true,
"type": "url",
"default_value":"",
"options": [],
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "Device name"
}]
},
{
"column": "Object_SecondaryD",
"show": true,
"type": "label",
"default_value":"",
"options": [],
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "Ip and Port"
}]
} ,
{
"column": "DateTimeCreated",
"show": true,
"type": "label",
"default_value":"",
"options": [],
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "Created"
}]
},
{
"column": "DateTimeChanged",
"show": true,
"type": "label",
"default_value":"",
"options": [],
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "Changed"
}]
},
{
"column": "Watched_Value1",
"show": true,
"type": "label",
"default_value":"",
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "Service"
}]
},
{
"column": "Watched_Value2",
"show": true,
"type": "label",
"default_value":"",
"options": [],
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "State"
}]
},
{
"column": "Watched_Value3",
"show": false,
"type": "label",
"default_value":"",
"options": [],
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "N/A"
}]
} ,
{
"column": "Watched_Value4",
"show": false,
"type": "label",
"default_value":"",
"options": [],
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "N/A"
}]
} ,
{
"column": "Extra",
"show": true,
"type": "label",
"default_value":"",
"options": [],
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "Extra"
}]
},
{
"column": "Status",
"show": true,
"type": "replace",
"default_value":"",
"options": [
{
"equals": "watched-not-changed",
"replacement": "<div style='text-align:center'><i class='fa-solid fa-square-check'></i><div></div>"
},
{
"equals": "watched-changed",
"replacement": "<div style='text-align:center'><i class='fa-solid fa-triangle-exclamation'></i></div>"
},
{
"equals": "new",
"replacement": "<div style='text-align:center'><i class='fa-solid fa-circle-plus'></i></div>"
}
],
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "Status"
}]
}
],
"settings":[
{
"function": "RUN",
"type": "selecttext",
"default_value":"disabled",
"options": ["disabled", "once", "schedule", "always_after_scan", "on_new_device"],
"localized": ["name", "description"],
"name" :[{
"language_code":"en_us",
"string" : "When to run"
}],
"description": [{
"language_code":"en_us",
"string" : "Specify when the SQL query is executed."
}]
},
{
"function": "CMD",
"type": "text",
"default_value":"SELECT dv.dev_Name as Object_PrimaryID, cast(dv.dev_LastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, ns.Service as Watched_Value1, ns.State as Watched_Value2, 'null' as Watched_Value3, 'null' as Watched_Value4, ns.Extra as Extra FROM (SELECT * FROM Nmap_Scan) ns LEFT JOIN (SELECT dev_Name, dev_MAC, dev_LastIP FROM Devices) dv ON ns.MAC = dv.dev_MAC",
"options": [],
"localized": ["name", "description"],
"name" : [{
"language_code":"en_us",
"string" : "SQL to run"
}],
"description": [{
"language_code":"en_us",
"string" : "This SQL query is used to populate the coresponding UI tables under the Plugins section."
}]
},
{
"function": "RUN_SCHD",
"type": "text",
"default_value":"0 2 * * *",
"options": [],
"localized": ["name", "description"],
"name" : [{
"language_code":"en_us",
"string" : "Schedule"
}],
"description": [{
"language_code":"en_us",
"string" : "Only enabled if you select <code>schedule</code> in the <a href=\"#NMAPSRV_RUN\"><code>NMAPSRV_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
}]
},
{
"function": "RUN_TIMEOUT",
"type": "integer",
"default_value":5,
"options": [],
"localized": ["name", "description"],
"name" : [{
"language_code":"en_us",
"string" : "Run timeout"
},
{
"language_code":"de_de",
"string" : "Wartezeit"
}],
"description": [{
"language_code":"en_us",
"string" : "Maximum time in seconds to wait for the call to finish. If this time is exceeded the script is aborted."
}]
},
{
"function": "WATCH",
"type": "multiselect",
"default_value":["Watched_Value1"],
"options": ["Watched_Value1","Watched_Value2","Watched_Value3","Watched_Value4"],
"localized": ["name", "description"],
"name" :[{
"language_code":"en_us",
"string" : "Watched"
}] ,
"description":[{
"language_code":"en_us",
"string" : "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is service type (e.g.: http, ssh)</li><li><code>Watched_Value2</code> is Status (open or closed)</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>"
}]
},
{
"function": "REPORT_ON",
"type": "multiselect",
"default_value":["new","watched-changed"],
"options": ["new","watched-changed","watched-not-changed"],
"localized": ["name", "description"],
"name" :[{
"language_code":"en_us",
"string" : "Report on"
}] ,
"description":[{
"language_code":"en_us",
"string" : "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
}]
}
]
}

View File

@@ -1,6 +1,7 @@
{ {
"code_name": "website_monitor", "code_name": "website_monitor",
"unique_prefix": "WEBMON", "unique_prefix": "WEBMON",
"data_source": "python-script",
"localized": ["display_name", "description", "icon"], "localized": ["display_name", "description", "icon"],
"display_name" : [{ "display_name" : [{
"language_code":"en_us", "language_code":"en_us",
@@ -192,15 +193,15 @@
"options": [ "options": [
{ {
"equals": "watched-not-changed", "equals": "watched-not-changed",
"replacement": "<i class='fa-solid fa-square-check'></i>" "replacement": "<div style='text-align:center'><i class='fa-solid fa-square-check'></i><div></div>"
}, },
{ {
"equals": "watched-changed", "equals": "watched-changed",
"replacement": "<i class='fa-solid fa-triangle-exclamation'></i>" "replacement": "<div style='text-align:center'><i class='fa-solid fa-triangle-exclamation'></i></div>"
}, },
{ {
"equals": "new", "equals": "new",
"replacement": "<i class='fa-solid fa-circle-plus'></i>" "replacement": "<div style='text-align:center'><i class='fa-solid fa-circle-plus'></i></div>"
} }
], ],
"localized": ["name"], "localized": ["name"],
@@ -276,7 +277,7 @@
"localized": ["name", "description"], "localized": ["name", "description"],
"name" : [{ "name" : [{
"language_code":"en_us", "language_code":"en_us",
"string" : "API endpoint" "string" : "API endpoint (not implemented)"
}], }],
"description": [{ "description": [{
"language_code":"en_us", "language_code":"en_us",
@@ -299,7 +300,7 @@
}], }],
"description": [{ "description": [{
"language_code":"en_us", "language_code":"en_us",
"string" : "Maximum time in seconds to wait for a Website monitor check to finish for any url." "string" : "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted."
}] }]
}, },
{ {
@@ -335,7 +336,7 @@
{ {
"function": "urls_to_check", "function": "urls_to_check",
"type": "list", "type": "list",
"default_value":[], "default_value":["https://google.com", "https://duck.com"],
"options": [], "options": [],
"localized": ["name", "description"], "localized": ["name", "description"],
"name" : [{ "name" : [{