Plugins 0.3 - SQL support, UI CSS tweks, Lang fixes
This commit is contained in:
12
.github/workflows/docker_prod.yml
vendored
12
.github/workflows/docker_prod.yml
vendored
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
12
front/plugins/nmap_services/README.md
Executable file
12
front/plugins/nmap_services/README.md
Executable 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.
|
||||||
275
front/plugins/nmap_services/config.json
Executable file
275
front/plugins/nmap_services/config.json
Executable 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."
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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" : [{
|
||||||
|
|||||||
Reference in New Issue
Block a user