diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 73d282a1..719aabc0 100755 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -9,20 +9,6 @@ body: options: - label: I have searched the existing open and closed issues 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 attributes: 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. validations: 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" diff --git a/Dockerfile b/Dockerfile index 48eb5d6f..6a044d0d 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ -FROM alpine:3.20 as builder +FROM alpine:3.20 AS builder ARG INSTALL_DIR=/app -ENV PYTHONUNBUFFERED 1 +ENV PYTHONUNBUFFERED=1 # Install build dependencies 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 {} \;" # second stage -FROM alpine:3.20 as runner +FROM alpine:3.20 AS runner ARG INSTALL_DIR=/app diff --git a/Dockerfile.debian b/Dockerfile.debian index d073b579..25ff50c6 100755 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -1,7 +1,7 @@ FROM debian:bookworm-slim # 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 # Todo, figure out why using a workdir instead of full paths don't work diff --git a/docker-compose.yml b/docker-compose.yml index 8bb12e09..c258192b 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: "3" services: netalertx: privileged: true diff --git a/front/plugins/mikrotik_scan/config.json b/front/plugins/mikrotik_scan/config.json index baca3a15..9805c26c 100755 --- a/front/plugins/mikrotik_scan/config.json +++ b/front/plugins/mikrotik_scan/config.json @@ -1,7 +1,7 @@ { "code_name": "mikrotik_scan", "unique_prefix": "MTSCAN", - "plugin_type": "other", + "plugin_type": "device_scanner", "execution_order" : "Layer_4", "enabled": true, "data_source": "script", diff --git a/front/plugins/mikrotik_scan/mikrotik.py b/front/plugins/mikrotik_scan/mikrotik.py index d8594bf6..1d627dde 100755 --- a/front/plugins/mikrotik_scan/mikrotik.py +++ b/front/plugins/mikrotik_scan/mikrotik.py @@ -1,6 +1,4 @@ #!/usr/bin/env python -# test script by running: -# tbc import os import pathlib @@ -40,42 +38,35 @@ pluginName = 'MTSCAN' def main(): - mylog('verbose', [f'[{pluginName}] In script']) + mylog('verbose', [f'[{pluginName}] In script']) - 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_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() + # init global variables + global MT_HOST, MT_PORT, MT_USER, MT_PASS # Initialize the Plugin obj output file plugin_objects = Plugin_Objects(RESULT_FILE) - # Create a Device_obj instance - device_handler = Device_obj(db) + # Mikrotik settings + 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 - #unknown_devices = device_handler.getUnknown() - #mylog('verbose', [f'[{pluginName}] Unknown devices count: {len(unknown_devices)}']) + plugin_objects = get_entries(plugin_objects) - 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: # 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 leases = api('/ip/dhcp-server/lease/print') - - for lease in leases: lease_id = lease.get('.id') @@ -84,56 +75,31 @@ def main(): host_name = lease.get('host-name') comment = lease.get('comment') 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}"]) - if mac_address in device_map.keys(): - device_name = host_name - if comment != '': - device_name = comment - + 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 (status == "bound"): plugin_objects.add_object( - # "Name-MAC", "LastIP", "IP", "Name","Host","LastSeen","Comment" primaryId = mac_address, - secondaryId = device_map[mac_address], + secondaryId = '', watched1 = address, - watched2 = device_name, - watched3 = host_name, - watched4 = last_seen, + watched2 = host_name, + watched3 = last_seen, + watched4 = '', extra = '', helpVal1 = comment, foreignKey = mac_address) - - plugin_objects.write_result_file() + except TrapError as e: mylog('error', [f"An error occurred: {e}"]) except Exception as 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']) - return 0 + return plugin_objects - - #=============================================================================== # BEGIN