mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
Some checks are pending
docker / docker_dev (push) Waiting to run
This commit is contained in:
28
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
28
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -9,20 +9,6 @@ body:
|
|||||||
options:
|
options:
|
||||||
- label: I have searched the existing open and closed issues
|
- label: I have searched the existing open and closed issues
|
||||||
required: true
|
required: true
|
||||||
- type: checkboxes
|
|
||||||
attributes:
|
|
||||||
label: Am I willing to test this? 🧪
|
|
||||||
description: I rely on the community to test unreleased features. If you are requesting a feature, please be willing to test it within 48h of test request. Otherwise, the feature might be pulled from the code base.
|
|
||||||
options:
|
|
||||||
- label: I will do my best to test this feature on the `netlertx-dev` image when requested within 48h and report bugs to help deliver a great user experience for everyone and not to break existing installations.
|
|
||||||
required: true
|
|
||||||
- type: checkboxes
|
|
||||||
attributes:
|
|
||||||
label: Can I help implement this? 👩💻👨💻
|
|
||||||
description: The maintainer will provide guidance and help. The implementer will read the PR guidelines https://github.com/jokob-sk/NetAlertX/tree/main/docs#-pull-requests-prs
|
|
||||||
options:
|
|
||||||
- label: "Yes"
|
|
||||||
- label: "No"
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Is your feature request related to a problem? Please describe
|
label: Is your feature request related to a problem? Please describe
|
||||||
@@ -50,3 +36,17 @@ body:
|
|||||||
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Am I willing to test this? 🧪
|
||||||
|
description: I rely on the community to test unreleased features. If you are requesting a feature, please be willing to test it within 48h of test request. Otherwise, the feature might be pulled from the code base.
|
||||||
|
options:
|
||||||
|
- label: I will do my best to test this feature on the `netlertx-dev` image when requested within 48h and report bugs to help deliver a great user experience for everyone and not to break existing installations.
|
||||||
|
required: true
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Can I help implement this? 👩💻👨💻
|
||||||
|
description: The maintainer will provide guidance and help. The implementer will read the PR guidelines https://github.com/jokob-sk/NetAlertX/tree/main/docs#-pull-requests-prs
|
||||||
|
options:
|
||||||
|
- label: "Yes"
|
||||||
|
- label: "No"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
FROM alpine:3.20 as builder
|
FROM alpine:3.20 AS builder
|
||||||
|
|
||||||
ARG INSTALL_DIR=/app
|
ARG INSTALL_DIR=/app
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED 1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
# Install build dependencies
|
# Install build dependencies
|
||||||
RUN apk add --no-cache bash python3 python3-dev gcc musl-dev libffi-dev openssl-dev \
|
RUN apk add --no-cache bash python3 python3-dev gcc musl-dev libffi-dev openssl-dev \
|
||||||
@@ -21,7 +21,7 @@ RUN pip install netifaces tplink-omada-client pycryptodome requests paho-mqtt sc
|
|||||||
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
|
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
|
||||||
|
|
||||||
# second stage
|
# second stage
|
||||||
FROM alpine:3.20 as runner
|
FROM alpine:3.20 AS runner
|
||||||
|
|
||||||
ARG INSTALL_DIR=/app
|
ARG INSTALL_DIR=/app
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
FROM debian:bookworm-slim
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
# default UID and GID
|
# default UID and GID
|
||||||
ENV USER=pi USER_ID=1000 USER_GID=1000 PORT=20211
|
ENV USER=pi USER_ID=1000 USER_GID=1000 PORT=20211
|
||||||
#TZ=Europe/London
|
#TZ=Europe/London
|
||||||
|
|
||||||
# Todo, figure out why using a workdir instead of full paths don't work
|
# Todo, figure out why using a workdir instead of full paths don't work
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
version: "3"
|
|
||||||
services:
|
services:
|
||||||
netalertx:
|
netalertx:
|
||||||
privileged: true
|
privileged: true
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"code_name": "mikrotik_scan",
|
"code_name": "mikrotik_scan",
|
||||||
"unique_prefix": "MTSCAN",
|
"unique_prefix": "MTSCAN",
|
||||||
"plugin_type": "other",
|
"plugin_type": "device_scanner",
|
||||||
"execution_order" : "Layer_4",
|
"execution_order" : "Layer_4",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"data_source": "script",
|
"data_source": "script",
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# test script by running:
|
|
||||||
# tbc
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
@@ -40,42 +38,35 @@ pluginName = 'MTSCAN'
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
mylog('verbose', [f'[{pluginName}] In script'])
|
mylog('verbose', [f'[{pluginName}] In script'])
|
||||||
|
|
||||||
mt_host = get_setting_value('MTSCAN_MT_HOST')
|
# init global variables
|
||||||
mt_port = get_setting_value('MTSCAN_MT_PORT')
|
global MT_HOST, MT_PORT, MT_USER, MT_PASS
|
||||||
mt_user = get_setting_value('MTSCAN_MT_USER')
|
|
||||||
mt_password = get_setting_value('MTSCAN_MT_PASS')
|
|
||||||
|
|
||||||
#mylog('verbose', [f'[{pluginName}] Router: {mt_host}:{mt_port} user: {mt_user}, pass: {mt_password}'])
|
|
||||||
# Create a database connection
|
|
||||||
db = DB() # instance of class DB
|
|
||||||
db.open()
|
|
||||||
|
|
||||||
# Initialize the Plugin obj output file
|
# Initialize the Plugin obj output file
|
||||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||||
|
|
||||||
# Create a Device_obj instance
|
# Mikrotik settings
|
||||||
device_handler = Device_obj(db)
|
MT_HOST = get_setting_value('MTSCAN_MT_HOST')
|
||||||
|
MT_PORT = get_setting_value('MTSCAN_MT_PORT')
|
||||||
|
MT_USER = get_setting_value('MTSCAN_MT_USER')
|
||||||
|
MT_PASS = get_setting_value('MTSCAN_MT_PASS')
|
||||||
|
|
||||||
# Retrieve devices
|
plugin_objects = get_entries(plugin_objects)
|
||||||
#unknown_devices = device_handler.getUnknown()
|
|
||||||
#mylog('verbose', [f'[{pluginName}] Unknown devices count: {len(unknown_devices)}'])
|
|
||||||
|
|
||||||
all_devices = device_handler.getAll()
|
plugin_objects.write_result_file()
|
||||||
|
|
||||||
|
mylog('verbose', [f'[{pluginName}] Scan finished, found {len(plugin_objects)} devices'])
|
||||||
|
|
||||||
mylog('verbose', [f'[{pluginName}] all devices count: {len(all_devices)}'])
|
|
||||||
|
|
||||||
device_map = {d['dev_MAC']:d['dev_LastIP'] for d in all_devices}
|
def get_entries(plugin_objects: Plugin_Objects) -> Plugin_Objects:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# connect router
|
# connect router
|
||||||
api = connect(username=mt_user, password=mt_password, host=mt_host, port=mt_port)
|
api = connect(username=MT_USER, password=MT_PASS, host=MT_HOST, port=MT_PORT)
|
||||||
|
|
||||||
# get dhcp leases
|
# get dhcp leases
|
||||||
leases = api('/ip/dhcp-server/lease/print')
|
leases = api('/ip/dhcp-server/lease/print')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for lease in leases:
|
for lease in leases:
|
||||||
lease_id = lease.get('.id')
|
lease_id = lease.get('.id')
|
||||||
@@ -84,56 +75,31 @@ def main():
|
|||||||
host_name = lease.get('host-name')
|
host_name = lease.get('host-name')
|
||||||
comment = lease.get('comment')
|
comment = lease.get('comment')
|
||||||
last_seen = lease.get('last-seen')
|
last_seen = lease.get('last-seen')
|
||||||
|
status = lease.get('status')
|
||||||
|
|
||||||
mylog('verbose', [f"ID: {lease_id}, Address: {address}, MAC Address: {mac_address}, Host Name: {host_name}, Comment: {comment}, Last Seen: {last_seen}"])
|
mylog('verbose', [f"ID: {lease_id}, Address: {address}, MAC Address: {mac_address}, Host Name: {host_name}, Comment: {comment}, Last Seen: {last_seen}, Status: {status}"])
|
||||||
if mac_address in device_map.keys():
|
|
||||||
device_name = host_name
|
if (status == "bound"):
|
||||||
if comment != '':
|
|
||||||
device_name = comment
|
|
||||||
|
|
||||||
plugin_objects.add_object(
|
plugin_objects.add_object(
|
||||||
# "Name-MAC", "LastIP", "IP", "Name","Host","LastSeen","Comment"
|
|
||||||
primaryId = mac_address,
|
primaryId = mac_address,
|
||||||
secondaryId = device_map[mac_address],
|
secondaryId = '',
|
||||||
watched1 = address,
|
watched1 = address,
|
||||||
watched2 = device_name,
|
watched2 = host_name,
|
||||||
watched3 = host_name,
|
watched3 = last_seen,
|
||||||
watched4 = last_seen,
|
watched4 = '',
|
||||||
extra = '',
|
extra = '',
|
||||||
helpVal1 = comment,
|
helpVal1 = comment,
|
||||||
foreignKey = mac_address)
|
foreignKey = mac_address)
|
||||||
|
|
||||||
plugin_objects.write_result_file()
|
|
||||||
except TrapError as e:
|
except TrapError as e:
|
||||||
mylog('error', [f"An error occurred: {e}"])
|
mylog('error', [f"An error occurred: {e}"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
mylog('error', [f"Failed to connect to MikroTik API: {e}"])
|
mylog('error', [f"Failed to connect to MikroTik API: {e}"])
|
||||||
|
|
||||||
|
|
||||||
#for device in unknown_devices:
|
|
||||||
# domain_name, dns_server = execute_nslookup(device['dev_LastIP'], timeout)
|
|
||||||
|
|
||||||
# if domain_name != '':
|
|
||||||
# plugin_objects.add_object(
|
|
||||||
# # "MAC", "IP", "Server", "Name"
|
|
||||||
# primaryId = device['dev_MAC'],
|
|
||||||
# secondaryId = device['dev_LastIP'],
|
|
||||||
# watched1 = dns_server,
|
|
||||||
# watched2 = domain_name,
|
|
||||||
# watched3 = '',
|
|
||||||
# watched4 = '',
|
|
||||||
# extra = '',
|
|
||||||
# foreignKey = device['dev_MAC'])
|
|
||||||
|
|
||||||
#plugin_objects.write_result_file()
|
|
||||||
|
|
||||||
|
|
||||||
mylog('verbose', [f'[{pluginName}] Script finished'])
|
mylog('verbose', [f'[{pluginName}] Script finished'])
|
||||||
|
|
||||||
return 0
|
return plugin_objects
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# BEGIN
|
# BEGIN
|
||||||
|
|||||||
Reference in New Issue
Block a user