mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
Compare commits
107 Commits
7d57370741
...
v24.7.18
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4453ea59af | ||
|
|
31ecd6ac8c | ||
|
|
8e8493f638 | ||
|
|
adf24cebb6 | ||
|
|
5ac609e68e | ||
|
|
7f0debb04a | ||
|
|
a51571bd70 | ||
|
|
3af1f67956 | ||
|
|
9143b90bdf | ||
|
|
a892b8b5fb | ||
|
|
db621a110e | ||
|
|
4a3598e840 | ||
|
|
a19e268ea7 | ||
|
|
e9319cace3 | ||
|
|
74b2432729 | ||
|
|
d65b07685f | ||
|
|
a8dc4099e8 | ||
|
|
9c368982ce | ||
|
|
662394618b | ||
|
|
147166e46e | ||
|
|
fb8a7432cd | ||
|
|
fa00fa3004 | ||
|
|
294cfe80f2 | ||
|
|
b45e82b2a0 | ||
|
|
bf2ce3262d | ||
|
|
f468903b00 | ||
|
|
d706a156c0 | ||
|
|
71c631d784 | ||
|
|
460d2f4658 | ||
|
|
f502d93854 | ||
|
|
68fb1b7cbb | ||
|
|
942908d074 | ||
|
|
1aeed6b433 | ||
|
|
698876065c | ||
|
|
7e554242c2 | ||
|
|
129ae92141 | ||
|
|
25647023d0 | ||
|
|
fe752192e1 | ||
|
|
0ea0cd5ee0 | ||
|
|
bac78e926d | ||
|
|
d6125ef4e2 | ||
|
|
bf90ee81c7 | ||
|
|
ae74f1f538 | ||
|
|
3ae0daad3c | ||
|
|
8e7e0afb1e | ||
|
|
d7d7306a85 | ||
|
|
4b26044427 | ||
|
|
0a9ae5e9d9 | ||
|
|
ade1d9997f | ||
|
|
578b992c5a | ||
|
|
52b293a662 | ||
|
|
bd52536107 | ||
|
|
9f44c0de01 | ||
|
|
41b5de9292 | ||
|
|
95d5dbcf68 | ||
|
|
0eff7cc3f1 | ||
|
|
f31c55d6c4 | ||
|
|
6049ba00c7 | ||
|
|
8e4bd246df | ||
|
|
07164429d5 | ||
|
|
cac33fde2b | ||
|
|
5f71e9fc92 | ||
|
|
d834708220 | ||
|
|
6ea3d14480 | ||
|
|
0a11ec5379 | ||
|
|
b65c8022d6 | ||
|
|
55440090fe | ||
|
|
75bcf42225 | ||
|
|
6db9cd2f61 | ||
|
|
eff98257d6 | ||
|
|
2f97c8fd55 | ||
|
|
f03f3f33b1 | ||
|
|
457059cae8 | ||
|
|
5afc82f33e | ||
|
|
06e24b4585 | ||
|
|
482902f6e4 | ||
|
|
6e6b99fa46 | ||
|
|
30f4cba3e5 | ||
|
|
e9c0bf151f | ||
|
|
70d117cb6d | ||
|
|
624e30842a | ||
|
|
7c22f209d1 | ||
|
|
760a3c981f | ||
|
|
b86ab576bd | ||
|
|
1b6e806830 | ||
|
|
612ff7c293 | ||
|
|
74fc7ecdbf | ||
|
|
b6451e6e76 | ||
|
|
55e7bed5a8 | ||
|
|
10b6c9836b | ||
|
|
158ff2453b | ||
|
|
6b92d9f862 | ||
|
|
2fb6e8fb12 | ||
|
|
15d16dcd81 | ||
|
|
28a5b6af2a | ||
|
|
651b346a27 | ||
|
|
df90060adf | ||
|
|
d3228b2d55 | ||
|
|
83edfa66d2 | ||
|
|
40c5be3758 | ||
|
|
e2d0914334 | ||
|
|
0b5cf66451 | ||
|
|
974427f392 | ||
|
|
9d0e6a5a5d | ||
|
|
08b163ebe4 | ||
|
|
709408ca2a | ||
|
|
eae93ef6b2 |
4
.github/ISSUE_TEMPLATE/i-have-an-issue.yml
vendored
4
.github/ISSUE_TEMPLATE/i-have-an-issue.yml
vendored
@@ -1,5 +1,5 @@
|
||||
name: Bug Report
|
||||
description: 'When submitting an issue enable debug and have a look at the docs.'
|
||||
description: 'When submitting an issue enable LOG_LEVEL="trace" and have a look at the docs.'
|
||||
labels: ['bug 🐛']
|
||||
body:
|
||||
- type: checkboxes
|
||||
@@ -64,7 +64,7 @@ body:
|
||||
***Generally speaking, all bug reports should have logs provided.***
|
||||
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||
Additionally, any additional info? Screenshots? References? Anything that will give us more context about the issue you are encountering!
|
||||
You can use `tail -100 /app/front/log/app.log` in the container if you have troubles getting to the log files.
|
||||
You can use `tail -100 /app/front/log/app.log` in the container if you have trouble getting to the log files.
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
|
||||
@@ -15,7 +15,7 @@ ENV PATH="/opt/venv/bin:$PATH"
|
||||
COPY . ${INSTALL_DIR}/
|
||||
|
||||
|
||||
RUN pip install tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython \
|
||||
RUN pip install netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython \
|
||||
&& bash -c "find ${INSTALL_DIR} -type d -exec chmod 750 {} \;" \
|
||||
&& bash -c "find ${INSTALL_DIR} -type f -exec chmod 640 {} \;" \
|
||||
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
|
||||
@@ -40,15 +40,20 @@ ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
|
||||
|
||||
RUN apk update --no-cache \
|
||||
&& apk add --no-cache bash zip lsblk gettext-envsubst sudo mtr tzdata s6-overlay \
|
||||
&& apk add --no-cache curl arp-scan iproute2 iproute2-ss nmap nmap-scripts traceroute net-tools net-snmp-tools bind-tools awake ca-certificates \
|
||||
&& apk add --no-cache curl arp-scan iproute2 iproute2-ss nmap nmap-scripts traceroute nbtscan net-tools net-snmp-tools bind-tools awake ca-certificates \
|
||||
&& apk add --no-cache sqlite php83 php83-fpm php83-cgi php83-curl php83-sqlite3 php83-session \
|
||||
&& apk add --no-cache python3 nginx \
|
||||
&& apk add --no-cache dcron \
|
||||
&& ln -s /usr/bin/awake /usr/bin/wakeonlan \
|
||||
&& bash -c "install -d -m 750 -o nginx -g www-data ${INSTALL_DIR} ${INSTALL_DIR}" \
|
||||
&& rm -f /etc/nginx/http.d/default.conf
|
||||
|
||||
COPY --from=builder --chown=nginx:www-data ${INSTALL_DIR}/ ${INSTALL_DIR}/
|
||||
|
||||
# Add crontab file
|
||||
COPY install/crontab /etc/crontabs/root
|
||||
|
||||
# Start all required services
|
||||
RUN ${INSTALL_DIR}/dockerfiles/pre-setup.sh
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=2 \
|
||||
|
||||
@@ -33,7 +33,7 @@ COPY --chmod=775 --chown=${USER_ID}:${USER_GID} . ${INSTALL_DIR}/
|
||||
RUN apt-get install -y \
|
||||
tini snmp ca-certificates curl libwww-perl arp-scan perl apt-utils cron sudo \
|
||||
nginx-light php php-cgi php-fpm php-sqlite3 php-curl sqlite3 dnsutils net-tools php-openssl \
|
||||
python3 python3-dev iproute2 nmap python3-pip zip systemctl usbutils traceroute
|
||||
python3 python3-dev iproute2 nmap python3-pip zip systemctl usbutils traceroute nbtscan
|
||||
|
||||
# Alternate dependencies
|
||||
RUN apt-get install nginx nginx-core mtr php-fpm php8.2-fpm php-cli php8.2 php8.2-sqlite3 -y
|
||||
|
||||
18
README.md
18
README.md
@@ -1,4 +1,4 @@
|
||||
# 💻🔍 Network security scanner & notification framework
|
||||
# 💻🔍 Network scanner & notification framework
|
||||
|
||||
Get visibility of what's going on on your WIFI/LAN network. Schedule scans for devices, port changes and get alerts if unknown devices or changes are found. Write your own [Plugins](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) with auto-generated UI and in-build notification system. Build out and easily maintain your network source of truth (NSoT).
|
||||
|
||||
@@ -18,7 +18,7 @@ Get visibility of what's going on on your WIFI/LAN network. Schedule scans for d
|
||||
![network_setup][network_setup]
|
||||
|
||||
|
||||
Head to [https://netalertx.com/](https://netalertx.com/) for more screenshots.
|
||||
Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and screenshots 📷.
|
||||
|
||||
<details>
|
||||
<summary>📷 Click for more screenshots</summary>
|
||||
@@ -36,13 +36,13 @@ Head to [https://netalertx.com/](https://netalertx.com/) for more screenshots.
|
||||
|
||||
Most of us don't know what's going on on our home network, but we want our family and data to be safe. _Command-line tools_ are great, but the output can be _hard to understand_ and action if you are not a network specialist.
|
||||
|
||||
Net <b>Alert</b><sup>x</sup> gives you peace of mind. _Visualize and immediately report 📬_ what is going on in your network - this is the first step to enhance your _network security 🔐_.
|
||||
Net<b>Alert</b><sup>x</sup> gives you peace of mind. _Visualize and immediately report 📬_ what is going on in your network - this is the first step to enhance your _network security 🔐_.
|
||||
|
||||
Net <b>Alert</b><sup>x</sup> combines several network and other scanning tools 🔍 with notifications 📧 into one user-friendly package 📦.
|
||||
Net<b>Alert</b><sup>x</sup> combines several network and other scanning tools 🔍 with notifications 📧 into one user-friendly package 📦.
|
||||
|
||||
Set up a _kill switch ☠_ for your network via a smart plug with the available [Home Assistant](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HOME_ASSISTANT.md) integration. Implement custom automations with the [CSV device Exports 📤](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/csv_backup), [Webhooks](https://github.com/jokob-sk/NetAlertX/blob/main/docs/WEBHOOK_N8N.md), or [API endpoints](https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md) features.
|
||||
|
||||
Extend the app if you want to create your own scanner [Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) and handle the results and notifications in Net <b>Alert</b><sup>x</sup>.
|
||||
Extend the app if you want to create your own scanner [Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) and handle the results and notifications in Net<b>Alert</b><sup>x</sup>.
|
||||
|
||||
Looking forward to your contributions if you decide to share your work with the community ❤.
|
||||
|
||||
@@ -92,18 +92,20 @@ Thank you to all the wonderful people who are sponsoring this project.
|
||||
<!-- SPONSORS-LIST DO NOT MODIFY BELOW -->
|
||||
| All Sponsors |
|
||||
|---|
|
||||
| [fama-lama](https://github.com/fama-lama) |
|
||||
| [iptvcld](https://github.com/iptvcld) |
|
||||
|
||||
<!-- SPONSORS-LIST DO NOT MODIFY ABOVE -->
|
||||
|
||||
| [](https://github.com/sponsors/jokob-sk) | [](https://www.buymeacoffee.com/jokobsk) | [](https://www.patreon.com/user?u=84385063) |
|
||||
| --- | --- | --- |
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Click for more ways to donate</summary>
|
||||
|
||||
<hr>
|
||||
|
||||
| [](https://github.com/sponsors/jokob-sk) | [](https://www.buymeacoffee.com/jokobsk) | [](https://www.patreon.com/user?u=84385063) |
|
||||
| --- | --- | --- |
|
||||
|
||||
- Bitcoin: `1N8tupjeCK12qRVU2XrV17WvKK7LCawyZM`
|
||||
- Ethereum: `0x6e2749Cb42F4411bc98501406BdcD82244e3f9C7`
|
||||
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
# Generated: 2022-12-30_22-19-40 #
|
||||
# #
|
||||
# Config file for the LAN intruder detection app: #
|
||||
# https://github.com/jokob-sk/NetAlertX #
|
||||
# https://github.com/jokob-sk/NetAlertX #
|
||||
# #
|
||||
#-----------------AUTOGENERATED FILE-----------------#
|
||||
|
||||
# 🔺 Use the Settings UI - only edit when necessary 🔺
|
||||
|
||||
|
||||
# General
|
||||
#---------------------------
|
||||
# Scan using interface eth0
|
||||
@@ -19,15 +18,23 @@
|
||||
# SCAN_SUBNETS = [ '192.168.1.0/24 --interface=eth1', '192.168.1.0/24 --interface=eth0' ]
|
||||
|
||||
SCAN_SUBNETS=['192.168.1.0/24 --interface=eth1']
|
||||
|
||||
TIMEZONE='Europe/Berlin'
|
||||
LOADED_PLUGINS = ['ARPSCAN','CSVBCKP','DBCLNP', 'INTRNT','MAINT','NEWDEV','NSLOOKUP','NTFPRCS', 'PHOLUS','SETPWD','SMTP', 'SYNC', 'VNDRPDT', 'WORKFLOWS']
|
||||
|
||||
DAYS_TO_KEEP_EVENTS=90
|
||||
# Used for generating links in emails. Make sure not to add a trailing slash!
|
||||
REPORT_DASHBOARD_URL='http://netalertx'
|
||||
|
||||
# Make sure at least these scanners are enabled for new installs, other defaults are taken from the config.json
|
||||
INTRNT_RUN='schedule'
|
||||
ARPSCAN_RUN='schedule'
|
||||
PHOLUS_RUN='on_new_device'
|
||||
NSLOOKUP_RUN='before_name_updates'
|
||||
|
||||
# Email
|
||||
#---------------------------
|
||||
# Email
|
||||
#-------------------------------------
|
||||
# (add SMTP to LOADED_PLUGINS to load)
|
||||
#-------------------------------------
|
||||
SMTP_RUN='disabled' # use 'on_notification' to enable
|
||||
SMTP_SERVER='smtp.gmail.com'
|
||||
SMTP_PORT=587
|
||||
@@ -39,8 +46,10 @@ SMTP_PASS='password'
|
||||
SMTP_SKIP_TLS=False
|
||||
|
||||
|
||||
# Webhooks
|
||||
#---------------------------
|
||||
# Webhook
|
||||
#-------------------------------------
|
||||
# (add WEBHOOK to LOADED_PLUGINS to load)
|
||||
#-------------------------------------
|
||||
WEBHOOK_RUN='disabled' # use 'on_notification' to enable
|
||||
WEBHOOK_URL='http://n8n.local:5555/webhook-test/aaaaaaaa-aaaa-aaaa-aaaaa-aaaaaaaaaaaa'
|
||||
WEBHOOK_PAYLOAD='json' # webhook payload data format for the "body > attachements > text" attribute
|
||||
@@ -50,15 +59,19 @@ WEBHOOK_PAYLOAD='json' # webhook payload data format for the "bo
|
||||
WEBHOOK_REQUEST_METHOD='GET'
|
||||
|
||||
|
||||
# Apprise
|
||||
#---------------------------
|
||||
# Apprise
|
||||
#-------------------------------------
|
||||
# (add APPRISE to LOADED_PLUGINS to load)
|
||||
#-------------------------------------
|
||||
APPRISE_RUN='disabled' # use 'on_notification' to enable
|
||||
APPRISE_HOST='http://localhost:8000/notify'
|
||||
APPRISE_URL='mailto://smtp-relay.sendinblue.com:587?from=user@gmail.com&name=apprise&user=user@gmail.com&pass=password&to=user@gmail.com'
|
||||
|
||||
|
||||
# NTFY
|
||||
#---------------------------
|
||||
#-------------------------------------
|
||||
# (add NTFY to LOADED_PLUGINS to load)
|
||||
#-------------------------------------
|
||||
NTFY_RUN='disabled' # use 'on_notification' to enable
|
||||
NTFY_HOST='https://ntfy.sh'
|
||||
NTFY_TOPIC='replace_my_secure_topicname_91h889f28'
|
||||
@@ -66,14 +79,18 @@ NTFY_USER='user'
|
||||
NTFY_PASSWORD='passw0rd'
|
||||
|
||||
|
||||
# PUSHSAFER
|
||||
#---------------------------
|
||||
# PUSHSAFER
|
||||
#-------------------------------------
|
||||
# (add PUSHSAFER to LOADED_PLUGINS to load)
|
||||
#-------------------------------------
|
||||
PUSHSAFER_RUN='disabled' # use 'on_notification' to enable
|
||||
PUSHSAFER_TOKEN='ApiKey'
|
||||
|
||||
|
||||
# MQTT
|
||||
#---------------------------
|
||||
# MQTT
|
||||
#-------------------------------------
|
||||
# (add MQTT to LOADED_PLUGINS to load)
|
||||
#-------------------------------------
|
||||
MQTT_RUN='disabled' # use 'on_notification' to enable
|
||||
MQTT_BROKER='192.168.1.2'
|
||||
MQTT_PORT=1883
|
||||
|
||||
13
back/cron_script.sh
Executable file
13
back/cron_script.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
export INSTALL_DIR=/app
|
||||
|
||||
LOG_FILE="${INSTALL_DIR}/front/log/execution_queue.log"
|
||||
|
||||
# Check if there are any entries with cron_restart_backend
|
||||
if grep -q "cron_restart_backend" "$LOG_FILE"; then
|
||||
# Kill all python processes and restart the server
|
||||
pkill -f "python " && (python ${INSTALL_DIR}/server > /dev/null 2>&1 &) && echo 'done'
|
||||
|
||||
# Remove all lines containing cron_restart_backend from the log file
|
||||
sed -i '/cron_restart_backend/d' "$LOG_FILE"
|
||||
fi
|
||||
@@ -4,7 +4,7 @@
|
||||

|
||||
[](https://github.com/sponsors/jokob-sk)
|
||||
|
||||
# NetAlertX 💻🔍 Network security scanner & notification framework
|
||||
# NetAlertX 💻🔍 Network scanner & notification framework
|
||||
|
||||
| 🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/netalertx) | 📑 [Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) |🆕 [Release notes](https://github.com/jokob-sk/NetAlertX/releases) | 📚 [All Docs](https://github.com/jokob-sk/NetAlertX/tree/main/docs) |
|
||||
|----------------------|----------------------| ----------------------| ----------------------|
|
||||
@@ -13,6 +13,8 @@
|
||||
<img src="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" width="1000px" />
|
||||
</a>
|
||||
|
||||
Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and screenshots 📷.
|
||||
|
||||
> [!NOTE]
|
||||
> There is also an experimental 🧪 [bare-metal install](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HW_INSTALL.md) method available.
|
||||
|
||||
@@ -81,16 +83,17 @@ These are the most important settings to get at least some output in your Device
|
||||
|
||||
#### 🧭 Community guides
|
||||
|
||||
Use the official installation guides at first and use community content as suplementary material. Open an issue if you'd like to add your link to the list 🙏
|
||||
Use the official installation guides at first and use community content as supplementary material. Open an issue if you'd like to add your link to the list 🙏
|
||||
|
||||
- 📄 [How to Install Pi.Alert on Your Synology NAS - Marius hosting (English)](https://mariushosting.com/how-to-install-pi-alert-on-your-synology-nas/) (Updated frequently)
|
||||
- 📄 [Using the PiAlert Network Security Scanner on a Raspberry Pi - PiMyLifeUp (English)](https://pimylifeup.com/raspberry-pi-pialert/)
|
||||
- ▶ [How to Setup Pi.Alert on Your Synology NAS - Digital Aloha (English)](https://www.youtube.com/watch?v=M4YhpuRFaUg)
|
||||
- ▶ [Home Lab Network Monitoring - Scotti-BYTE Enterprise Consulting Services](https://www.youtube.com/watch?v=0DryhzrQSJA) (July 2024)
|
||||
- 📄 [How to Install NetAlertX on Your Synology NAS - Marius hosting](https://mariushosting.com/how-to-install-pi-alert-on-your-synology-nas/) (Updated frequently)
|
||||
- 📄 [Using the PiAlert Network Security Scanner on a Raspberry Pi - PiMyLifeUp](https://pimylifeup.com/raspberry-pi-pialert/)
|
||||
- ▶ [How to Setup Pi.Alert on Your Synology NAS - Digital Aloha](https://www.youtube.com/watch?v=M4YhpuRFaUg)
|
||||
- 📄 [시놀/헤놀에서 네트워크 스캐너 Pi.Alert Docker로 설치 및 사용하기 (Korean)](https://blog.dalso.org/article/%EC%8B%9C%EB%86%80-%ED%97%A4%EB%86%80%EC%97%90%EC%84%9C-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%8A%A4%EC%BA%90%EB%84%88-pi-alert-docker%EB%A1%9C-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9) (July 2023)
|
||||
- 📄 [网络入侵探测器Pi.Alert (Chinese)](https://codeantenna.com/a/VgUvIAjZ7J) (May 2023)
|
||||
- ▶ [Pi.Alert auf Synology & Docker by - Jürgen Barth (German)](https://www.youtube.com/watch?v=-ouvA2UNu-A) (March 2023)
|
||||
- ▶ [Top Docker Container for Home Server Security - VirtualizationHowto (English)](https://www.youtube.com/watch?v=tY-w-enLF6Q) (March 2023)
|
||||
- ▶ [Pi.Alert or WatchYourLAN can alert you to unknown devices appearing on your WiFi or LAN network - Danie van der Merwe (English)](https://www.youtube.com/watch?v=v6an9QG2xF0) (November 2022)
|
||||
- ▶ [Top Docker Container for Home Server Security - VirtualizationHowto](https://www.youtube.com/watch?v=tY-w-enLF6Q) (March 2023)
|
||||
- ▶ [Pi.Alert or WatchYourLAN can alert you to unknown devices appearing on your WiFi or LAN network - Danie van der Merwe](https://www.youtube.com/watch?v=v6an9QG2xF0) (November 2022)
|
||||
|
||||
> Ordered by last update time.
|
||||
|
||||
|
||||
@@ -38,4 +38,6 @@ touch /etc/s6-overlay/s6-rc.d/user/contents.d/{SetupOneshot,php-fpm,nginx,$APP_N
|
||||
touch /etc/s6-overlay/s6-rc.d/nginx/dependencies.d/php-fpm
|
||||
touch /etc/s6-overlay/s6-rc.d/$APP_NAME/dependencies.d/nginx
|
||||
|
||||
|
||||
|
||||
rm -f $0
|
||||
|
||||
@@ -109,6 +109,10 @@ if [ ! -f "${INSTALL_DIR}/front/buildtimestamp.txt" ]; then
|
||||
chown nginx:www-data "${INSTALL_DIR}/front/buildtimestamp.txt"
|
||||
fi
|
||||
|
||||
# Start crond service in the background
|
||||
echo "[INSTALL] Starting crond service..."
|
||||
crond -f -d 8 > /dev/null 2>&1 &
|
||||
|
||||
echo -e "
|
||||
[ENV] PATH is ${PATH}
|
||||
[ENV] PORT is ${PORT}
|
||||
|
||||
@@ -6,7 +6,7 @@ Please follow tips 1 - 4 to get a more detailed error.
|
||||
|
||||
When debugging an issue always set the highest log level:
|
||||
|
||||
`LOG_LEVEL='debug'`
|
||||
`LOG_LEVEL='trace'`
|
||||
|
||||
|
||||
## 2. Surfacing errors when container restarts 🔁
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
## 🌟 Create a custom plugin: Overview
|
||||
|
||||
| ![Screen 1][screen1] | ![Screen 2][screen2] | ![Screen 3][screen3] |
|
||||
|----------------------|----------------------| ----------------------|
|
||||
| ![Screen 4][screen4] | ![Screen 5][screen5] |
|
||||
|
||||
NetAlertX comes with a plugin system to feed events from third-party scripts into the UI and then send notifications, if desired. The highlighted core functionality this plugin system supports, is:
|
||||
|
||||
* dynamic creation of a simple UI to interact with the discovered objects,
|
||||
@@ -12,7 +8,19 @@ NetAlertX comes with a plugin system to feed events from third-party scripts int
|
||||
* different column types for reported values to e.g. link back to a device
|
||||
* import objects into existing NetAlertX database tables
|
||||
|
||||
> (Currently, update/overwriting of existing objects is not supported.)
|
||||
> (Currently, update/overwriting of existing objects is only supported for devices via the `CurrentScan` table.)
|
||||
|
||||
### 🎥 Watch the video:
|
||||
|
||||
[](https://youtu.be/cdbxlwiWhv8)
|
||||
|
||||
### 📸 Screenshots
|
||||
|
||||
| ![Screen 1][screen1] | ![Screen 2][screen2] | ![Screen 3][screen3] |
|
||||
|----------------------|----------------------| ----------------------|
|
||||
| ![Screen 4][screen4] | ![Screen 5][screen5] |
|
||||
|
||||
## Use cases
|
||||
|
||||
Example use cases for plugins could be:
|
||||
|
||||
@@ -83,6 +91,16 @@ More on specifics below.
|
||||
|
||||
The `config.json` file is the manifest of the plugin. It contains mainly settings definitions and the mapping of Plugin objects to NetAlertX objects.
|
||||
|
||||
## Execution order
|
||||
|
||||
The execution order is used to specify wwhen a plugin is executed. This is useful if a plugin has access and surfaces more information than others. If a device is detected by 2 plugins and inserted into the `CurrentScan` table, the plugin with the higher priority (e.g.: `Level_0` is a higher priority than `Level_1`) will insert it's values first. These values (devices) will be then prioritized over any values inserted later.
|
||||
|
||||
```json
|
||||
{
|
||||
"execution_order" : "Layer_0"
|
||||
}
|
||||
```
|
||||
|
||||
## Supported data sources
|
||||
|
||||
Currently, these data sources are supported (valid `data_source` value).
|
||||
@@ -183,7 +201,7 @@ This SQL query is executed on the `app.db` SQLite database file.
|
||||
> ```json
|
||||
> {
|
||||
> "function": "CMD",
|
||||
> "type": "text",
|
||||
> "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]},
|
||||
> "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"],
|
||||
@@ -214,7 +232,7 @@ For example for `PIHOLE` (`"unique_prefix": "PIHOLE"`) it is `EXTERNAL_PIHOLE.`.
|
||||
> ...
|
||||
>{
|
||||
> "function": "DB_PATH",
|
||||
> "type": "readonly",
|
||||
> "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]},
|
||||
> "default_value":"/etc/pihole/pihole-FTL.db",
|
||||
> "options": [],
|
||||
> "localized": ["name", "description"],
|
||||
@@ -239,7 +257,7 @@ The actual SQL query you want to execute is then stored as a `CMD` setting, simi
|
||||
>```json
|
||||
>{
|
||||
> "function": "CMD",
|
||||
> "type": "text",
|
||||
> "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]},
|
||||
> "default_value":"SELECT hwaddr as Object_PrimaryID, cast('http://' || (SELECT ip FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC, ip LIMIT 1) as VARCHAR(100)) || ':' || cast( SUBSTR((SELECT name FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC, ip LIMIT 1), 0, INSTR((SELECT name FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC, ip LIMIT 1), '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, macVendor as Watched_Value1, lastQuery as Watched_Value2, (SELECT name FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC, ip LIMIT 1) as Watched_Value3, 'null' as Watched_Value4, '' as Extra, hwaddr as ForeignKey FROM EXTERNAL_PIHOLE.network WHERE hwaddr NOT LIKE 'ip-%' AND hwaddr <> '00:00:00:00:00:00'; ",
|
||||
> "options": [],
|
||||
> "localized": ["name", "description"],
|
||||
@@ -417,7 +435,7 @@ The `params` array in the `config.json` is used to enable the user to change the
|
||||
```json
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]},
|
||||
"default_value":"python3 /app/front/plugins/website_monitor/script.py urls={urls}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -500,18 +518,7 @@ Required attributes are:
|
||||
| -------- | ----------- |
|
||||
| `"function"` | Specifies the function the setting drives or a simple unique code name. See Supported settings function values for options. |
|
||||
| `"type"` | Specifies the form control used for the setting displayed in the Settings page and what values are accepted. Supported options include: |
|
||||
| | - `text` |
|
||||
| | - `integer` |
|
||||
| | - `boolean` |
|
||||
| | - `password` |
|
||||
| | - `readonly` |
|
||||
| | - `integer.select` |
|
||||
| | - `text.select` |
|
||||
| | - `text.multiselect` |
|
||||
| | - `list` |
|
||||
| | - `list.select` |
|
||||
| | - `integer.checkbox` |
|
||||
| | - `text.template` |
|
||||
| | - `{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{"type":"password"}] ,"transformers": ["sha256"]}]}` |
|
||||
| `"localized"` | A list of properties on the current JSON level that need to be localized. |
|
||||
| `"name"` | Displayed on the Settings page. An array of localized strings. See Localized strings below. |
|
||||
| `"description"` | Displayed on the Settings page. An array of localized strings. See Localized strings below. |
|
||||
@@ -554,7 +561,7 @@ You can have any `"function": "my_custom_name"` custom name, however, the ones l
|
||||
> ```json
|
||||
> {
|
||||
> "function": "RUN",
|
||||
> "type": "text.select",
|
||||
> "type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]},
|
||||
> "default_value":"disabled",
|
||||
> "options": ["disabled", "once", "schedule", "always_after_scan", "on_new_device"],
|
||||
> "localized": ["name", "description"],
|
||||
@@ -619,7 +626,7 @@ The UI will adjust how columns are displayed in the UI based on the resolvers de
|
||||
|
||||
```json
|
||||
"function": "dev_DeviceType",
|
||||
"type": "text.select",
|
||||
"type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]},
|
||||
"maxLength": 30,
|
||||
"default_value": "",
|
||||
"options": ["{value}"],
|
||||
|
||||
@@ -19,7 +19,6 @@ When opening an issue please:
|
||||
|
||||
Check for browser console (F12 browser dev console) errors + check different browsers.
|
||||
|
||||
|
||||
## 3. Clear the app cache and cached JavaScript files
|
||||
|
||||
Refresh the browser cache (usually shoft + refresh), try a private window, or different browsers. Please also refresh the app cache by clicking the 🔃 (reload) button in the header of the application.
|
||||
@@ -28,11 +27,15 @@ Refresh the browser cache (usually shoft + refresh), try a private window, or di
|
||||
|
||||
If you have any reverse proxy or similar, try disabling it.
|
||||
|
||||
## 5. Post your docker start details
|
||||
## 5. Disable your firewall
|
||||
|
||||
If you are using a firewall, try to temporarily disabling it.
|
||||
|
||||
## 6. Post your docker start details
|
||||
|
||||
If you haven't, post your docker compose/run command.
|
||||
|
||||
## 6. Check for errors in your PHP/NGINX error logs
|
||||
## 7. Check for errors in your PHP/NGINX error logs
|
||||
|
||||
In the container execute:
|
||||
|
||||
@@ -40,8 +43,7 @@ In the container execute:
|
||||
|
||||
`cat /app/front/log/app.php_errors.log`
|
||||
|
||||
|
||||
## 7. Make sure permissions are correct
|
||||
## 8. Make sure permissions are correct
|
||||
|
||||
> [!TIP]
|
||||
> You can try to start the container without mapping the `/app/config` and `/app/db` dirs and if the UI shows up then the issue is most likely related to your file system permissions or file ownership.
|
||||
|
||||
BIN
docs/img/YouTube_thumbnail.png
Executable file
BIN
docs/img/YouTube_thumbnail.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 183 KiB |
@@ -25,13 +25,33 @@
|
||||
color:white;
|
||||
background-color: black;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: .85em;
|
||||
|
||||
}
|
||||
.logs-row textarea
|
||||
{
|
||||
width: 100%;
|
||||
}
|
||||
#tab_Logging .actions{
|
||||
display:contents;
|
||||
position: relative;
|
||||
padding: 0.4em
|
||||
|
||||
}
|
||||
|
||||
#tab_Logging .actions .toggle{
|
||||
|
||||
margin: 0.5em;
|
||||
height: 3em;
|
||||
}
|
||||
|
||||
.logs-row .button{
|
||||
margin: 2px;
|
||||
}
|
||||
.logs-row
|
||||
{
|
||||
align-content: center;
|
||||
width: 100%;
|
||||
display: grid;
|
||||
margin: 5px;
|
||||
}
|
||||
.logs-size
|
||||
@@ -48,12 +68,11 @@
|
||||
}
|
||||
.logs-small
|
||||
{
|
||||
height: 100px;
|
||||
height: 150px;
|
||||
}
|
||||
.log-file
|
||||
{
|
||||
width: 145px;
|
||||
display: inline-grid;
|
||||
|
||||
font-size: 20px;
|
||||
}
|
||||
.log-purge
|
||||
@@ -213,9 +232,15 @@
|
||||
.content-wrapper,
|
||||
.right-side,
|
||||
.main-footer {
|
||||
margin-left: 150px;
|
||||
margin-left: 150px;
|
||||
}
|
||||
|
||||
#settingsPage
|
||||
{
|
||||
display: grid;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.main-header .logo {
|
||||
width: 100%;
|
||||
@@ -230,6 +255,15 @@
|
||||
.main-footer {
|
||||
margin-left: 0px;
|
||||
}
|
||||
.fixed .content-wrapper, .fixed .right-side {
|
||||
padding-top: 50px;
|
||||
}
|
||||
.main-sidebar {
|
||||
padding-top: 50px;
|
||||
}
|
||||
.content-header {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-open .content-wrapper,
|
||||
@@ -1111,7 +1145,7 @@ input[readonly] {
|
||||
color: white;
|
||||
}
|
||||
|
||||
#dropdownIcon li svg, #dropdownIcon li i{
|
||||
#dropdownIcon li svg, #dropdownIcon li i, .dropdownIcon li svg, .dropdownIcon li i, .icon-maxsize svg, .icon-maxsize i{
|
||||
height: 1.5em !important;
|
||||
}
|
||||
|
||||
@@ -1246,6 +1280,21 @@ input[readonly] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.networkNodeTabHeaders
|
||||
{
|
||||
max-width: 200px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
text-wrap: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
|
||||
.networkNodeTabHeaders .node-name
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* PLUGINS page */
|
||||
|
||||
@@ -824,20 +824,20 @@ function initializeCombos () {
|
||||
initializeCombo ( '#dropdownDevices', 'getDevices', 'txtFromDevice', false);
|
||||
|
||||
// Initiate dropdown
|
||||
// function initSettingDropdown(settingKey, // Identifier for the setting
|
||||
// valuesArray, // Array of values to be pre-selected in the dropdown
|
||||
// targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
|
||||
// callbackToGenerateEntries, // Callback function to generate entries based on options
|
||||
// targetField, // Target field or element where selected value should be applied or updated
|
||||
// nameTransformer) // callback to transform name
|
||||
// generateSetOptions(settingKey, // Identifier for the setting
|
||||
// valuesArray, // Array of values to be pre-selected in the dropdown
|
||||
// targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
|
||||
// callbackToGenerateEntries, // Callback function to generate entries based on options
|
||||
// targetField, // Target field or element where selected value should be applied or updated
|
||||
// nameTransformer) // callback to transform name
|
||||
|
||||
|
||||
initSettingDropdown("NEWDEV_dev_Icon", [], "dropdownIcon_tmp", genListWithInputSet, 'txtIcon', atob )
|
||||
initSettingDropdown("NEWDEV_dev_DeviceType", [], "dropdownDeviceType_tmp", genListWithInputSet, 'txtDeviceType' )
|
||||
initSettingDropdown("NEWDEV_dev_Owner", [], "dropdownOwner_tmp", genListWithInputSet, 'txtOwner' )
|
||||
initSettingDropdown("NEWDEV_dev_Group", [], "dropdownGroup_tmp", genListWithInputSet, 'txtGroup' )
|
||||
initSettingDropdown("NEWDEV_dev_Location", [], "dropdownLocation_tmp", genListWithInputSet, 'txtLocation' )
|
||||
initSettingDropdown("NEWDEV_dev_Network_Node_MAC_ADDR", [], "dropdownNetworkNodeMac_tmp", genListWithInputSet, 'txtNetworkNodeMac' )
|
||||
generateOptionsOrSetOptions("NEWDEV_dev_Icon", [], "dropdownIcon_tmp", genListWithInputSet, 'txtIcon', ["base64"])
|
||||
generateOptionsOrSetOptions("NEWDEV_dev_DeviceType", [], "dropdownDeviceType_tmp", genListWithInputSet, 'txtDeviceType' )
|
||||
generateOptionsOrSetOptions("NEWDEV_dev_Owner", [], "dropdownOwner_tmp", genListWithInputSet, 'txtOwner' )
|
||||
generateOptionsOrSetOptions("NEWDEV_dev_Group", [], "dropdownGroup_tmp", genListWithInputSet, 'txtGroup' )
|
||||
generateOptionsOrSetOptions("NEWDEV_dev_Location", [], "dropdownLocation_tmp", genListWithInputSet, 'txtLocation' )
|
||||
generateOptionsOrSetOptions("NEWDEV_dev_Network_Node_MAC_ADDR", [], "dropdownNetworkNodeMac_tmp", genListWithInputSet, 'txtNetworkNodeMac' )
|
||||
|
||||
// Initialize static combos
|
||||
initializeComboSkipRepeated ();
|
||||
|
||||
@@ -336,6 +336,7 @@ function getDevicesTotals(devicesData) {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Render the info boxes/tiles on top
|
||||
function renderInfoboxes(customData) {
|
||||
$.ajax({
|
||||
url: 'php/components/tile_cards.php', // PHP script URL
|
||||
|
||||
@@ -147,19 +147,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion_det" href="#collapse301">
|
||||
<?= lang('HelpFAQ_Cat_Detail_301_head_a');?> "<?= lang('DevDetail_EveandAl_ScanCycle');?>" <?= lang('HelpFAQ_Cat_Detail_301_head_b');?></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse301" class="panel-collapse collapse" style="font-size: 16px;">
|
||||
<div class="panel-body">
|
||||
<?= lang('HelpFAQ_Cat_Detail_301_text');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
|
||||
@@ -124,8 +124,10 @@ function cacheSettings()
|
||||
settingsData.forEach((set) => {
|
||||
|
||||
resolvedOptions = createArray(set.Options)
|
||||
resolvedOptionsOld = resolvedOptions
|
||||
setPlugObj = {};
|
||||
options_params = [];
|
||||
resolved = ""
|
||||
|
||||
// proceed only if first option item contains something to resolve
|
||||
if( !set.Code_Name.includes("__metadata") &&
|
||||
@@ -158,7 +160,7 @@ function cacheSettings()
|
||||
}
|
||||
}
|
||||
|
||||
setCache(`pia_set_${set.Code_Name}`, set.Value)
|
||||
setCache(`pia_set_${set.Code_Name}`, set.Value)
|
||||
setCache(`pia_set_opt_${set.Code_Name}`, resolvedOptions)
|
||||
});
|
||||
}).then(() => handleSuccess('cacheSettings', resolve())).catch(() => handleFailure('cacheSettings', reject("cacheSettings already completed"))); // handle AJAX synchronization
|
||||
@@ -179,6 +181,7 @@ function getSettingOptions (key) {
|
||||
if (result == "")
|
||||
{
|
||||
console.log(`Setting options with key "${key}" not found`)
|
||||
result = []
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -743,10 +746,14 @@ function isRandomMAC(mac)
|
||||
// ---------------------------------------------------------
|
||||
// Generate an array object from a string representation of an array
|
||||
function createArray(input) {
|
||||
// Empty array
|
||||
if (input === '[]') {
|
||||
return [];
|
||||
// Is already array, return
|
||||
if (Array.isArray(input)) {
|
||||
return input;
|
||||
}
|
||||
// Empty array
|
||||
if (input === '[]' || input === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Regex pattern for brackets
|
||||
const patternBrackets = /(^\s*\[)|(\]\s*$)/g;
|
||||
@@ -945,7 +952,8 @@ function updateApi()
|
||||
{
|
||||
|
||||
// value has to be in format event|param. e.g. run|ARPSCAN
|
||||
action = `update_api|devices,appevents`
|
||||
action = `${getGuid()}|update_api|devices,appevents`
|
||||
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
|
||||
@@ -2,51 +2,108 @@
|
||||
// General utilities to interact with the database
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// // Call to render lists
|
||||
// renderList(
|
||||
// options,
|
||||
// callbackToGenerateEntries,
|
||||
// valuesArray,
|
||||
// placeholder,
|
||||
// targetField,
|
||||
// transformers
|
||||
// );
|
||||
|
||||
// --------------------------------------------------
|
||||
// Read data and place intotarget location, callback processies the results
|
||||
function readData(sqlQuery, processDataCallback, valuesArray, targetLocation, targetField, nameTransformer) {
|
||||
var apiUrl = `php/server/dbHelper.php?action=read&rawSql=${encodeURIComponent(sqlQuery)}`;
|
||||
$.get(apiUrl, function(data) {
|
||||
// Process the JSON data using the provided callback function
|
||||
function renderList(
|
||||
options,
|
||||
processDataCallback,
|
||||
valuesArray,
|
||||
placeholder,
|
||||
targetField,
|
||||
transformers
|
||||
) {
|
||||
// Check if there are options provided
|
||||
if (options.length > 0) {
|
||||
// Determine if the first option's name is an SQL query
|
||||
const sqlQuery = isSQLQuery(options[0].name) ? options[0].name : "";
|
||||
|
||||
data = JSON.parse(data)
|
||||
// If there is an SQL query, fetch additional options
|
||||
if (sqlQuery) {
|
||||
// remove first item containing the SQL query
|
||||
options.shift();
|
||||
|
||||
var htmlResult = processDataCallback(data, valuesArray, targetField, nameTransformer);
|
||||
const apiUrl = `php/server/dbHelper.php?action=read&rawSql=${encodeURIComponent(sqlQuery)}`;
|
||||
|
||||
// Place the resulting HTML into the specified placeholder div
|
||||
$("#" + targetLocation).replaceWith(htmlResult);
|
||||
});
|
||||
$.get(apiUrl, function (sqlOptionsData) {
|
||||
|
||||
// Parse the returned SQL data
|
||||
const sqlOption = JSON.parse(sqlOptionsData);
|
||||
|
||||
// Concatenate options from SQL query with the supplied options
|
||||
options = options.concat(sqlOption);
|
||||
|
||||
|
||||
// Process the combined options
|
||||
setTimeout(() => {
|
||||
processDataCallback(
|
||||
options,
|
||||
valuesArray,
|
||||
targetField,
|
||||
transformers,
|
||||
placeholder
|
||||
);
|
||||
}, 1);
|
||||
});
|
||||
} else {
|
||||
// No SQL query, directly process the supplied options
|
||||
setTimeout(() => {
|
||||
processDataCallback(
|
||||
options,
|
||||
valuesArray,
|
||||
targetField,
|
||||
transformers,
|
||||
placeholder
|
||||
);
|
||||
}, 1);
|
||||
}
|
||||
} else {
|
||||
// No options provided, directly process with empty options
|
||||
setTimeout(() => {
|
||||
processDataCallback(
|
||||
options,
|
||||
valuesArray,
|
||||
targetField,
|
||||
transformers,
|
||||
placeholder
|
||||
);
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
// Check if database is locked
|
||||
function checkDbLock() {
|
||||
$.ajax({
|
||||
url: 'log/db_is_locked.log', // Replace with the actual path to your PHP file
|
||||
type: 'GET',
|
||||
|
||||
success: function(response) {
|
||||
// console.log(response);
|
||||
if (response == 0) {
|
||||
// console.log('Database is not locked');
|
||||
$(".header-status-locked-db").hide()
|
||||
|
||||
} else {
|
||||
console.log('🟥 Database is locked:');
|
||||
console.log(response);
|
||||
$(".header-status-locked-db").show()
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
console.log('🟥 Error checking database lock status');
|
||||
$(".header-status-locked-db").show()
|
||||
}
|
||||
});
|
||||
$.ajax({
|
||||
url: "log/db_is_locked.log", // Replace with the actual path to your PHP file
|
||||
type: "GET",
|
||||
|
||||
success: function (response) {
|
||||
console.log(response);
|
||||
if (response == 0) {
|
||||
// console.log('Database is not locked');
|
||||
$(".header-status-locked-db").hide();
|
||||
} else {
|
||||
console.log("🟥 Database is locked:");
|
||||
console.log(response);
|
||||
$(".header-status-locked-db").show();
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
console.log("🟥 Error checking database lock status");
|
||||
$(".header-status-locked-db").show();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
setInterval(checkDbLock(), 1000);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -337,7 +337,7 @@ const phpEndpoint = 'php/server/utilNotification.php';
|
||||
|
||||
// --------------------------------------------------
|
||||
// Write a notification
|
||||
function writeNotification(content, level) {
|
||||
function write_notification(content, level) {
|
||||
|
||||
$.ajax({
|
||||
url: phpEndpoint, // Change this to the path of your PHP script
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -78,42 +78,50 @@ function initDeviceSelectors() {
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Initiate dropdown
|
||||
function initSettingDropdown(settingKey, // Identifier for the setting
|
||||
valuesArray, // Array of values to be pre-selected in the dropdown
|
||||
targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
|
||||
callbackToGenerateEntries, // Callback function to generate entries based on options
|
||||
targetField, // Target field or element where selected value should be applied or updated
|
||||
nameTransformer) // callback to transform the name (e.g. base64)
|
||||
{
|
||||
// // -----------------------------------------------------------------------------
|
||||
// // (ASYNC) Initiate dropdown
|
||||
// function generateSetOptions(settingKey, // Identifier for the setting
|
||||
// valuesArray, // Array of values to be pre-selected in the dropdown
|
||||
// targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
|
||||
// callbackToGenerateEntries, // Callback function to generate entries based on options
|
||||
// targetField, // Target field or element where selected value should be applied or updated
|
||||
// nameTransformer) // callback to transform the name (e.g. base64)
|
||||
// {
|
||||
|
||||
var optionsHtml = ""
|
||||
// var optionsHtml = ""
|
||||
|
||||
// NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
|
||||
optionsArray = createArray(getSettingOptions(settingKey))
|
||||
// // NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
|
||||
// optionsArray = createArray(getSettingOptions(settingKey))
|
||||
|
||||
// check if the result is a SQL query
|
||||
if(isSQLQuery(optionsArray[0]))
|
||||
{
|
||||
readData(optionsArray[0], callbackToGenerateEntries, valuesArray, targetLocation, targetField, nameTransformer);
|
||||
|
||||
} else // this should be already an array, e.g. from a setting or pre-defined
|
||||
{
|
||||
optionsArray.forEach(option => {
|
||||
let selected = valuesArray.includes(option) ? 'selected' : '';
|
||||
optionsHtml += `<option value="${option}" ${selected}>${option}</option>`;
|
||||
});
|
||||
|
||||
// Replace the specified placeholder div with the resulting HTML
|
||||
setTimeout(() => {
|
||||
// // check if the result is a SQL query
|
||||
// if(optionsArray.length > 0 && isSQLQuery(optionsArray[0]))
|
||||
// {
|
||||
|
||||
$("#" + targetLocation).replaceWith(optionsHtml);
|
||||
// if (settingKey == "NEWDEV_dev_Network_Node_MAC_ADDR") {
|
||||
// console.log("isSQLQuery in generateSetOptions");
|
||||
|
||||
// }
|
||||
// readData(optionsArray[0], callbackToGenerateEntries, valuesArray, targetLocation, targetField, nameTransformer);
|
||||
|
||||
// } else // this should be already an array, e.g. from a setting or pre-defined
|
||||
// {
|
||||
// optionsArray.forEach(option => {
|
||||
// let selected = valuesArray.includes(option) ? 'selected' : '';
|
||||
// optionsHtml += `<option value="${option}" ${selected}>${option}</option>`;
|
||||
// });
|
||||
|
||||
// // Replace the specified placeholder div with the resulting HTML
|
||||
// setTimeout(() => {
|
||||
|
||||
// $("#" + targetLocation).replaceWith(optionsHtml);
|
||||
|
||||
}, 50);
|
||||
|
||||
}
|
||||
}
|
||||
// }, 50);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -145,86 +153,6 @@ function hideUIelements(settingKey) {
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Data processors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Processor to generate options for a dropdown menu
|
||||
function generateDropdownOptions(data, valuesArray, targetField, nameTransformer) {
|
||||
var optionsHtml = "";
|
||||
data.forEach(function(item) {
|
||||
|
||||
labelName = item.name
|
||||
|
||||
// console.log(nameTransformer);
|
||||
// console.log(labelName);
|
||||
|
||||
// if(nameTransformer && nameTransformer != '' && labelName != '❌None')
|
||||
// {
|
||||
// console.log(labelName);
|
||||
// labelName = nameTransformer(labelName)
|
||||
// console.log(labelName);
|
||||
// }
|
||||
|
||||
let selected = valuesArray.includes(item.id) ? 'selected' : '';
|
||||
|
||||
optionsHtml += `<option value="${item.id}" ${selected}>${labelName}</option>`;
|
||||
});
|
||||
return `${optionsHtml}`;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Processor to generate a list
|
||||
function generateList(data, valuesArray, targetField, nameTransformer) {
|
||||
var listHtml = "";
|
||||
data.forEach(function(item) {
|
||||
|
||||
labelName = item.name
|
||||
|
||||
if(nameTransformer && nameTransformer != '' && labelName != '❌None')
|
||||
{
|
||||
labelName = nameTransformer(labelName)
|
||||
}
|
||||
|
||||
let selected = valuesArray.includes(item.id) ? 'selected' : '';
|
||||
|
||||
listHtml += `<li ${selected}>${labelName}</li>`;
|
||||
});
|
||||
|
||||
return listHtml;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Processor to generate a list in the deviceDetails page
|
||||
function genListWithInputSet(data, valuesArray, targetField, nameTransformer) {
|
||||
|
||||
var listHtml = "";
|
||||
|
||||
console.log(data);
|
||||
data.forEach(function(item) {
|
||||
|
||||
let selected = valuesArray.includes(item.id) ? 'selected' : '';
|
||||
|
||||
// console.log(item);
|
||||
|
||||
labelName = item.name
|
||||
|
||||
if(nameTransformer && nameTransformer != '' && labelName != '❌None')
|
||||
{
|
||||
labelName = nameTransformer(labelName)
|
||||
}
|
||||
|
||||
listHtml += `<li ${selected}>
|
||||
<a href="javascript:void(0)" onclick="setTextValue('${targetField}','${item.id}')">${labelName}</a>
|
||||
</li>`;
|
||||
|
||||
});
|
||||
|
||||
return listHtml;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -306,6 +234,57 @@ function getCellValue(row, index) {
|
||||
return $(row).children('td').eq(index).text();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// handling events on the backend initiated by the front end START
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
modalEventStatusId = 'modal-message-front-event'
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Calls a backend function to add a front-end event (specified by the attributes 'data-myevent' and 'data-myparam-plugin' on the passed element) to an execution queue
|
||||
function addToExecutionQueue_settingEvent(element)
|
||||
{
|
||||
|
||||
// value has to be in format event|param. e.g. run|ARPSCAN
|
||||
action = `${getGuid()}|${$(element).attr('data-myevent')}|${$(element).attr('data-myparam-plugin')}`
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "php/server/util.php",
|
||||
data: { function: "addToExecutionQueue", action: action },
|
||||
success: function(data, textStatus) {
|
||||
// showModalOk ('Result', data );
|
||||
|
||||
// show message
|
||||
showModalOk(getString("general_event_title"), `${getString("general_event_description")} <br/> <br/> <code id='${modalEventStatusId}'></code>`);
|
||||
|
||||
updateModalState()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Updating the execution queue in in modal pop-up
|
||||
function updateModalState() {
|
||||
setTimeout(function() {
|
||||
// Fetch the content from the log file using an AJAX request
|
||||
$.ajax({
|
||||
url: '/log/execution_queue.log',
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
// Update the content of the HTML element (e.g., a div with id 'logContent')
|
||||
$('#'+modalEventStatusId).html(data);
|
||||
|
||||
updateModalState();
|
||||
},
|
||||
error: function() {
|
||||
// Handle error, such as the file not being found
|
||||
$('#logContent').html('Error: Log file not found.');
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// initialize
|
||||
|
||||
@@ -370,9 +370,27 @@ $db->close();
|
||||
</div>
|
||||
<div class="tab-pane" id="tab_BackupRestore">
|
||||
<div class="db_info_table">
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnExportCSV" onclick="ExportCSV()"><?= lang('Maintenance_Tool_ExportCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ExportCSV_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnPiaBackupDBtoArchive" onclick="askPiaBackupDBtoArchive()"><?= lang('Maintenance_Tool_backup');?></button>
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportCSV" onclick="askImportCSV()"><?= lang('Maintenance_Tool_ImportCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportCSV_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportPastedCSV" onclick="askImportPastedCSV()"><?= lang('Maintenance_Tool_ImportPastedCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportPastedCSV_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnPiaBackupDBtoArchive" onclick="askPiaBackupDBtoArchive()"><?= lang('Maintenance_Tool_backup');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_backup_text');?></div>
|
||||
</div>
|
||||
@@ -388,146 +406,54 @@ $db->close();
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_purgebackup_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnExportCSV" onclick="askExportCSV()"><?= lang('Maintenance_Tool_ExportCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ExportCSV_text');?></div>
|
||||
</div>
|
||||
<div class="db_info_table_row">
|
||||
<div class="db_tools_table_cell_a" >
|
||||
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportCSV" onclick="askImportCSV()"><?= lang('Maintenance_Tool_ImportCSV');?></button>
|
||||
</div>
|
||||
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportCSV_text');?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ---------------------------Logging-------------------------------------------- -->
|
||||
<div class="tab-pane" id="tab_Logging">
|
||||
<div class="db_info_table">
|
||||
<div class="log-area box box-solid box-primary">
|
||||
<div class="row logs-row">
|
||||
<textarea id="app_log" class="logs" cols="70" rows="10" wrap='off' readonly >
|
||||
<?php
|
||||
if(filesize("./log/app.log") > 2000000)
|
||||
{
|
||||
echo file_get_contents( "./log/app.log", false, null, -2000000);
|
||||
}
|
||||
else{
|
||||
echo file_get_contents( "./log/app.log" );
|
||||
}
|
||||
|
||||
?>
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="row logs-row" >
|
||||
<div>
|
||||
<div class="log-file">app.log <div class="logs-size"><?php echo number_format((filesize("./log/app.log") / 1000000),2,",",".") . ' MB';?>
|
||||
<span class="span-padding"><a href="./log/app.log" target="_blank"><i class="fa fa-download"></i> </a></span>
|
||||
</div></div>
|
||||
<button class="btn btn-primary col-sm-2 col-xs-2" onclick="restartBackend()">Not working: Restart Backend</button>
|
||||
<div class="log-purge">
|
||||
|
||||
<button class="btn btn-primary " onclick="logManage('app.log','cleanLog')"><?= lang('Gen_Purge');?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="log-area box box-solid box-primary">
|
||||
<div class="row logs-row">
|
||||
<textarea id="app_front_log" class="logs" cols="70" rows="10" wrap='off' readonly><?php echo file_get_contents( "./log/app_front.log" ); ?>
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="row logs-row" >
|
||||
<div>
|
||||
<div class="log-file">app_front.log<div class="logs-size"><?php echo number_format((filesize("./log/app_front.log") / 1000000),2,",",".") . ' MB';?>
|
||||
<span class="span-padding"><a href="./log/app_front.log"><i class="fa fa-download"></i> </a></span>
|
||||
</div></div>
|
||||
<div class="log-purge">
|
||||
<button class="btn btn-primary" onclick="logManage('app_front.log','cleanLog')"><?= lang('Gen_Purge');?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="log-area box box-solid box-primary">
|
||||
<div class="row logs-row">
|
||||
<textarea id="app_php_log" class="logs" cols="70" rows="10" wrap='off' readonly><?php echo file_get_contents( "./log/app.php_errors.log" ); ?>
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="row logs-row" >
|
||||
<div>
|
||||
<div class="log-file">app.php_errors.log<div class="logs-size"><?php echo number_format((filesize("./log/app.php_errors.log") / 1000000),2,",",".") . ' MB';?>
|
||||
<span class="span-padding"><a href="./log/app.php_errors.log"><i class="fa fa-download"></i> </a></span>
|
||||
</div></div>
|
||||
<div class="log-purge">
|
||||
<button class="btn btn-primary" onclick="logManage('app.php_errors.log','cleanLog')"><?= lang('Gen_Purge');?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="log-area box box-solid box-primary ">
|
||||
<div class="row logs-row">
|
||||
<textarea id="nginx_error_log" class="logs logs-small" cols="70" rows="10" wrap='off' readonly><?php echo file_get_contents( "/var/log/nginx/error.log" ); ?>
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="row logs-row" >
|
||||
<div>
|
||||
<div class="log-file" title="/var/log/nginx/error.log">nginx/error.log</div>
|
||||
<span class="span-padding"><a href="/var/log/nginx/error.log"><i class="fa fa-download"></i> </a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="log-area box box-solid box-primary">
|
||||
<div class="row logs-row">
|
||||
<textarea id="stdout_log" class="logs logs-small" cols="70" rows="10" wrap='off' readonly><?php echo file_get_contents( "./log/stdout.log" ); ?>
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="row logs-row" >
|
||||
<div>
|
||||
<div class="log-file">stdout.log<div class="logs-size"><?php echo number_format((filesize("./log/stdout.log") / 1000000),2,",",".") . ' MB';?>
|
||||
<span class="span-padding"><a href="./log/stdout.log"><i class="fa fa-download"></i> </a></span>
|
||||
</div></div>
|
||||
<div class="log-purge">
|
||||
<button class="btn btn-primary" onclick="logManage('stdout.log','cleanLog')"><?= lang('Gen_Purge');?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="log-area box box-solid box-primary">
|
||||
<div class="row logs-row">
|
||||
<textarea id="stderr_log" class="logs logs-small" cols="70" rows="10" wrap='off' readonly><?php echo file_get_contents( "./log/stderr.log" ); ?>
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="row logs-row" >
|
||||
<div>
|
||||
<div class="log-file">stderr.log<div class="logs-size"><?php echo number_format((filesize("./log/stderr.log") / 1000000),2,",",".") . ' MB';?>
|
||||
<span class="span-padding"><a href="./log/stderr.log"><i class="fa fa-download"></i> </a></span>
|
||||
</div></div>
|
||||
<div class="log-purge">
|
||||
<button class="btn btn-primary" onclick="logManage('stderr.log','cleanLog')"><?= lang('Gen_Purge');?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row actions">
|
||||
<div class="col-sm-2">
|
||||
<div class="form-check toggle">
|
||||
<label class="form-check-label pointer" for="logsAutoRefresh">
|
||||
<input class="form-check-input" type="checkbox" id="logsAutoRefresh" onchange="toggleAutoRefresh()" />
|
||||
Auto-refresh
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ---------------------------Bulk edit -------------------------------------------- -->
|
||||
<div class="tab-pane" id="tab_multiEdit">
|
||||
<div class="db_info_table">
|
||||
<div class="box box-solid">
|
||||
<?php
|
||||
require 'multiEditCore.php';
|
||||
?>
|
||||
<div class="col-sm-2">
|
||||
<div class="form-check toggle">
|
||||
<label class="form-check-label pointer" for="logsAutoScroll">
|
||||
<input class="form-check-input" type="checkbox" checked id="logsAutoScroll" />
|
||||
Auto-scroll
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<div class="form-inline toggle">
|
||||
<input class="form-control" type="text" id="logsFilter" oninput="applyFilter()" placeholder="Filter lines with text..." />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="db_info_table">
|
||||
|
||||
<div id="logsPlc"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ---------------------------Bulk edit -------------------------------------------- -->
|
||||
<div class="tab-pane" id="tab_multiEdit">
|
||||
<div class="db_info_table">
|
||||
<div class="box box-solid">
|
||||
<?php
|
||||
require 'multiEditCore.php';
|
||||
?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- ------------------------------------------------------------------------------ -->
|
||||
</div>
|
||||
<!-- ------------------------------------------------------------------------------ -->
|
||||
|
||||
</div>
|
||||
|
||||
@@ -558,7 +484,6 @@ $db->close();
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var emptyArr = ['undefined', "", undefined, null];
|
||||
@@ -566,76 +491,92 @@ var selectedTab = 'tab_Settings_id';
|
||||
|
||||
initializeTabs();
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// delete devices with emty macs
|
||||
function askDeleteDevicesWithEmptyMACs () {
|
||||
// Ask
|
||||
showModalWarning('<?= lang('Maintenance_Tool_del_empty_macs_noti');?>', '<?= lang('Maintenance_Tool_del_empty_macs_noti_text');?>',
|
||||
'Cancel', 'Delete', 'deleteDevicesWithEmptyMACs');
|
||||
}
|
||||
// -----------------------------------------------------------
|
||||
function deleteDevicesWithEmptyMACs()
|
||||
{
|
||||
// Delete device
|
||||
$.get('php/server/devices.php?action=deleteAllWithEmptyMACs', function(msg) {
|
||||
showMessage (msg);
|
||||
write_notification(`[Maintenance] All devices witout a Mac manually deleted`, 'info')
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// delete all devices
|
||||
function askDeleteAllDevices () {
|
||||
// Ask
|
||||
showModalWarning('<?= lang('Maintenance_Tool_del_alldev_noti');?>', '<?= lang('Maintenance_Tool_del_alldev_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteAllDevices');
|
||||
}
|
||||
// -----------------------------------------------------------
|
||||
function deleteAllDevices()
|
||||
{
|
||||
// Delete device
|
||||
$.get('php/server/devices.php?action=deleteAllDevices', function(msg) {
|
||||
showMessage (msg);
|
||||
write_notification(`[Maintenance] All devices manually deleted`, 'info')
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// delete all (unknown) devices
|
||||
function askDeleteUnknown () {
|
||||
// Ask
|
||||
showModalWarning('<?= lang('Maintenance_Tool_del_unknowndev_noti');?>', '<?= lang('Maintenance_Tool_del_unknowndev_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteUnknownDevices');
|
||||
}
|
||||
// -----------------------------------------------------------
|
||||
function deleteUnknownDevices()
|
||||
{
|
||||
// Execute
|
||||
$.get('php/server/devices.php?action=deleteUnknownDevices', function(msg) {
|
||||
showMessage (msg);
|
||||
write_notification(`[Maintenance] Unknown devices manually deleted`, 'info')
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// delete all Events
|
||||
function askDeleteEvents () {
|
||||
// Ask
|
||||
showModalWarning('<?= lang('Maintenance_Tool_del_allevents_noti');?>', '<?= lang('Maintenance_Tool_del_allevents_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteEvents');
|
||||
}
|
||||
// -----------------------------------------------------------
|
||||
function deleteEvents()
|
||||
{
|
||||
// Execute
|
||||
$.get('php/server/devices.php?action=deleteEvents', function(msg) {
|
||||
showMessage (msg);
|
||||
write_notification(`[Maintenance] Events manually deleted (all)`, 'info')
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// delete all Events older than 30 days
|
||||
function askDeleteEvents30 () {
|
||||
// Ask
|
||||
showModalWarning('<?= lang('Maintenance_Tool_del_allevents30_noti');?>', '<?= lang('Maintenance_Tool_del_allevents30_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', 'deleteEvents30');
|
||||
}
|
||||
// -----------------------------------------------------------
|
||||
function deleteEvents30()
|
||||
{
|
||||
// Execute
|
||||
$.get('php/server/devices.php?action=deleteEvents30', function(msg) {
|
||||
showMessage (msg);
|
||||
write_notification(`[Maintenance] Events manually deleted (last 30 days kep)`, 'info')
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// delete History
|
||||
function askDeleteActHistory () {
|
||||
// Ask
|
||||
@@ -650,6 +591,7 @@ function deleteActHistory()
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Backup DB to Archive
|
||||
function askPiaBackupDBtoArchive () {
|
||||
// Ask
|
||||
@@ -664,6 +606,7 @@ function PiaBackupDBtoArchive()
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Restore DB from Archive
|
||||
function askPiaRestoreDBfromArchive () {
|
||||
// Ask
|
||||
@@ -678,6 +621,7 @@ function PiaRestoreDBfromArchive()
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Purge Backups
|
||||
function askPiaPurgeDBBackups() {
|
||||
// Ask
|
||||
@@ -692,34 +636,47 @@ function PiaPurgeDBBackups()
|
||||
});
|
||||
}
|
||||
|
||||
// Restart Backend
|
||||
function restartBackend() {
|
||||
// Execute
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "php/server/util.php",
|
||||
data: { function: 'restartBackend' },
|
||||
success: function(data, textStatus) {
|
||||
showModalOk ('Result', data );
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Restart Backend Python Server
|
||||
|
||||
function askRestartBackend() {
|
||||
// Ask
|
||||
showModalWarning('<?= lang('Maint_RestartServer');?>', '<?= lang('Maint_Restart_Server_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Maint_RestartServer');?>', 'restartBackend');
|
||||
}
|
||||
|
||||
// Export CSV
|
||||
function askExportCSV() {
|
||||
// Ask
|
||||
showModalWarning('<?= lang('Maintenance_Tool_ExportCSV_noti');?>', '<?= lang('Maintenance_Tool_ExportCSV_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'ExportCSV');
|
||||
// -----------------------------------------------------------
|
||||
function restartBackend() {
|
||||
|
||||
modalEventStatusId = 'modal-message-front-event'
|
||||
|
||||
// Execute
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "php/server/util.php",
|
||||
data: { function: "addToExecutionQueue", action: `${getGuid()}|cron_restart_backend` },
|
||||
success: function(data, textStatus) {
|
||||
// showModalOk ('Result', data );
|
||||
|
||||
// show message
|
||||
showModalOk(getString("general_event_title"), `${getString("general_event_description")} <br/> <br/> <code id='${modalEventStatusId}'></code>`);
|
||||
|
||||
updateModalState()
|
||||
|
||||
write_notification('[Maintenance] App manually restarted', 'info')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Export CSV
|
||||
function ExportCSV()
|
||||
{
|
||||
// Execute
|
||||
openInNewTab("php/server/devices.php?action=ExportCSV")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Import CSV
|
||||
function askImportCSV() {
|
||||
// Ask
|
||||
@@ -731,6 +688,27 @@ function ImportCSV()
|
||||
// Execute
|
||||
$.get('php/server/devices.php?action=ImportCSV', function(msg) {
|
||||
showMessage (msg);
|
||||
write_notification(`[Maintenance] Devices imported from CSV file`, 'info')
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Import pasted CSV
|
||||
function askImportPastedCSV() {
|
||||
|
||||
// Add new icon as base64 string
|
||||
showModalInput ('<i class="fa fa-square-plus pointer"></i> <?= lang('Maintenance_Tool_ImportCSV_noti');?>', '<?= lang('Maintenance_Tool_ImportPastedCSV_noti_text');?>',
|
||||
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'ImportPastedCSV');
|
||||
}
|
||||
|
||||
function ImportPastedCSV()
|
||||
{
|
||||
var csv = $('#modal-input-textarea').val();
|
||||
csvBase64 = btoa(csv)
|
||||
// Execute
|
||||
$.post('php/server/devices.php?action=ImportCSV', { content: csvBase64 }, function(msg) {
|
||||
showMessage(msg);
|
||||
write_notification(`[Maintenance] Devices imported from pasted content`, 'info');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -800,41 +778,29 @@ function performLogManage() {
|
||||
data: { function: logFileAction, settings: targetLogFile },
|
||||
success: function(data, textStatus) {
|
||||
showModalOk ('Result', data );
|
||||
write_notification(`[Maintenance] Log file "${targetLogFile}" manually purged`, 'info')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// scroll down the log areas
|
||||
function scrollDown()
|
||||
{
|
||||
setTimeout(() => {
|
||||
|
||||
function scrollDown() {
|
||||
|
||||
var elementToCheck = $("#tab_Logging_id");
|
||||
|
||||
// Check if the parent <li> is active
|
||||
if (elementToCheck.parent().hasClass("active")) {
|
||||
{
|
||||
var areaIDs = ['app_log', 'app_front_log', 'IP_changes_log', 'stdout_log', 'stderr_log', 'app_pholus_log', 'app_pholus_lastrun_log', 'app_php_log'];
|
||||
|
||||
for (let i = 0; i < areaIDs.length; i++) {
|
||||
var textAreas = $("#logsPlc textarea");
|
||||
|
||||
var tempArea = $('#' + areaIDs[i]);
|
||||
|
||||
if (tempArea.length > 0)
|
||||
{
|
||||
$(tempArea[0]).scrollTop(tempArea[0].scrollHeight);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
textAreas.each(function() {
|
||||
$(this).scrollTop(this.scrollHeight);
|
||||
});
|
||||
}
|
||||
|
||||
}, 200);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Manage displayed columns
|
||||
// --------------------------------------------------------
|
||||
@@ -951,14 +917,77 @@ function initializeTabs () {
|
||||
}, 50);
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// Logs render functionality
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Manages the auto-refresh functionality for the logs
|
||||
let intervalId;
|
||||
|
||||
// load footer asynchronously not to block the page load/other sections
|
||||
function toggleAutoRefresh() {
|
||||
const checkbox = $('#logsAutoRefresh')[0];
|
||||
|
||||
if (checkbox.checked) {
|
||||
intervalId = setInterval(renderLogs, 1000);
|
||||
} else {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Manages thefilter application
|
||||
function applyFilter() {
|
||||
const filterText = $("#logsFilter").val().toLowerCase();
|
||||
|
||||
$(".logs").each(function() {
|
||||
const originalText = $(this).data('originalText') || $(this).val();
|
||||
|
||||
if (!$(this).data('originalText')) {
|
||||
$(this).data('originalText', originalText);
|
||||
}
|
||||
|
||||
const filteredLines = originalText.split('\n').filter(line =>
|
||||
line.toLowerCase().includes(filterText)
|
||||
);
|
||||
|
||||
$(this).val(filteredLines.join('\n'));
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Renders all the logs
|
||||
function renderLogs(customData) {
|
||||
$.ajax({
|
||||
url: 'php/components/logs.php', // PHP script URL
|
||||
type: 'POST', // Use POST method to send data
|
||||
dataType: 'html', // Expect HTML response
|
||||
// data: { items: JSON.stringify(customData) }, // Send customData as JSON
|
||||
success: function(response) {
|
||||
$('#logsPlc').html(response); // Replace container content with fetched HTML
|
||||
|
||||
applyFilter();
|
||||
|
||||
if($('#logsAutoScroll')[0].checked)
|
||||
{
|
||||
scrollDown(); // scroll down the logs
|
||||
}
|
||||
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('Error fetching infoboxes:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Init
|
||||
window.onload = function asyncFooter()
|
||||
{
|
||||
initializeSelectedColumns();
|
||||
scrollDown();
|
||||
initializeTabs();
|
||||
renderLogs();
|
||||
|
||||
// initializeTabs();
|
||||
|
||||
$("#lastCommit").append('<a href="https://github.com/jokob-sk/NetAlertX/commits" target="_blank"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/jokob-sk/netalertx/main?logo=github"></a>');
|
||||
|
||||
@@ -967,10 +996,6 @@ window.onload = function asyncFooter()
|
||||
|
||||
}
|
||||
|
||||
// scroll to the latest log entrie sat teh bottom of the file
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="callout callout-warning">
|
||||
<h4><?= lang('Gen_Warning');?></h4>
|
||||
@@ -102,26 +100,35 @@
|
||||
// Append form groups to the column
|
||||
for (let j = i * elementsPerColumn; j < Math.min((i + 1) * elementsPerColumn, columns.length); j++) {
|
||||
|
||||
let inputType;
|
||||
const setTypeObject = JSON.parse(columns[j].Type.replace(/'/g, '"'));
|
||||
// console.log(setTypeObject);
|
||||
const lastElementObj = setTypeObject.elements[setTypeObject.elements.length - 1]
|
||||
|
||||
switch (columns[j].Type) {
|
||||
case 'integer.checkbox':
|
||||
case 'checkbox':
|
||||
inputType = 'checkbox';
|
||||
break;
|
||||
case 'text.select':
|
||||
inputType = 'text.select';
|
||||
break;
|
||||
default:
|
||||
inputType = 'text';
|
||||
break;
|
||||
}
|
||||
|
||||
if (inputType === 'text.select') {
|
||||
const { elementType, elementOptions = [], transformers = [] } = lastElementObj;
|
||||
const {
|
||||
inputType,
|
||||
readOnly,
|
||||
isMultiSelect,
|
||||
cssClasses,
|
||||
placeholder,
|
||||
suffix,
|
||||
sourceIds,
|
||||
separator,
|
||||
editable,
|
||||
valRes,
|
||||
getStringKey,
|
||||
onClick
|
||||
} = handleElementOptions('none', elementOptions, transformers, val = "");
|
||||
|
||||
targetLocation = columns[j].Code_Name + "_initSettingDropdown"
|
||||
// console.log(setTypeObject);
|
||||
// console.log(inputType);
|
||||
|
||||
initSettingDropdown(columns[j].Code_Name, [], targetLocation, generateDropdownOptions)
|
||||
// render based on element type
|
||||
if (lastElementObj.elementType === 'select') {
|
||||
|
||||
targetLocation = columns[j].Code_Name + "_generateSetOptions"
|
||||
|
||||
generateOptionsOrSetOptions(columns[j].Code_Name, [], targetLocation, generateOptions)
|
||||
|
||||
// Handle Icons as tehy need a preview
|
||||
if(columns[j].Code_Name == 'NEWDEV_dev_Icon')
|
||||
@@ -147,15 +154,11 @@
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
} else if (lastElementObj.elementType === 'input'){
|
||||
|
||||
// Add classes specifically for checkboxes
|
||||
if (inputType === 'checkbox') {
|
||||
inputClass = 'checkbox';
|
||||
|
||||
} else {
|
||||
inputClass = 'form-control';
|
||||
}
|
||||
inputType === 'checkbox' ? inputClass = 'checkbox' : inputClass = 'form-control';
|
||||
|
||||
|
||||
input = `<input class="${inputClass}"
|
||||
id="${columns[j].Code_Name}"
|
||||
@@ -290,7 +293,7 @@ function executeAction(action, whereColumnName, key, targetColumns, newTargetCol
|
||||
// update API endpoints to refresh the UI
|
||||
updateApi()
|
||||
|
||||
writeNotification(`[Multi edit] Executed "${action}" on Columns "${targetColumns}" matching "${key}"`, 'info')
|
||||
write_notification(`[Multi edit] Executed "${action}" on Columns "${targetColumns}" matching "${key}"`, 'info')
|
||||
|
||||
} else {
|
||||
showMessage(getString('Gen_LockedDB'));
|
||||
@@ -317,7 +320,7 @@ function deleteSelectedDevices()
|
||||
{
|
||||
macs_tmp = selectorMacs()
|
||||
executeAction('delete', 'dev_MAC', macs_tmp )
|
||||
writeNotification('[Multi edit] Manually deleted devices with MACs:' + macs_tmp, 'info')
|
||||
write_notification('[Multi edit] Manually deleted devices with MACs:' + macs_tmp, 'info')
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -50,10 +50,10 @@
|
||||
|
||||
$decoded_icon = base64_decode($icon);
|
||||
$idFromMac = str_replace(":", "_", $node_mac);
|
||||
$str_tab_header = '<li class="'.$activetab.'">
|
||||
$str_tab_header = '<li class="networkNodeTabHeaders '.$activetab.' " >
|
||||
|
||||
<a href="#'.$idFromMac.'" data-mytabmac="'.$node_mac.'" id="'.$idFromMac.'_id" data-toggle="tab" >' // _id is added so it doesn't conflict with AdminLTE tab behavior
|
||||
.'<div class="icon">'.$decoded_icon.' </div>'.$node_name.' ' .$str_port.$node_badge.
|
||||
<a href="#'.$idFromMac.'" data-mytabmac="'.$node_mac.'" id="'.$idFromMac.'_id" data-toggle="tab" title="'.$node_name.' ">' // _id is added so it doesn't conflict with AdminLTE tab behavior
|
||||
.'<div class="icon">'.$decoded_icon.' </div> <span class="node-name">'.$node_name.'</span>' .$str_port.$node_badge.
|
||||
'</a>
|
||||
</li>';
|
||||
|
||||
@@ -464,7 +464,7 @@
|
||||
<script src="lib/treeviz/require.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
<script defer>
|
||||
$.get('php/server/devices.php?action=getDevicesList&status=all&forceDefaultOrder', function(data) {
|
||||
|
||||
rawData = JSON.parse (data)
|
||||
@@ -528,8 +528,10 @@
|
||||
for(var i in list)
|
||||
{
|
||||
//... of the current node
|
||||
if(list[i].parentMac == node.mac && !hiddenMacs.includes(list[i].parentMac))
|
||||
|
||||
if(list[i].parentMac.toLowerCase() == node.mac.toLowerCase() && !hiddenMacs.includes(list[i].parentMac))
|
||||
{
|
||||
|
||||
visibleNodesCount++
|
||||
|
||||
// and process them
|
||||
@@ -546,7 +548,6 @@
|
||||
{
|
||||
parentNodesCount++
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
name: node.name,
|
||||
@@ -570,7 +571,6 @@
|
||||
|
||||
function getHierarchy()
|
||||
{
|
||||
|
||||
for(i in deviceListGlobal)
|
||||
{
|
||||
if(deviceListGlobal[i].mac == 'Internet')
|
||||
@@ -615,10 +615,10 @@
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Handle network node click - select correct tab in teh bottom table
|
||||
// Handle network node click - select correct tab in the bottom table
|
||||
function handleNodeClick(event)
|
||||
{
|
||||
console.log(event.target.offsetParent.offsetParent)
|
||||
// console.log(event.target.offsetParent.offsetParent)
|
||||
|
||||
const targetTabMAC = $(event.target.offsetParent.offsetParent).attr("data-mytreemacmain");
|
||||
|
||||
@@ -630,14 +630,24 @@
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
var myTree;
|
||||
var visibleTreeArea = $(window).height()-135;
|
||||
var treeAreaHeight = visibleTreeArea > 800 ? 800 : visibleTreeArea;
|
||||
var visibleTreeArea = $(window).height()-155;
|
||||
var nodeWidth = 160;
|
||||
var emSize;
|
||||
var nodeHeight;
|
||||
var sizeCoefficient = 1
|
||||
|
||||
function initTree(myHierarchy)
|
||||
{
|
||||
console.log(myHierarchy)
|
||||
|
||||
// calculate the drawing area based on teh tree width and available screen size
|
||||
var treeAreaHeight = visibleTreeArea > 800 ? 800 : visibleTreeArea;
|
||||
let screenWidth = $('.content-header').width();
|
||||
let treeWidth = (nodeWidth + 20) * parentNodesCount;
|
||||
let treeAreaWidth = screenWidth < treeWidth ? treeWidth : screenWidth;
|
||||
|
||||
// init the drawing area size
|
||||
$("#networkTree").attr('style', `height:${treeAreaHeight}px; width:${treeAreaWidth}px`)
|
||||
|
||||
if(myHierarchy.type == "")
|
||||
{
|
||||
@@ -654,7 +664,7 @@
|
||||
// nodeHeight = ((emSize*100*0.30).toFixed(0))
|
||||
nodeHeight = ((emSize*100*0.30).toFixed(0))
|
||||
|
||||
$("#networkTree").attr('style', `height:${treeAreaHeight}px; width:${$('.content-header').width()}px`)
|
||||
console.log(Treeviz);
|
||||
|
||||
myTree = Treeviz.create({
|
||||
htmlId: "networkTree",
|
||||
@@ -703,7 +713,7 @@
|
||||
>
|
||||
<div class="netNodeText">
|
||||
<strong>${devicePort} ${deviceIcon}
|
||||
<span class="spanNetworkTree anonymizeDev">${nodeData.data.name}</span>
|
||||
<span class="spanNetworkTree anonymizeDev" >${nodeData.data.name}</span>
|
||||
</strong>
|
||||
${collapseExpandHtml}
|
||||
</div>
|
||||
@@ -718,8 +728,8 @@
|
||||
secondaryAxisNodeSpacing: 0.3,
|
||||
nodeHeight: nodeHeight.toString(),
|
||||
marginTop: '5',
|
||||
hasZoom: false,
|
||||
hasPan: false,
|
||||
hasZoom: true,
|
||||
hasPan: true,
|
||||
// marginLeft: '15',
|
||||
idKey: "id",
|
||||
hasFlatData: false,
|
||||
@@ -728,8 +738,8 @@
|
||||
onNodeClick: (nodeData) => handleNodeClick(nodeData),
|
||||
relationnalField: "children",
|
||||
});
|
||||
|
||||
|
||||
console.log(myHierarchy)
|
||||
|
||||
myTree.refresh(myHierarchy);
|
||||
|
||||
|
||||
94
front/php/components/logs.php
Executable file
94
front/php/components/logs.php
Executable file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
require '../server/init.php';
|
||||
|
||||
// Function to render the log area component
|
||||
function renderLogArea($params) {
|
||||
$fileName = isset($params['fileName']) ? $params['fileName'] : '';
|
||||
$filePath = isset($params['filePath']) ? $params['filePath'] : '';
|
||||
$textAreaCssClass = isset($params['textAreaCssClass']) ? $params['textAreaCssClass'] : '';
|
||||
$buttons = isset($params['buttons']) ? $params['buttons'] : [];
|
||||
$content = "";
|
||||
|
||||
if (filesize($filePath) > 2000000) {
|
||||
$content = file_get_contents($filePath, false, null, -2000000);
|
||||
} else {
|
||||
$content = file_get_contents($filePath);
|
||||
}
|
||||
|
||||
// Prepare the download button HTML if filePath starts with /app/front
|
||||
$downloadButtonHtml = '';
|
||||
if (strpos($filePath, '/app/front') === 0) {
|
||||
$downloadButtonHtml = '
|
||||
<span class="span-padding">
|
||||
<a href="' . htmlspecialchars(str_replace('/app/front', '', $filePath)) . '" target="_blank">
|
||||
<i class="fa fa-download"></i>
|
||||
</a>
|
||||
</span>';
|
||||
}
|
||||
|
||||
// Prepare buttons HTML
|
||||
$buttonsHtml = '';
|
||||
$totalButtons = count($buttons);
|
||||
if ($totalButtons > 0) {
|
||||
$colClass = 12 / $totalButtons;
|
||||
// Use $colClass in your HTML generation or further logic
|
||||
} else {
|
||||
// Handle case where $buttons array is empty
|
||||
$colClass = 12;
|
||||
}
|
||||
|
||||
foreach ($buttons as $button) {
|
||||
$labelStringCode = isset($button['labelStringCode']) ? $button['labelStringCode'] : '';
|
||||
$event = isset($button['event']) ? $button['event'] : '';
|
||||
|
||||
$buttonsHtml .= '
|
||||
<div class="button-wrap col-sm-' . $colClass . ' col-xs-' . $colClass . '">
|
||||
<button class="btn btn-primary col-sm-12 col-xs-12" onclick="' . htmlspecialchars($event) . '">' . lang($labelStringCode) . '</button>
|
||||
</div>';
|
||||
}
|
||||
|
||||
|
||||
// Render the log area HTML
|
||||
$html = '
|
||||
<div class="log-area box box-solid box-primary">
|
||||
<div class="row logs-row col-sm-12 col-xs-12">
|
||||
<textarea class="' . htmlspecialchars($textAreaCssClass) . '" cols="70" rows="20" wrap="off" readonly>'
|
||||
. htmlspecialchars($content) .
|
||||
'</textarea>
|
||||
</div>
|
||||
<div class="row logs-row">
|
||||
<div class="log-file col-sm-6 col-xs-12">' . htmlspecialchars($fileName) . '
|
||||
<div class="logs-size">' . number_format((filesize($filePath) / 1000000), 2, ",", ".") . ' MB'
|
||||
. $downloadButtonHtml .
|
||||
'</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-xs-12">'
|
||||
. $buttonsHtml .
|
||||
'</div>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
// Load default data from JSON file
|
||||
$defaultDataFile = 'logs_defaults.json';
|
||||
$defaultData = file_exists($defaultDataFile) ? json_decode(file_get_contents($defaultDataFile), true) : [];
|
||||
|
||||
// Check if JSON data is submitted via POST
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['items'])) {
|
||||
$items = json_decode($_POST['items'], true);
|
||||
} else {
|
||||
$items = $defaultData;
|
||||
}
|
||||
|
||||
// Render the log areas with the retrieved or default data
|
||||
$html = '';
|
||||
foreach ($items as $item) {
|
||||
$html .= renderLogArea($item);
|
||||
}
|
||||
|
||||
echo $html;
|
||||
exit();
|
||||
?>
|
||||
98
front/php/components/logs_defaults.json
Executable file
98
front/php/components/logs_defaults.json
Executable file
@@ -0,0 +1,98 @@
|
||||
[
|
||||
{
|
||||
"buttons": [
|
||||
{
|
||||
"labelStringCode": "Maint_PurgeLog",
|
||||
"event": "logManage('app.log', 'cleanLog')"
|
||||
},
|
||||
{
|
||||
"labelStringCode": "Maint_RestartServer",
|
||||
"event": "askRestartBackend()"
|
||||
}
|
||||
],
|
||||
"fileName": "app.log",
|
||||
"filePath": "/app/front/log/app.log",
|
||||
"textAreaCssClass": "logs"
|
||||
|
||||
},
|
||||
{
|
||||
"buttons": [
|
||||
{
|
||||
"labelStringCode": "Maint_PurgeLog",
|
||||
"event": "logManage('app_front.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "app_front.log",
|
||||
"filePath": "/app/front/log/app_front.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
"buttons": [
|
||||
{
|
||||
"labelStringCode": "Maint_PurgeLog",
|
||||
"event": "logManage('app.php_errors.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "app.php_errors.log",
|
||||
"filePath": "/app/front/log/app.php_errors.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
"buttons": [
|
||||
{
|
||||
"labelStringCode": "Maint_PurgeLog",
|
||||
"event": "logManage('execution_queue.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "execution_queue.log",
|
||||
"filePath": "/app/front/log/execution_queue.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
"buttons": [
|
||||
],
|
||||
"fileName": "nginx/error.log",
|
||||
"filePath": "/var/log/nginx/error.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
"buttons": [
|
||||
{
|
||||
"labelStringCode": "Maint_PurgeLog",
|
||||
"event": "logManage('app_front.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "app_front.log",
|
||||
"filePath": "/app/front/log/app_front.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
"buttons": [
|
||||
],
|
||||
"fileName": "db_is_locked.log",
|
||||
"filePath": "/app/front/log/db_is_locked.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
"buttons": [
|
||||
{
|
||||
"labelStringCode": "Maint_PurgeLog",
|
||||
"event": "logManage('stdout.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "stdout.log",
|
||||
"filePath": "/app/front/log/stdout.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
"buttons": [
|
||||
{
|
||||
"labelStringCode": "Maint_PurgeLog",
|
||||
"event": "logManage('stderr.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "stderr.log",
|
||||
"filePath": "/app/front/log/stderr.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
}
|
||||
]
|
||||
@@ -463,15 +463,29 @@ function ExportCSV() {
|
||||
// Import CSV of devices
|
||||
//------------------------------------------------------------------------------
|
||||
function ImportCSV() {
|
||||
$file = '../../../config/devices.csv';
|
||||
|
||||
if (file_exists($file)) {
|
||||
global $db;
|
||||
$skipped = "";
|
||||
$error = "";
|
||||
global $db;
|
||||
$file = '../../../config/devices.csv';
|
||||
$data = "";
|
||||
$skipped = "";
|
||||
$error = "";
|
||||
|
||||
// check if content passed in query string
|
||||
if(isset ($_POST['content']) && !empty ($_POST['content']))
|
||||
{
|
||||
// Decode the Base64 string
|
||||
$data = base64_decode($_POST['content']);
|
||||
|
||||
} else if (file_exists($file)) { // try to get the data form the file
|
||||
|
||||
// Read the CSV file
|
||||
$data = file_get_contents($file);
|
||||
} else {
|
||||
echo lang('BackDevices_DBTools_ImportCSVMissing');
|
||||
}
|
||||
|
||||
if($data != "")
|
||||
{
|
||||
$lines = explode("\n", $data);
|
||||
|
||||
// Get the column headers from the first line of the CSV
|
||||
@@ -517,8 +531,6 @@ function ImportCSV() {
|
||||
// An error occurred while writing to the DB, display the last error message
|
||||
echo lang('BackDevices_DBTools_ImportCSVError') . "\n" . $error . "\n" . $sql . "\n\n" . $result;
|
||||
}
|
||||
} else {
|
||||
echo lang('BackDevices_DBTools_ImportCSVMissing');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -901,18 +913,11 @@ function copyFromDevice() {
|
||||
|
||||
$MAC_FROM = $_REQUEST['macFrom'];
|
||||
$MAC_TO = $_REQUEST['macTo'];
|
||||
|
||||
if ((false === filter_var($MAC_FROM , FILTER_VALIDATE_MAC) && $MAC_FROM != "Internet" && $MAC_FROM != "") ) {
|
||||
throw new Exception('Invalid mac address');
|
||||
}
|
||||
if ((false === filter_var($MAC_TO , FILTER_VALIDATE_MAC) && $MAC_TO != "Internet" && $MAC_TO != "") ) {
|
||||
throw new Exception('Invalid mac address');
|
||||
}
|
||||
|
||||
global $db;
|
||||
|
||||
// clean-up temporary table
|
||||
$sql = "DROP TABLE temp_devices ";
|
||||
$sql = "DROP TABLE IF EXISTS temp_devices ";
|
||||
$result = $db->query($sql);
|
||||
|
||||
// create temporary table with the source data
|
||||
|
||||
@@ -28,10 +28,7 @@ if(array_key_exists('settings', $_REQUEST) != FALSE)
|
||||
|
||||
// call functions based on requested params
|
||||
switch ($FUNCTION) {
|
||||
case 'restartBackend':
|
||||
|
||||
restartBackend();
|
||||
break;
|
||||
|
||||
case 'savesettings':
|
||||
|
||||
saveSettings();
|
||||
@@ -228,6 +225,8 @@ function displayMessage($message, $logAlert = FALSE, $logConsole = TRUE, $logFil
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Adds an action to perform into the execution_queue.log file
|
||||
function addToExecutionQueue($action)
|
||||
{
|
||||
@@ -247,27 +246,6 @@ function addToExecutionQueue($action)
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
function restartBackend()
|
||||
{
|
||||
$command = 'pkill -f "python /app/server" && (python /app/server > /dev/null 2>&1 &) && echo "done" 2>&1';
|
||||
|
||||
// Execute the command
|
||||
$output = [];
|
||||
$output_str = "";
|
||||
$return_var = 0;
|
||||
exec($command, $output, $return_var);
|
||||
|
||||
// Format the output
|
||||
foreach ($output as $line) {
|
||||
$output_str .= $line . "\n";
|
||||
}
|
||||
|
||||
|
||||
echo "Command result: $return_var, $output_str";
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
function cleanLog($logFile)
|
||||
@@ -276,7 +254,7 @@ function cleanLog($logFile)
|
||||
|
||||
$path = "";
|
||||
|
||||
$allowedFiles = ['app.log', 'app_front.log', 'IP_changes.log', 'stdout.log', 'stderr.log', "pholus_lastrun.log", 'app.php_errors.log'];
|
||||
$allowedFiles = ['app.log', 'app_front.log', 'IP_changes.log', 'stdout.log', 'stderr.log', "pholus_lastrun.log", 'app.php_errors.log', 'execution_queue.log'];
|
||||
|
||||
if(in_array($logFile, $allowedFiles))
|
||||
{
|
||||
@@ -328,7 +306,7 @@ function saveSettings()
|
||||
$txt = $txt."# Generated: ".$timestamp." #\n";
|
||||
$txt = $txt."# #\n";
|
||||
$txt = $txt."# Config file for the LAN intruder detection app: #\n";
|
||||
$txt = $txt."# https://github.com/jokob-sk/NetAlertX #\n";
|
||||
$txt = $txt."# https://github.com/jokob-sk/NetAlertX #\n";
|
||||
$txt = $txt."# #\n";
|
||||
$txt = $txt."#-----------------AUTOGENERATED FILE-----------------#\n";
|
||||
|
||||
@@ -348,56 +326,57 @@ function saveSettings()
|
||||
$txt .= "\n#---------------------------\n";
|
||||
|
||||
foreach ($decodedSettings as $setting) {
|
||||
$settingGroup = $setting[0];
|
||||
$settingKey = $setting[1];
|
||||
$settingType = $setting[2];
|
||||
$settingValue = $setting[3];
|
||||
|
||||
// sanity check
|
||||
if($settingKey == "UI_LANG" && $settingValue == "")
|
||||
{
|
||||
$settingGroup = $setting[0];
|
||||
$settingKey = $setting[1];
|
||||
$dataType = $setting[2];
|
||||
$settingValue = $setting[3];
|
||||
|
||||
// // Parse the settingType JSON
|
||||
// $settingType = json_decode($settingTypeJson, true);
|
||||
|
||||
// Sanity check
|
||||
if($settingKey == "UI_LANG" && $settingValue == "") {
|
||||
echo "🔴 Error: important settings missing. Refresh the page with 🔃 on the top and try again.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ($group == $settingGroup) {
|
||||
|
||||
if ($dataType == 'string' ) {
|
||||
$val = encode_single_quotes($settingValue);
|
||||
$txt .= $settingKey . "='" . $val . "'\n";
|
||||
} elseif ($dataType == 'integer') {
|
||||
$txt .= $settingKey . "=" . $settingValue . "\n";
|
||||
} elseif ($dataType == 'json') {
|
||||
$txt .= $settingKey . "=" . $settingValue . "\n";
|
||||
} elseif ($dataType == 'boolean') {
|
||||
$val = ($settingValue === true || $settingValue === 1 || strtolower($settingValue) === 'true') ? "True" : "False";
|
||||
$txt .= $settingKey . "=" . $val . "\n";
|
||||
} elseif ($dataType == 'array' ) {
|
||||
$temp = '';
|
||||
|
||||
if(is_array($settingValue) == FALSE)
|
||||
{
|
||||
$settingValue = json_decode($settingValue);
|
||||
}
|
||||
// skipping __metadata entries (?)
|
||||
if (count($setting) > 3 && is_array($settingValue) == true) {
|
||||
foreach ($settingValue as $val) {
|
||||
$temp .= "'" . encode_single_quotes($val) . "',";
|
||||
}
|
||||
|
||||
if ($group == $settingGroup) {
|
||||
if ($settingType == 'text' || $settingType == 'password' || $settingType == 'password.SHA256' || $settingType == 'readonly' || $settingType == 'text.select') {
|
||||
$val = encode_single_quotes($settingValue);
|
||||
$txt .= $settingKey . "='" . $val . "'\n";
|
||||
} elseif ($settingType == 'integer' || $settingType == 'integer.select') {
|
||||
$txt .= $settingKey . "=" . $settingValue . "\n";
|
||||
} elseif ($settingType == 'boolean' || $settingType == 'integer.checkbox') {
|
||||
$temp = substr_replace($temp, "", -1); // remove last comma ','
|
||||
}
|
||||
|
||||
if ($settingValue === true || $settingValue === 1 || strtolower($settingValue) === 'true') {
|
||||
$val = "True";
|
||||
} else {
|
||||
$val = "False";
|
||||
}
|
||||
|
||||
$txt .= $settingKey . "=" . $val . "\n";
|
||||
} elseif ($settingType == 'text.multiselect' || $settingType == 'subnets' || $settingType == 'list' || $settingType == 'list.select') {
|
||||
$temp = '';
|
||||
|
||||
if(is_array($settingValue) == FALSE)
|
||||
{
|
||||
$settingValue = json_decode($settingValue);
|
||||
}
|
||||
|
||||
if (count($setting) > 3 && is_array($settingValue) == true) {
|
||||
foreach ($settingValue as $val) {
|
||||
$temp .= "'" . encode_single_quotes($val) . "',";
|
||||
}
|
||||
|
||||
$temp = substr_replace($temp, "", -1); // remove last comma ','
|
||||
}
|
||||
|
||||
$temp = '['.$temp.']'; // wrap brackets
|
||||
$txt .= $settingKey . "=" . $temp . "\n";
|
||||
} elseif ($settingType == 'json') {
|
||||
$txt .= $settingKey . "=" . $settingValue . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
$temp = '['.$temp.']'; // wrap brackets
|
||||
$txt .= $settingKey . "=" . $temp . "\n";
|
||||
|
||||
} else {
|
||||
$txt .= $settingKey . "='⭕Not handled⭕'\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
require dirname(__FILE__).'/../templates/timezone.php';
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Check if the action parameter is set in the GET request
|
||||
if (isset($_GET['action'])) {
|
||||
// Collect GUID if provided
|
||||
@@ -46,6 +46,8 @@ if (isset($_GET['action'])) {
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Generates a random GUID
|
||||
function generate_guid() {
|
||||
if (function_exists('com_create_guid') === true) {
|
||||
return trim(com_create_guid(), '{}');
|
||||
@@ -54,8 +56,10 @@ function generate_guid() {
|
||||
mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535),
|
||||
mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535),
|
||||
mt_rand(0, 65535), mt_rand(0, 65535));
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Logs a notification in in-app notification system
|
||||
function write_notification($content, $level = "interrupt") {
|
||||
$NOTIFICATION_API_FILE = '/app/front/api/user_notifications.json';
|
||||
|
||||
@@ -87,6 +91,8 @@ function write_notification($content, $level = "interrupt") {
|
||||
file_put_contents($NOTIFICATION_API_FILE, json_encode($notifications));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Removes a notification based on GUID
|
||||
function remove_notification($guid) {
|
||||
$NOTIFICATION_API_FILE = '/app/front/api/user_notifications.json';
|
||||
|
||||
@@ -102,6 +108,8 @@ function remove_notification($guid) {
|
||||
file_put_contents($NOTIFICATION_API_FILE, json_encode(array_values($filtered_notifications)));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Deletes all notifications
|
||||
function notifications_clear() {
|
||||
$NOTIFICATION_API_FILE = '/app/front/api/user_notifications.json';
|
||||
|
||||
@@ -109,6 +117,8 @@ function notifications_clear() {
|
||||
file_put_contents($NOTIFICATION_API_FILE, json_encode(array()));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Mark a notification read based on GUID
|
||||
function mark_notification_as_read($guid) {
|
||||
$NOTIFICATION_API_FILE = '/app/front/api/user_notifications.json';
|
||||
$max_attempts = 3;
|
||||
@@ -152,10 +162,12 @@ function mark_notification_as_read($guid) {
|
||||
echo "Failed to read notification file after $max_attempts attempts.";
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
function notifications_mark_all_read() {
|
||||
mark_notification_as_read(null);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
function get_unread_notifications() {
|
||||
$NOTIFICATION_API_FILE = '/app/front/api/user_notifications.json';
|
||||
|
||||
|
||||
35
front/php/templates/auth.php
Executable file
35
front/php/templates/auth.php
Executable file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
$isAuthenticated = false;
|
||||
|
||||
// Check if the user is logged in
|
||||
if (isset($_SESSION["login"]) && $_SESSION["login"] == 1) {
|
||||
$isAuthenticated = true;
|
||||
}
|
||||
|
||||
// $current_directory = __DIR__;
|
||||
// echo "Current directory: " . $current_directory;
|
||||
|
||||
// Check if a valid cookie is present
|
||||
$CookieSaveLoginName = "NetAlertX_SaveLogin";
|
||||
$config_file = "../../../config/app.conf"; // depends on where this file is called from
|
||||
$config_file_lines = file($config_file);
|
||||
$config_file_lines = array_values(preg_grep('/^SETPWD_password.*=/', $config_file_lines));
|
||||
$password_line = explode("'", $config_file_lines[0]);
|
||||
$Pia_Password = $password_line[1];
|
||||
|
||||
if (isset($_COOKIE[$CookieSaveLoginName]) && $Pia_Password == $_COOKIE[$CookieSaveLoginName]) {
|
||||
$isAuthenticated = true;
|
||||
}
|
||||
|
||||
if ($isAuthenticated) {
|
||||
echo 'Authorized 200';
|
||||
http_response_code(200);
|
||||
exit; // Important: Ensure script exits after successful authentication
|
||||
} else {
|
||||
http_response_code(401);
|
||||
echo 'Unauthorized 401';
|
||||
exit; // Ensure script exits after failed authentication
|
||||
}
|
||||
?>
|
||||
@@ -55,7 +55,7 @@
|
||||
<!-- NetAlertX -->
|
||||
<script src="js/handle_version.js"></script>
|
||||
<script src="js/ui_components.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||
<script src="js/db_methods.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||
|
||||
|
||||
<!-- Select2 JavaScript -->
|
||||
<script src="lib/AdminLTE/bower_components/select2/dist/js/select2.full.min.js" defer></script>
|
||||
|
||||
@@ -33,6 +33,8 @@ require dirname(__FILE__).'/security.php';
|
||||
<script src="js/common.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||
<script src="js/modal.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||
<script src="js/tests.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||
<script src="js/db_methods.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||
<script src="js/settings_utils.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||
|
||||
<!-- Bootstrap 3.3.7 -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/bootstrap/dist/css/bootstrap.min.css">
|
||||
@@ -339,7 +341,7 @@ if ($ENABLED_DARKMODE === True) {
|
||||
</a>
|
||||
<ul class="treeview-menu" style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('settings.php') ) ){ echo 'block'; } else {echo 'none';} ?>;">
|
||||
<li>
|
||||
<a href="settings.php#pageTitle"> <?= lang("settings_enabled");?> </a>
|
||||
<a href="settings.php#settingsOverview"> <?= lang("settings_enabled");?> </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="settings.php#core_content_header"> <?= lang("settings_core_label");?> </a>
|
||||
@@ -348,13 +350,13 @@ if ($ENABLED_DARKMODE === True) {
|
||||
<a href="settings.php#system_content_header"> <?= lang("settings_system_label");?> </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="settings.php#device_scanner_content_header"> <?= lang("settings_device_scanners_label");?> </a>
|
||||
<a href="settings.php#device_scanners_content_header"> <?= lang("settings_device_scanners_label");?> </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="settings.php#other_content_header"> <?= lang("settings_other_scanners_label");?> </a>
|
||||
<a href="settings.php#other_scanners_content_header"> <?= lang("settings_other_scanners_label");?> </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="settings.php#publisher_content_header"> <?= lang("settings_publishers_label");?> </a>
|
||||
<a href="settings.php#publishers_content_header"> <?= lang("settings_publishers_label");?> </a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
@@ -370,7 +372,7 @@ if ($ENABLED_DARKMODE === True) {
|
||||
</a>
|
||||
<ul class="treeview-menu " style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('plugins.php', 'workflows.php' ) ) ){ echo 'block'; } else {echo 'none';} ?>;">
|
||||
<li>
|
||||
<div class="info-icon-nav work-in-progress"> </div>
|
||||
<div class="info-icon-nav"> </div>
|
||||
<a href="workflows.php"><?= lang('Navigation_Workflows');?></a>
|
||||
</li>
|
||||
<li>
|
||||
@@ -414,7 +416,7 @@ if ($ENABLED_DARKMODE === True) {
|
||||
// Generate work-in-progress icons
|
||||
function workInProgress() {
|
||||
|
||||
if($(".work-in-progress").html().trim() == "")
|
||||
if($(".work-in-progress").length > 0 && $(".work-in-progress").html().trim() == "")
|
||||
{
|
||||
$(".work-in-progress").append(`
|
||||
<a href="https://github.com/jokob-sk/NetAlertX/issues" target="_blank">
|
||||
|
||||
44
front/php/templates/language/de_de.json
Executable file → Normal file
44
front/php/templates/language/de_de.json
Executable file → Normal file
@@ -5,7 +5,7 @@
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"APPRISE_HOST_description": "Apprise host URL starting with <code>http://</code> or <code>https://</code>. (do not forget to include <code>/notify</code> at the end)",
|
||||
"APPRISE_HOST_name": "Apprise host URL",
|
||||
"APPRISE_PAYLOAD_description": "Select the payoad type sent to Apprise. For example <code>html</code> works well with emails, <code>text</code> with chat apps, such as Telegram.",
|
||||
"APPRISE_PAYLOAD_description": "Select the payload type sent to Apprise. For example <code>html</code> works well with emails, <code>text</code> with chat apps, such as Telegram.",
|
||||
"APPRISE_PAYLOAD_name": "Payload type",
|
||||
"APPRISE_SIZE_description": "The maximum size of the apprise payload as number of characters in the passed string. If above limit, it will be truncated and a <code>(text was truncated)</code> message is appended.",
|
||||
"APPRISE_SIZE_name": "Max payload size",
|
||||
@@ -13,7 +13,7 @@
|
||||
"APPRISE_URL_name": "Apprise notification URL",
|
||||
"About_Design": "Designed for:",
|
||||
"About_Exit": "Abmelden",
|
||||
"About_Title": "Open Source Network Guard",
|
||||
"About_Title": "Netzwerksicherheitsscanner und Benachrichtigungsframework",
|
||||
"AppEvents_DateTimeCreated": "protokolliert",
|
||||
"AppEvents_Extra": "Extra",
|
||||
"AppEvents_GUID": "Anwendungsereignis-GUID",
|
||||
@@ -93,17 +93,17 @@
|
||||
"DevDetail_MainInfo_Group": "Gruppe",
|
||||
"DevDetail_MainInfo_Location": "Standort",
|
||||
"DevDetail_MainInfo_Name": "Name",
|
||||
"DevDetail_MainInfo_Network": "Netzwerk Knoten",
|
||||
"DevDetail_MainInfo_Network_Port": "Netzwerk Knoten Port",
|
||||
"DevDetail_MainInfo_Network": "<i class=\"fa fa-server\"></i> Knoten (MAC)",
|
||||
"DevDetail_MainInfo_Network_Port": "<i class=\"fa fa-ethernet\"></i> Port",
|
||||
"DevDetail_MainInfo_Network_Site": "",
|
||||
"DevDetail_MainInfo_Network_Title": "<i class=\"fa fa-network-wired\"></i> Network",
|
||||
"DevDetail_MainInfo_Owner": "Eigen­tümer",
|
||||
"DevDetail_MainInfo_SSID": "",
|
||||
"DevDetail_MainInfo_Title": "Haupt Infos",
|
||||
"DevDetail_MainInfo_Title": "<i class=\"fa fa-pencil\"></i> Hauptinformation",
|
||||
"DevDetail_MainInfo_Type": "Typ",
|
||||
"DevDetail_MainInfo_Vendor": "Hersteller",
|
||||
"DevDetail_MainInfo_mac": "MAC",
|
||||
"DevDetail_Network_Node_hover": "Select the parent network device the current device is connected to to populate the Network tree.",
|
||||
"DevDetail_Network_Node_hover": "Wählen Sie das Elternnetzgerät aus, an das das aktuelle Gerät angeschlossen ist, um den Netzwerkbaum zu erstellen.",
|
||||
"DevDetail_Network_Port_hover": "The port this device is connected to on the parent network device. If left empty a wifi icon is displayed in the Network tree.",
|
||||
"DevDetail_Nmap_Scans": "Nmap Scans",
|
||||
"DevDetail_Nmap_Scans_desc": "Hier kannst du manuelle NMAP Scans starten. Reguläre automatische NMAP Scans können mit dem Services & Ports (NMAP) Plugin geplant werden. Gehe zu den <a href='/settings.php' target='_blank'>Einstellungen</a> um mehr herauszufinden.",
|
||||
@@ -129,7 +129,7 @@
|
||||
"DevDetail_SessionInfo_LastSession": "Letzte Sitzung",
|
||||
"DevDetail_SessionInfo_StaticIP": "Statische IP",
|
||||
"DevDetail_SessionInfo_Status": "Status",
|
||||
"DevDetail_SessionInfo_Title": "Sitzungsinfos",
|
||||
"DevDetail_SessionInfo_Title": "<i class=\"fa fa-calendar\"></i> Sitzungsinformation",
|
||||
"DevDetail_SessionTable_Additionalinfo": "Zusätzliche Info",
|
||||
"DevDetail_SessionTable_Connection": "Verbindung",
|
||||
"DevDetail_SessionTable_Disconnection": "Trennung",
|
||||
@@ -140,13 +140,13 @@
|
||||
"DevDetail_Shortcut_DownAlerts": "Down Meldungen",
|
||||
"DevDetail_Shortcut_Presence": "Anwesenheit",
|
||||
"DevDetail_Shortcut_Sessions": "Sitzungen",
|
||||
"DevDetail_Tab_Details": "Details",
|
||||
"DevDetail_Tab_Events": "Ereignisse",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Details",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Ereignisse",
|
||||
"DevDetail_Tab_EventsTableDate": "Datum",
|
||||
"DevDetail_Tab_EventsTableEvent": "Ereignistype",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
"DevDetail_Tab_EventsTableInfo": "Zusätzliche Informationen",
|
||||
"DevDetail_Tab_Nmap": "Nmap",
|
||||
"DevDetail_Tab_Nmap": "<i class=\"fa fa-ethernet\"></i> Nmap",
|
||||
"DevDetail_Tab_NmapEmpty": "An diesem Gerät wurden keine offenen Ports mit Nmap gefunden.",
|
||||
"DevDetail_Tab_NmapTableExtra": "Extra",
|
||||
"DevDetail_Tab_NmapTableHeader": "Ergebnisse geplanter Scans",
|
||||
@@ -157,8 +157,8 @@
|
||||
"DevDetail_Tab_NmapTableText": "Erstelle einen Plan über die<a href=\"/settings.php#NMAP_ACTIVE\">Einstellungen</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Zeit",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Plugins",
|
||||
"DevDetail_Tab_Presence": "Anwesenheit",
|
||||
"DevDetail_Tab_Sessions": "Sitzungen",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Anwesenheit",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sitzungen",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Tools",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Description": "Das Internet-Info-Tool zeigt Informationen über die Internetverbindung an, wie z. B. IP-Adresse, Stadt, Land, Ortsvorwahl und Zeitzone.",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Error": "Es ist ein Fehler aufgetreten",
|
||||
@@ -314,17 +314,17 @@
|
||||
"Gen_Work_In_Progress": "Keine Finalversion, feedback bitte unter: https://github.com/jokob-sk/NetAlertX/issues",
|
||||
"General_display_name": "Allgemein",
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Dies ist eine Wartungseinstellung. Geräte markiert als <b>Neues Gerät</b> werden gelöscht, wenn ihre <b>Erste Sitzung</b> länger her ist als die angegebenen Stunden in dieser Einstellung. <code>0</code> deaktiviert diese Funktion. Nutzen Sie diese Einstellung, um <b>Neue Geräte</b> automatisch nach <code>X</code> Stunden zu löschen.",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Dies ist eine Wartungseinstellung. Wenn aktiviert (<code>0</code> bedeutet deaktiviert), werden als <b>\"Neues Gerät\"</b> markierte Geräte gelöscht, wenn ihre <b>erste Sitzung</b> länger her ist als in dieser Einstellung angegeben. Verwenden Sie diese Einstellung, wenn Sie <b>Neue Geräte</b> nach <code>X</code> Stunden automatisch löschen wollen.",
|
||||
"HRS_TO_KEEP_NEWDEV_name": "Neue Geräte speichern für",
|
||||
"HelpFAQ_Cat_Detail": "Detailansicht",
|
||||
"HelpFAQ_Cat_Detail_300_head": "Was bedeutet ",
|
||||
"HelpFAQ_Cat_Detail_300_text_a": "meint ein Netzwerkgerät (welches den typ AP, Gateway, Firewall, Hypervisor, Powerline, Switch, WLAN, PLC, Router,USB LAN Adapter, USB WIFI Adapter, or Internet eingestellt hat)",
|
||||
"HelpFAQ_Cat_Detail_300_text_a": "meint ein Netzwerkgerät (ein Gerät vom Typ AP, Gateway, Firewall, Hypervisor, Powerline, Switch, WLAN, PLC, Router, USB-LAN-Adapter oder Internet). Benutzerdefinierte Typen können über die <code>NETWORK_DEVICE_TYPES</code> Einstellung hinzugefügt werden.",
|
||||
"HelpFAQ_Cat_Detail_300_text_b": "bezeichnet die Anschlussnummer/Portnummer, an der das gerade bearbeitete Gerät mit diesem Netzwerkgerät verbunden ist. Siehe <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md\">diese Dokumentation</a> für mehr informationen.",
|
||||
"HelpFAQ_Cat_Detail_301_head_a": "Wann wird nun gescannt? Bei ",
|
||||
"HelpFAQ_Cat_Detail_301_head_b": " steht 1min aber der Graph zeigt 5min - Abstände an.",
|
||||
"HelpFAQ_Cat_Detail_301_text": "Den zeitlichen Abstand zwischen den Scans legt der \"Cronjob\" fest, welcher standardmäßig auf 5min eingestellt ist. Die Benennung \"1min\" bezieht sich auf die zu erwartende Dauer des Scans. Abhängig vor der Netzwerkkonfiguration kann diese Zeitangabe variieren. Um den Cronjob zu bearbeiten, kannst du im Terminal/der Konsole <span class=\"text-danger help_faq_code\">crontab -e</span> eingeben und den Intervall ändern.",
|
||||
"HelpFAQ_Cat_Detail_302_head_a": "Was bedeutet ",
|
||||
"HelpFAQ_Cat_Detail_302_head_b": " und warum kann ich das nicht auswählen?",
|
||||
"HelpFAQ_Cat_Detail_302_head_b": "und warum kann ich das nicht auswählen?",
|
||||
"HelpFAQ_Cat_Detail_302_text": "Einige moderne Geräte generieren aus Datenschutzgründen zufällige MAC-Adressen, die keinem Hersteller mehr zugeordnet werden können und welche sich mit jeder neuen Verbindung ändern. NetAlertX erkennt, ob es sich um eine solche zufällige MAC-Adresse handelt und aktiviert dieses \"Feld\" automatisch. Um das Verhalten abzustellen, musst du in deinem Endgerät schauen, wie du die MAC-Adressen-Generierung deaktivierst.",
|
||||
"HelpFAQ_Cat_Detail_303_head": "Was ist Nmap und wozu dient es?",
|
||||
"HelpFAQ_Cat_Detail_303_text": "Nmap ist ein Netzwerkscanner mit vielfältigen Möglichkeiten.<br> Wenn ein neues Gerät in deiner Liste auftaucht, hast du die Möglichkeit über den Nmap-Scan genauere Informationen über das Gerät zu erhalten.",
|
||||
@@ -384,17 +384,23 @@
|
||||
"MQTT_USER_name": "MQTT user",
|
||||
"MQTT_display_name": "MQTT",
|
||||
"MQTT_icon": "<i class=\"fa fa-square-rss\"></i>",
|
||||
"Maint_PurgeLog": "",
|
||||
"Maint_RestartServer": "",
|
||||
"Maint_Restart_Server_noti_text": "",
|
||||
"Maintenance_Running_Version": "Installierte Version",
|
||||
"Maintenance_Status": "Status",
|
||||
"Maintenance_Title": "Wartungswerkzeuge",
|
||||
"Maintenance_Tool_ExportCSV": "CSV Export",
|
||||
"Maintenance_Tool_ExportCSV_noti": "CSV Export",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Sind Sie sich sicher, dass Sie die CSV-Datei erstellen wollen?",
|
||||
"Maintenance_Tool_ExportCSV_text": "Generiere eine CSV-Datei (comma separated values) mit einer Liste aller Geräte und deren Beziehungen zwischen Netzwerkknoten und verbundenen Geräten. Dies kann auch durch das Besuchen dieser URL <code>your NetAlertX url/php/server/devices.php?action=ExportCSV</code> ausgelöst werden.",
|
||||
"Maintenance_Tool_ExportCSV_text": "Generiere eine CSV-Datei (comma separated values) mit einer Liste aller Geräte und deren Beziehungen zwischen Netzwerkknoten und verbundenen Geräten. Dies kann auch durch das Besuchen der URL <code>your NetAlertX url/php/server/devices.php?action=ExportCSV</code> oder durch Aktivieren des <a href=\"settings.php#CSVBCKP_header\">CSV-Backups</a> ausgelöst werden.",
|
||||
"Maintenance_Tool_ImportCSV": "CSV Import",
|
||||
"Maintenance_Tool_ImportCSV_noti": "CSV Import",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Sind Sie sich sicher, dass Sie die CSV-Datei importieren wollen? Dies wird alle Geräte in der Datenbank überschreiben.",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Sind Sie sich sicher, dass Sie die CSV-Datei importieren wollen? Dies wird <b>alle Geräte in der Datenbank überschreiben</b>.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Machen Sie ein Backup, bevor Sie diese Funktion nutzen. Importiere eine CSV-Datei (comma separated values) mit einer Liste aller Geräte und deren Beziehungen zwischen Netzwerkknoten und verbundenen Geräten. Um dies zu tun platziere die <b>devices.csv</b> benannte CSV-Datei in deinen <b>/config</b> Ordner.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_arpscansw": "arp-Scan stoppen/starten",
|
||||
"Maintenance_Tool_arpscansw_noti": "arp-Scan stoppen/starten",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Wenn der Scan aus ist, bleibt er so lange aus bis er wieder aktiviert wird.",
|
||||
@@ -730,7 +736,7 @@
|
||||
"Webhooks_display_name": "Webhooks",
|
||||
"Webhooks_icon": "<i class=\"fa fa-circle-nodes\"></i>",
|
||||
"devices_old": "Aktualisiert...",
|
||||
"general_event_description": " The event you have triggered might take a while until background processes finish. The execution ended once you see <code>finished</code> below. Check the <a href='/maintenance.php#tab_Logging'>error log</a> if you didn not get the expected result. <br/> <br/> Status: ",
|
||||
"general_event_description": "Das Ereignis, das Sie ausgelöst haben, könnte eine Weile dauern, bis Hintergrundprozesse abgeschlossen sind. Die Ausführung endet, wenn die unten ausgeführte Warteschlangen abgearbeitet ist. (Siehe <a href='/maintenance.php#tab_Logging'>error log</a>, wenn Probleme auftreten.)<br/> <br/> Ausführungsschlange:",
|
||||
"general_event_title": "Executing an ad-hoc event",
|
||||
"report_guid": "",
|
||||
"report_guid_missing": "",
|
||||
@@ -765,4 +771,4 @@
|
||||
"settings_update_item_warning": "",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Save your changes at first before you test your settings."
|
||||
}
|
||||
}
|
||||
|
||||
12
front/php/templates/language/en_us.json
Executable file → Normal file
12
front/php/templates/language/en_us.json
Executable file → Normal file
@@ -358,6 +358,9 @@
|
||||
"Login_Toggle_Alert_headline": "Password Alert!",
|
||||
"Login_Toggle_Info": "Password Information",
|
||||
"Login_Toggle_Info_headline": "Password Information",
|
||||
"Maint_PurgeLog": "Purge log",
|
||||
"Maint_RestartServer": "Restart server",
|
||||
"Maint_Restart_Server_noti_text": "Are you sure you want to restart the backend server? This may casue app inconsistency. Backup your setup first. <br/> <br/> Note: This may take a few minutes.",
|
||||
"Maintenance_Running_Version": "Installed version",
|
||||
"Maintenance_Status": "Status",
|
||||
"Maintenance_Title": "Maintenance tools",
|
||||
@@ -367,8 +370,11 @@
|
||||
"Maintenance_Tool_ExportCSV_text": "Generate a CSV (comma separated value) file containing the list of Devices including the Network relationships between Network Nodes and connected devices. You can also trigger this by accessing this URL <code>your NetAlertX url/php/server/devices.php?action=ExportCSV</code> or by enabling the <a href=\"settings.php#CSVBCKP_header\">CSV Backup</a> plugin.",
|
||||
"Maintenance_Tool_ImportCSV": "CSV Import",
|
||||
"Maintenance_Tool_ImportCSV_noti": "CSV Import",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Are you sure you want to import the CSV file? This will completely overwrite the devices in your database.",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Are you sure you want to import the CSV file? This will completely <b>overwrite</b> the devices in your database.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Before using this function, please make a backup. Import a CSV (comma separated value) file containing the list of Devices including the Network relationships between Network Nodes and connected devices. To do that place the CSV file named <b>devices.csv</b> into your <b>/config</b> folder.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "CSV Import (Paste)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "Are you sure you want to import the pasted CSV? This will completely <b>overwrite</b> the devices in your database.",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "Before using this function, please make a backup. Import a CSV (comma separated value) file containing the list of Devices including the Network relationships between Network Nodes and connected devices.",
|
||||
"Maintenance_Tool_arpscansw": "Toggle arp-Scan (on/off)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Toggle arp-Scan on or off",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "When the scan has been switched off it remains off until it is activated again.",
|
||||
@@ -649,7 +655,7 @@
|
||||
"UI_REFRESH_description": "Enter number of seconds after which the UI reloads. Set to <code>0</code> to disable.",
|
||||
"UI_REFRESH_name": "Auto-refresh UI",
|
||||
"devices_old": "Refreshing...",
|
||||
"general_event_description": "The event you have triggered might take a while until background processes finish. The execution ended once the below execution queue empties (Check the <a href='/maintenance.php#tab_Logging'>error log</a> if you encounter issues). <br/> <br/> Execution queue:",
|
||||
"general_event_description": "The event you have triggered might take a while until background processes finish. The execution ended once the below execution queue empties (Check the <a href='/maintenance.php#tab_Logging'>error log</a> if you encounter issues). <br/> <br/> Execution queue:",
|
||||
"general_event_title": "Executing an ad-hoc event",
|
||||
"report_guid": "Notification guid:",
|
||||
"report_guid_missing": "Linked notification not found. There is a small delay between recently sent notifications and them being available. Referesh your page and cache after a few seconds. It's also possible the selected notification have been deleted during maintenance as specified in the <code>DBCLNP_NOTIFI_HIST</code> setting. <br/> <br/>The latest notification is displayed instead. The missing notification has the following GUID:",
|
||||
@@ -684,4 +690,4 @@
|
||||
"settings_update_item_warning": "Update the value below. Be careful to follow the previous format. <b>Validation is not performed.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Save your changes at first before you test your settings."
|
||||
}
|
||||
}
|
||||
|
||||
22
front/php/templates/language/es_es.json
Executable file → Normal file
22
front/php/templates/language/es_es.json
Executable file → Normal file
@@ -93,10 +93,10 @@
|
||||
"DevDetail_MainInfo_Name": "Nombre",
|
||||
"DevDetail_MainInfo_Network": "<i class=\"fa fa-server\"></i> Nodo (MAC)",
|
||||
"DevDetail_MainInfo_Network_Port": "<i class=\"fa fa-ethernet\"></i> Puerto de Red HW",
|
||||
"DevDetail_MainInfo_Network_Site": "",
|
||||
"DevDetail_MainInfo_Network_Site": "Lugar",
|
||||
"DevDetail_MainInfo_Network_Title": "<i class=\"fa fa-network-wired\"></i> Red",
|
||||
"DevDetail_MainInfo_Owner": "Propietario",
|
||||
"DevDetail_MainInfo_SSID": "",
|
||||
"DevDetail_MainInfo_SSID": "SSID",
|
||||
"DevDetail_MainInfo_Title": "<i class=\"fa fa-pencil\"></i> Información principal",
|
||||
"DevDetail_MainInfo_Type": "Tipo",
|
||||
"DevDetail_MainInfo_Vendor": "Proveedor",
|
||||
@@ -218,13 +218,13 @@
|
||||
"Device_TableHead_MAC": "MAC aleatoria",
|
||||
"Device_TableHead_MAC_full": "MAC completa",
|
||||
"Device_TableHead_Name": "Nombre",
|
||||
"Device_TableHead_NetworkSite": "",
|
||||
"Device_TableHead_NetworkSite": "Lugar de la red",
|
||||
"Device_TableHead_Owner": "Propietario",
|
||||
"Device_TableHead_Parent_MAC": "Nodo principal de la MAC",
|
||||
"Device_TableHead_Port": "Puerto",
|
||||
"Device_TableHead_RowID": "Row ID",
|
||||
"Device_TableHead_Rowid": "Row ID",
|
||||
"Device_TableHead_SSID": "",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_Status": "Situación",
|
||||
"Device_TableHead_SyncHubNodeName": "Nodo de sincronización",
|
||||
"Device_TableHead_Type": "Tipo",
|
||||
@@ -280,7 +280,7 @@
|
||||
"Gen_Action": "Acción",
|
||||
"Gen_Add": "Añadir",
|
||||
"Gen_Add_All": "Añadir todo",
|
||||
"Gen_All_Devices": "",
|
||||
"Gen_All_Devices": "Todo los dispositivos",
|
||||
"Gen_AreYouSure": "¿Estás seguro?",
|
||||
"Gen_Backup": "Ejecutar copia de seguridad",
|
||||
"Gen_Cancel": "Cancelar",
|
||||
@@ -382,6 +382,9 @@
|
||||
"MQTT_USER_name": "Usuario de MQTT",
|
||||
"MQTT_display_name": "MQTT",
|
||||
"MQTT_icon": "<i class=\"fa fa-square-rss\"></i>",
|
||||
"Maint_PurgeLog": "Purgar los registros",
|
||||
"Maint_RestartServer": "Restablecer el servidor",
|
||||
"Maint_Restart_Server_noti_text": "¿Estás seguro de que desea reiniciar el servidor backend? Esto puede causar inconsistencia en la aplicación. Primero haga una copia de seguridad de su configuración.<br/> <br/> Nota: Esto puede tardar unos minutos.",
|
||||
"Maintenance_Running_Version": "Versión instalada",
|
||||
"Maintenance_Status": "Situación",
|
||||
"Maintenance_Title": "Herramientas de mantenimiento",
|
||||
@@ -393,6 +396,9 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "Importación CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "¿Está seguro de que quiere importar el archivo CSV? Esto sobrescribirá completamente los dispositivos de su base de datos.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Antes de usar esta función, haga una copia de seguridad. Importe un archivo CSV (valor separado por comas) que contiene la lista de dispositivos, incluidas las relaciones de red entre nodos de red y dispositivos conectados. Para hacer eso, coloque el archivo CSV llamado <b> devices.csv </b> en su carpeta <b>/config </b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_arpscansw": "Activar arp-scan (on/off)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Activar arp-scan on or off",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Cuando el escaneo se ha apagado, permanece apagado hasta que se active nuevamente.",
|
||||
@@ -741,7 +747,7 @@
|
||||
"settings_core_label": "Núcleo",
|
||||
"settings_device_scanners": "Los escáneres de los dispositivos se utilizan para descubrir dispositivos que escriben en la tabla de base de datos de CurrentScan.",
|
||||
"settings_device_scanners_icon": "fa-solid fa-magnifying-glass-plus",
|
||||
"settings_device_scanners_info": "",
|
||||
"settings_device_scanners_info": "Cargue aún más escáneres de dispositivos con el ajuste <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
|
||||
"settings_device_scanners_label": "Escáneres de dispositivos",
|
||||
"settings_enabled": "Configuración activada",
|
||||
"settings_enabled_icon": "fa-solid fa-toggle-on",
|
||||
@@ -756,7 +762,7 @@
|
||||
"settings_other_scanners_label": "Otros escáneres",
|
||||
"settings_publishers": "Puertas de enlace para las notificación habilitadas: editores, que enviarán una notificación según su configuración.",
|
||||
"settings_publishers_icon": "fa-solid fa-paper-plane",
|
||||
"settings_publishers_info": "",
|
||||
"settings_publishers_info": "Cargue más editor@s con el ajuste <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
|
||||
"settings_publishers_label": "Editores",
|
||||
"settings_saved": "<br/>Ajustes guardados. <br/><br/> Recargando... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
|
||||
"settings_system_icon": "fa-solid fa-gear",
|
||||
@@ -764,4 +770,4 @@
|
||||
"settings_update_item_warning": "Actualice el valor a continuación. Tenga cuidado de seguir el formato anterior. <b>O la validación no se realiza.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Guarda tus cambios antes de probar nuevos ajustes."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "",
|
||||
"API_CUSTOM_SQL_description": "Vous pouvez specifier votre propre requête SQL qui retournera un fichier JSON et l'exposer via <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> file endpoint</a>.",
|
||||
"API_CUSTOM_SQL_name": "Point de terminaison personnalisé",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"About_Design": "Conçu pour :",
|
||||
"About_Exit": "Quitter",
|
||||
"About_Title": "Analyse de la sécurité du réseau et cadre de notification",
|
||||
"AppEvents_DateTimeCreated": "Journalisé",
|
||||
"AppEvents_Extra": "Extra",
|
||||
"AppEvents_GUID": "",
|
||||
"AppEvents_Helper1": "",
|
||||
"AppEvents_Helper2": "",
|
||||
"AppEvents_Helper3": "",
|
||||
"AppEvents_Helper1": "Helper 1",
|
||||
"AppEvents_Helper2": "Helper 2",
|
||||
"AppEvents_Helper3": "Helper 3",
|
||||
"AppEvents_ObjectForeignKey": "Clé étrangère",
|
||||
"AppEvents_ObjectIndex": "Index",
|
||||
"AppEvents_ObjectIsArchived": "Est archivé (au moment de l'enregistrement)",
|
||||
"AppEvents_ObjectIsNew": "",
|
||||
"AppEvents_ObjectIsNew": "nouveau (au moment de l'enregistrement dans le journal)",
|
||||
"AppEvents_ObjectPlugin": "Greffon lié",
|
||||
"AppEvents_ObjectPrimaryID": "",
|
||||
"AppEvents_ObjectSecondaryID": "",
|
||||
"AppEvents_ObjectStatus": "Statut (au moment de l'enregistrement)",
|
||||
"AppEvents_ObjectPrimaryID": "Identité primaire",
|
||||
"AppEvents_ObjectSecondaryID": "Indentité secondaire",
|
||||
"AppEvents_ObjectStatus": "Status (au moment de l'enregistrement)",
|
||||
"AppEvents_ObjectStatusColumn": "Colonne d'état",
|
||||
"AppEvents_ObjectType": "Type d'objet",
|
||||
"AppEvents_Plugin": "Greffon",
|
||||
"AppEvents_Type": "Type",
|
||||
"BackDevDetail_Actions_Ask_Run": "",
|
||||
"BackDevDetail_Actions_Not_Registered": "",
|
||||
"BackDevDetail_Actions_Title_Run": "",
|
||||
"BackDevDetail_Copy_Ask": "",
|
||||
"BackDevDetail_Actions_Ask_Run": "Voulez vous executer cette commande ?",
|
||||
"BackDevDetail_Actions_Not_Registered": "Action non enregistrée ",
|
||||
"BackDevDetail_Actions_Title_Run": "Execute Action",
|
||||
"BackDevDetail_Copy_Ask": "Copie les details des objets selectioné dans la liste (tout ce qui est sur cette page sura remplacé)?",
|
||||
"BackDevDetail_Copy_Title": "Copier les détails",
|
||||
"BackDevDetail_Tools_WOL_error": "",
|
||||
"BackDevDetail_Tools_WOL_okay": "",
|
||||
"BackDevices_Arpscan_disabled": "",
|
||||
"BackDevices_Arpscan_enabled": "",
|
||||
"BackDevices_Backup_CopError": "",
|
||||
"BackDevices_Backup_Failed": "",
|
||||
"BackDevDetail_Tools_WOL_error": "Cette commande N'A PAS été exécutée.",
|
||||
"BackDevDetail_Tools_WOL_okay": "Commande Exécutée.",
|
||||
"BackDevices_Arpscan_disabled": "Arp-Scan Suspendu",
|
||||
"BackDevices_Arpscan_enabled": "Apr-Scan Activé",
|
||||
"BackDevices_Backup_CopError": "La base de donnée initiale n'a pas pu être sauvegardée.",
|
||||
"BackDevices_Backup_Failed": "La sauvegarde a été partiellement complétée. L'archive n'a pas pu être crée ou est vide.",
|
||||
"BackDevices_Backup_okay": "",
|
||||
"BackDevices_DBTools_DelDevError_a": "Erreur lors de la suppression de l'appareil",
|
||||
"BackDevices_DBTools_DelDevError_b": "Erreur lors de la suppression des appareils",
|
||||
@@ -358,6 +358,9 @@
|
||||
"Login_Toggle_Alert_headline": "",
|
||||
"Login_Toggle_Info": "",
|
||||
"Login_Toggle_Info_headline": "",
|
||||
"Maint_PurgeLog": "",
|
||||
"Maint_RestartServer": "",
|
||||
"Maint_Restart_Server_noti_text": "",
|
||||
"Maintenance_Running_Version": "Version installée",
|
||||
"Maintenance_Status": "État",
|
||||
"Maintenance_Title": "Outils d'entretien",
|
||||
@@ -369,6 +372,9 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "Importation CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Êtes-vous sûr de vouloir importer le fichier CSV ? Cela écrasera complètement les appareils de votre base de données.",
|
||||
"Maintenance_Tool_ImportCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_arpscansw": "Basculer l'arp-Scan (activé/désactivé)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Activer ou désactiver l'arp-Scan",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Une fois le scan désactivé, il reste désactivé jusqu'à ce qu'il soit réactivé.",
|
||||
|
||||
10
front/php/templates/language/it_it.json
Executable file → Normal file
10
front/php/templates/language/it_it.json
Executable file → Normal file
@@ -358,6 +358,9 @@
|
||||
"Login_Toggle_Alert_headline": "Avviso password!",
|
||||
"Login_Toggle_Info": "Informazioni password",
|
||||
"Login_Toggle_Info_headline": "Informazioni password",
|
||||
"Maint_PurgeLog": "Elimina log",
|
||||
"Maint_RestartServer": "Riavvia server",
|
||||
"Maint_Restart_Server_noti_text": "Sei sicuro di voler riavviare il server backend? Questo potrebbe causare incoerenze dell'app. Prima esegui il backup della tua configurazione. <br/> <br/> Nota: l'operazione potrebbe richiedere alcuni minuti.",
|
||||
"Maintenance_Running_Version": "Versione installata",
|
||||
"Maintenance_Status": "Stato",
|
||||
"Maintenance_Title": "Strumenti di manutenzione",
|
||||
@@ -369,6 +372,9 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "Importa CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Sei sicuro di voler importare il file CSV? Questa operazione sovrascriverà tutti i dispositivi presenti nel database.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Prima di utilizzare questa funzione, esegui un backup. Importa un file CSV (comma separated value) contenente la lista dei dispositivi incluse le relazioni di rete tra i nodi di rete e i dispositivi connessi. Per far ciò posiziona il file CSV denominato <b>devices.csv</b> nella cartella <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_arpscansw": "Attiva/disattiva arp-Scan",
|
||||
"Maintenance_Tool_arpscansw_noti": "Attiva o disattiva arp-Scan",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Una volta disattivata la scansione rimane disattivata finché non viene nuovamente attivata.",
|
||||
@@ -661,7 +667,7 @@
|
||||
"settings_core_label": "Core",
|
||||
"settings_device_scanners": "Scanner dei dispositivi utilizzati per rilevare i dispositivi che scrivono nella tabella del database CurrentScan.",
|
||||
"settings_device_scanners_icon": "fa-solid fa-magnifying-glass-plus",
|
||||
"settings_device_scanners_info": "",
|
||||
"settings_device_scanners_info": "Carica ancora più scanner di dispositivi con l'impostazione <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
|
||||
"settings_device_scanners_label": "Scanner dispositivi",
|
||||
"settings_enabled": "Impostazioni abilitate",
|
||||
"settings_enabled_icon": "fa-solid fa-toggle-on",
|
||||
@@ -676,7 +682,7 @@
|
||||
"settings_other_scanners_label": "Altri scanner",
|
||||
"settings_publishers": "Gateway/editori di notifica abilitati, che invieranno una notifica in base alle tue impostazioni.",
|
||||
"settings_publishers_icon": "fa-solid fa-paper-plane",
|
||||
"settings_publishers_info": "",
|
||||
"settings_publishers_info": "Carica più editori con l'impostazione <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
|
||||
"settings_publishers_label": "Editori",
|
||||
"settings_saved": "<br/>Impostazioni salvate. <br/> Aggiornamento in corso... <br/> <i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
|
||||
"settings_system_icon": "fa-solid fa-gear",
|
||||
|
||||
@@ -103,7 +103,8 @@ function lang($key)
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
// HTML encode the result before returning
|
||||
return str_replace("'", ''', $result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
8
front/php/templates/language/nb_no.json
Executable file → Normal file
8
front/php/templates/language/nb_no.json
Executable file → Normal file
@@ -358,6 +358,9 @@
|
||||
"Login_Toggle_Alert_headline": "Passord Varsling!",
|
||||
"Login_Toggle_Info": "Passordinformasjon",
|
||||
"Login_Toggle_Info_headline": "Passordinformasjon",
|
||||
"Maint_PurgeLog": "",
|
||||
"Maint_RestartServer": "",
|
||||
"Maint_Restart_Server_noti_text": "",
|
||||
"Maintenance_Running_Version": "Installert versjon",
|
||||
"Maintenance_Status": "Status",
|
||||
"Maintenance_Title": "Vedlikeholdsverktøy",
|
||||
@@ -369,6 +372,9 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "Importer CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Er du sikker på at du vil importere CSV-filen? Dette vil fullstendig overskrive enhetene i databasen din.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Før du bruker denne funksjonen, vennligst ta en sikkerhetskopi. Importer en CSV-fil (kommaseparert verdi) som inneholder listen over enheter, inkludert nettverksrelasjoner mellom nettverksnoder og tilkoblede enheter. For å gjøre det, plasser CSV-filen med navnet <b>devices.csv</b> i mappen <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_arpscansw": "Slå arp-Scan (på/av)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Slå arp-Scan på eller av",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Når skanningen er slått av, forblir den slått av til den aktiveres igjen.",
|
||||
@@ -684,4 +690,4 @@
|
||||
"settings_update_item_warning": "Oppdater verdien nedenfor. Pass på å følge forrige format. <b>Validering etterpå utføres ikke.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Lagre endringene først, før du tester innstillingene dine."
|
||||
}
|
||||
}
|
||||
|
||||
30
front/php/templates/language/pl_pl.json
Executable file → Normal file
30
front/php/templates/language/pl_pl.json
Executable file → Normal file
@@ -83,10 +83,10 @@
|
||||
"DevDetail_MainInfo_Name": "Nazwa",
|
||||
"DevDetail_MainInfo_Network": "<i class=\"fa fa-server\"></i> Węzeł (MAC)",
|
||||
"DevDetail_MainInfo_Network_Port": "<i class=\"fa fa-ethernet\"></i> Port",
|
||||
"DevDetail_MainInfo_Network_Site": "",
|
||||
"DevDetail_MainInfo_Network_Site": "Lokalizacja",
|
||||
"DevDetail_MainInfo_Network_Title": "<i class=\"fa fa-network-wired\"></i> Sieć",
|
||||
"DevDetail_MainInfo_Owner": "Właściciel",
|
||||
"DevDetail_MainInfo_SSID": "",
|
||||
"DevDetail_MainInfo_SSID": "SSID",
|
||||
"DevDetail_MainInfo_Title": "<i class=\"fa fa-pencil\"></i> Główne informacje",
|
||||
"DevDetail_MainInfo_Type": "Typ",
|
||||
"DevDetail_MainInfo_Vendor": "Dostawca",
|
||||
@@ -208,29 +208,29 @@
|
||||
"Device_TableHead_MAC": "Losowy MAC",
|
||||
"Device_TableHead_MAC_full": "Pełen MAC",
|
||||
"Device_TableHead_Name": "Nazwa",
|
||||
"Device_TableHead_NetworkSite": "",
|
||||
"Device_TableHead_NetworkSite": "Lokalizacja sieciowa",
|
||||
"Device_TableHead_Owner": "Właściciel",
|
||||
"Device_TableHead_Parent_MAC": "MAC rodzica węzła",
|
||||
"Device_TableHead_Port": "Port",
|
||||
"Device_TableHead_RowID": "ID wiersza",
|
||||
"Device_TableHead_Rowid": "ID wiersza",
|
||||
"Device_TableHead_SSID": "",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_Status": "Status",
|
||||
"Device_TableHead_SyncHubNodeName": "Węzeł Synchronizacji",
|
||||
"Device_TableHead_Type": "Typ",
|
||||
"Device_TableHead_Vendor": "Dostawca",
|
||||
"Device_Table_Not_Network_Device": "Nie skonfigurowane jako urządzenie sieciowe",
|
||||
"Device_Table_info": "Pokazuje_od_POCZĄTKU_do_KOŃCA_WSZYSKICH_wpisów",
|
||||
"Device_Table_info": "Pokazuje_od_POCZĄTKU_do_KOŃCA_WSZYSKIE_wpisy",
|
||||
"Device_Table_nav_next": "Następna",
|
||||
"Device_Table_nav_prev": "Poprzednia",
|
||||
"Device_Tablelenght": "Pokaż_wpisy_MENU",
|
||||
"Device_Tablelenght_all": "Wszystkie",
|
||||
"Device_Title": "Urządzenia",
|
||||
"Donations_Others": "Reszta",
|
||||
"Donations_Others": "Inne",
|
||||
"Donations_Platforms": "Platforma Sponsora",
|
||||
"Donations_Text": "Cześć 👋! </br> Dziękuje że kliknąłeś w to menu 😅 </br> </br> Próbuje zebrać trochę donacji by ulepszyć to oprogramowanie. Także pomaga mi to się nie wypalić bym dalej mógł wspierać to narzędzie. Każdy mały (powtarzający się lub nie) sponsoring sprawia że chce wkładać więcej pracy w tą aplikację. </br> Chciałbym skróć mój tydzień pracy i w wolnym czasie skupić się nad NetAlertX. Dostawalibyście więcej funkcjonalności i bardziej wypolerowane, posiadające mniej błędów wydania. </br> </br> Dziękuję że to przeczytałeś - Jestem wdzięczny za pomoc ❤🙏</br> </br> TL;DR: Wspierając mnie otrzymujesz: </br> </br> <ul><li> Regularne aktualizacje by zapewnić twoim danym i rodzinie bezpieczeństwo 🔄 </li><li>Mniej błędów (bugów) 🐛🔫</li><li>Więcej i lepsze funkcjonalności➕</li><li>Ja się nie wypale🔥🤯</li><li>Mniej wypchane na siłę wydania💨</li><li>Lepsza dokumentacja📚</li><li>Szybsza i lepsza pomoc w problemach🆘</li></ul> </br>📧Napisz E-mail do mnie na<a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> jeżeli chcesz nawiązać kontakt albo czy powinien dodać kolejną platformę z sponsoringiem.</br>",
|
||||
"Donations_Text": "Cześć 👋! </br> Dziękuje że kliknąłeś w to menu 😅 </br> </br> Próbuje zebrać trochę dotacji by ulepszyć to oprogramowanie. Także pomaga mi to się nie wypalić bym dalej mógł ulepszać to narzędzie. Każdy mały (powtarzający się lub nie) sponsoring sprawia że chce wkładać więcej pracy w tą aplikację. </br> Chciałbym skrócić mój tydzień pracy i w wolnym czasie skupić się nad NetAlertX. Dostawalibyście wtedy więcej funkcjonalności i były by one ciągle udoskonalane i posiadające mniej błędów. </br> </br> Dziękuję że to przeczytałeś - Jestem wdzięczny za pomoc ❤🙏</br> </br> TL;DR: Wspierając mnie otrzymujesz: </br> </br> <ul><li> Regularne aktualizacje by zapewnić twoim danym i rodzinie bezpieczeństwo 🔄 </li><li>Mniej błędów (bugów) 🐛🔫</li><li>Nowe i lepsze funkcjonalności➕</li><li>Nie tracę zapału do dalszego tworzenia 🔥🤯</li><li>Mniej pośpieszne, bardziej dopracowane wydania💨</li><li>Lepsza dokumentacja📚</li><li>Szybsza i lepsza pomoc w problemach🆘</li></ul> </br>📧Napisz E-mail do mnie na<a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> jeżeli chcesz nawiązać kontakt albo czy powinien dodać kolejną platformę z sponsoringiem.</br>",
|
||||
"Donations_Title": "Dotacje",
|
||||
"ENABLE_PLUGINS_description": "Włącza funkcjonalność <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">pluginów</a>. Uruchomienie pluginów wymaga więcej zasobów sprzętu więcej możesz chcieć to wyłączyć dla systemu o niskich parametrach.",
|
||||
"ENABLE_PLUGINS_description": "Włącza funkcjonalność <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">pluginów</a>. Uruchomienie pluginów wymaga więcej zasobów sprzętu więcej możesz chcieć to wyłączyć dla słabszych systemów.",
|
||||
"ENABLE_PLUGINS_name": "Włącz Pluginy",
|
||||
"Email_display_name": "Email",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
@@ -241,9 +241,9 @@
|
||||
"Events_Periodselect_LastYear": "Ostatni Rok",
|
||||
"Events_Periodselect_today": "Dzisiaj",
|
||||
"Events_Searchbox": "Szukaj",
|
||||
"Events_Shortcut_AllEvents": "Wszystkie Wydarzenia",
|
||||
"Events_Shortcut_AllEvents": "Wszystkie Zdarzenia",
|
||||
"Events_Shortcut_DownAlerts": "Alerty o rozłączeniu",
|
||||
"Events_Shortcut_Events": "Wydarzenia",
|
||||
"Events_Shortcut_Events": "Zdarzenia",
|
||||
"Events_Shortcut_MissSessions": "Brakujące Sesje",
|
||||
"Events_Shortcut_NewDevices": "Nowe Urządzenia",
|
||||
"Events_Shortcut_Sessions": "Sesje",
|
||||
@@ -270,7 +270,7 @@
|
||||
"Gen_Action": "Akcja",
|
||||
"Gen_Add": "Dodaj",
|
||||
"Gen_Add_All": "Dodaj wszystko",
|
||||
"Gen_All_Devices": "",
|
||||
"Gen_All_Devices": "Wszystkie urządzenia",
|
||||
"Gen_AreYouSure": "Jesteś pewien?",
|
||||
"Gen_Backup": "Wykonaj Kopie Zapasową",
|
||||
"Gen_Cancel": "Anuluj",
|
||||
@@ -358,6 +358,9 @@
|
||||
"Login_Toggle_Alert_headline": "Alert Hasła!",
|
||||
"Login_Toggle_Info": "Informacje o haśle",
|
||||
"Login_Toggle_Info_headline": "Informacje o haśle",
|
||||
"Maint_PurgeLog": "Wyczyść Logi",
|
||||
"Maint_RestartServer": "Zrestartuj serwer",
|
||||
"Maint_Restart_Server_noti_text": "Jesteś pewien, że chcesz zrestartować serwer backend? Może spowodować to niespujności w aplikacji. Najpierw utwórz backup konfiguracji. <br/> <br/> Uwaga: Może to zająć kilkla minut.",
|
||||
"Maintenance_Running_Version": "Zainstalowana wersja",
|
||||
"Maintenance_Status": "Status",
|
||||
"Maintenance_Title": "Narzędzia konserwacyjne",
|
||||
@@ -369,6 +372,9 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "Import CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Jesteś pewien że chcesz zaimportować plik CSV? Nadpisze to wszystkie urządzenie w bazie danych.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Przed użyciem tej funkcji, wykonaj proszę kopię zapasową. Zaimportuj plik CSV (wartości oddzielone przecinkami) zawierający listę Urządzeń, w tym Relacji Sieci między sieciowymi węzłami i podłączonymi urządzeniami. By to zrobić umieść plik CSV nazwany <b>devices.csv</b> do twojego folderu <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_arpscansw": "Przełącz Skan-arp (wł/wył)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Przełącz Skan-arp na włączony lub wyłączony",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Kiedy skan zostanie przełączony na wył zostaje wyłączony do czasu ponownej aktywacji.",
|
||||
@@ -684,4 +690,4 @@
|
||||
"settings_update_item_warning": "Zaktualizuj poniższą wartość. Zachowaj ostrożność i postępuj zgodnie z poprzednim formatem. <b>Walidacja nie jest wykonywana.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Zapisz zmiany zanim będziesz testować swoje ustawienia."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,6 +358,9 @@
|
||||
"Login_Toggle_Alert_headline": "",
|
||||
"Login_Toggle_Info": "",
|
||||
"Login_Toggle_Info_headline": "",
|
||||
"Maint_PurgeLog": "",
|
||||
"Maint_RestartServer": "",
|
||||
"Maint_Restart_Server_noti_text": "",
|
||||
"Maintenance_Running_Version": "",
|
||||
"Maintenance_Status": "",
|
||||
"Maintenance_Title": "",
|
||||
@@ -369,6 +372,9 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_arpscansw": "",
|
||||
"Maintenance_Tool_arpscansw_noti": "",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "",
|
||||
|
||||
@@ -358,6 +358,9 @@
|
||||
"Login_Toggle_Alert_headline": "Предупреждение о пароле!",
|
||||
"Login_Toggle_Info": "Информация о пароле",
|
||||
"Login_Toggle_Info_headline": "Информация о пароле",
|
||||
"Maint_PurgeLog": "Журнал очистки",
|
||||
"Maint_RestartServer": "Перезапустить сервер",
|
||||
"Maint_Restart_Server_noti_text": "Вы уверены, что хотите перезапустить внутренний сервер? Это может привести к несогласованности работы приложения. Сначала создайте резервную копию настроек. <br/> <br/> Примечание: Это может занять несколько минут.",
|
||||
"Maintenance_Running_Version": "Установленная версия",
|
||||
"Maintenance_Status": "Статус",
|
||||
"Maintenance_Title": "Инструменты обслуживания",
|
||||
@@ -369,6 +372,9 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "CSV Импорт",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Вы уверены, что хотите импортировать файл CSV? Это полностью перезапишет устройства в вашей базе данных.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Импортируйте файл CSV (значения, разделенные запятыми), содержащий список устройств, включая сетевые отношения между сетевыми узлами и подключенными устройствами. Для этого поместите файл CSV с именем <b>devices.csv</b> в папку <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_arpscansw": "Переключить arp-скан (ВКЛ./ВЫКЛ.)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Включить или выключить arp-скан",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Когда сканирование было выключено, оно остается выключенным до тех пор, пока не будет активировано снова.",
|
||||
@@ -661,7 +667,7 @@
|
||||
"settings_core_label": "Основные",
|
||||
"settings_device_scanners": "Сканеры устройств, используемые для обнаружения устройств, записывающих данные в таблицу базы данных CurrentScan.",
|
||||
"settings_device_scanners_icon": "fa-solid fa-magnifying-glass-plus",
|
||||
"settings_device_scanners_info": "",
|
||||
"settings_device_scanners_info": "Загрузите еще больше сканеров устройств с помощью параметра <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
|
||||
"settings_device_scanners_label": "Сканеры устройств",
|
||||
"settings_enabled": "Вкл. настройки",
|
||||
"settings_enabled_icon": "fa-solid fa-toggle-on",
|
||||
@@ -676,7 +682,7 @@
|
||||
"settings_other_scanners_label": "Другие сканеры",
|
||||
"settings_publishers": "Включенные шлюзы уведомлений - сервисы, которые будут отправлять уведомления в зависимости от ваших настроек.",
|
||||
"settings_publishers_icon": "fa-solid fa-paper-plane",
|
||||
"settings_publishers_info": "",
|
||||
"settings_publishers_info": "Загрузите больше нотификаторов с помощью настройки <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
|
||||
"settings_publishers_label": "Уведомления",
|
||||
"settings_saved": "<br/>Настройки сохранены. <br/> Перезагрузка... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
|
||||
"settings_system_icon": "fa-solid fa-gear",
|
||||
|
||||
@@ -358,6 +358,9 @@
|
||||
"Login_Toggle_Alert_headline": "",
|
||||
"Login_Toggle_Info": "",
|
||||
"Login_Toggle_Info_headline": "",
|
||||
"Maint_PurgeLog": "",
|
||||
"Maint_RestartServer": "",
|
||||
"Maint_Restart_Server_noti_text": "",
|
||||
"Maintenance_Running_Version": "",
|
||||
"Maintenance_Status": "",
|
||||
"Maintenance_Title": "",
|
||||
@@ -369,6 +372,9 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_arpscansw": "",
|
||||
"Maintenance_Tool_arpscansw_noti": "",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "",
|
||||
|
||||
@@ -358,6 +358,9 @@
|
||||
"Login_Toggle_Alert_headline": "",
|
||||
"Login_Toggle_Info": "",
|
||||
"Login_Toggle_Info_headline": "",
|
||||
"Maint_PurgeLog": "",
|
||||
"Maint_RestartServer": "",
|
||||
"Maint_Restart_Server_noti_text": "",
|
||||
"Maintenance_Running_Version": "",
|
||||
"Maintenance_Status": "",
|
||||
"Maintenance_Title": "",
|
||||
@@ -369,6 +372,9 @@
|
||||
"Maintenance_Tool_ImportCSV_noti": "",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_arpscansw": "",
|
||||
"Maintenance_Tool_arpscansw_noti": "",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "",
|
||||
|
||||
@@ -40,3 +40,4 @@ $timestamp = $date->format('Y-m-d_H-i-s');
|
||||
// ###################################
|
||||
// ## TimeZone processing end
|
||||
// ###################################
|
||||
|
||||
|
||||
@@ -24,39 +24,41 @@ NetAlertX supports additional plugins to extend its functionality, each with its
|
||||
Device-detecting plugins insert values into the `CurrentScan` database table. The plugins that are not required are safe to ignore, however, it makes sense to have at least some device-detecting plugins enabled, such as `ARPSCAN` or `NMAPDEV`.
|
||||
|
||||
|
||||
| ID | Type | Description | Required | Data source | Detailed docs |
|
||||
|---------------|---------|---------------------------------------------|----------|--------------------|---------------------------------------------------------------|
|
||||
| `APPRISE` | ▶️ | Apprise notification proxy | | Script | [📚_publisher_apprise](/front/plugins/_publisher_apprise/) |
|
||||
| `ARPSCAN` | 🔍 | ARP-scan on current network | | Script | [📚arp_scan](/front/plugins/arp_scan/) |
|
||||
| `CSVBCKP` | ⚙ | CSV devices backup | | Script | [📚csv_backup](/front/plugins/csv_backup/) |
|
||||
| `DBCLNP` | ⚙ | Database cleanup | Yes* | Script | [📚db_cleanup](/front/plugins/db_cleanup/) |
|
||||
| `DDNS` | ⚙ | DDNS update | | Script | [📚ddns_update](/front/plugins/ddns_update/) |
|
||||
| `DHCPLSS` | 🔍/📥 | Import devices from DHCP leases | | Script | [📚dhcp_leases](/front/plugins/dhcp_leases/) |
|
||||
| `DHCPSRVS` | ♻ | DHCP servers | | Script | [📚dhcp_servers](/front/plugins/dhcp_servers/) |
|
||||
| `INTRNT` | 🔍 | Internet IP scanner | | Script | [📚internet_ip](/front/plugins/internet_ip/) |
|
||||
| `INTRSPD` | ♻ | Internet speed test | | Script | [📚internet_speedtest](/front/plugins/internet_speedtest/) |
|
||||
| `MAINT` | ⚙ | Maintenance of logs, etc. | | Script | [📚maintenance](/front/plugins/maintenance/) |
|
||||
| `MQTT` | ▶️ | MQTT for synching to Home Assistant | | Script | [📚_publisher_mqtt](/front/plugins/_publisher_mqtt/) |
|
||||
| `NEWDEV` | ⚙ | New device template | Yes | Template | [📚newdev_template](/front/plugins/newdev_template/) |
|
||||
| `NMAP` | ♻ | Nmap port scanning & discovery | | Script | [📚nmap_scan](/front/plugins/nmap_scan/) |
|
||||
| `NMAPDEV` | 🔍 | Nmap dev scan on current network | | Script | [📚nmap_dev_scan](/front/plugins/nmap_dev_scan/) |
|
||||
| `NSLOOKUP` | ♻ | NSLookup name resolution | | Script | [📚nslookup_scan](/front/plugins/nslookup_scan/) |
|
||||
| `NTFPRCS` | ⚙ | Notification processing | Yes | Template | [📚notification_processing](/front/plugins/notification_processing/)|
|
||||
| `NTFY` | ▶️ | NTFY notifications | | Script | [📚_publisher_ntfy](/front/plugins/_publisher_ntfy/) |
|
||||
| `PHOLUS` | ♻ | Pholus name resolution | | Script | [📚pholus_scan](/front/plugins/pholus_scan/) |
|
||||
| `PIHOLE` | 🔍/📥 | Pi-hole device import & sync | | SQLite DB | [📚pihole_scan](/front/plugins/pihole_scan/) |
|
||||
| `PUSHSAFER` | ▶️ | Pushsafer notifications | | Script | [📚_publisher_pushsafer](/front/plugins/_publisher_pushsafer/) |
|
||||
| `PUSHOVER` | ▶️ | Pushover notifications | | Script | [📚_publisher_pushover](/front/plugins/_publisher_pushover/) |
|
||||
| `SETPWD` | ⚙ | Set password | Yes | Template | [📚set_password](/front/plugins/set_password/) |
|
||||
| `SMTP` | ▶️ | Email notifications | | Script | [📚_publisher_email](/front/plugins/_publisher_email/) |
|
||||
| `SNMPDSC` | 🔍/📥 | SNMP device import & sync | | Script | [📚snmp_discovery](/front/plugins/snmp_discovery/) |
|
||||
| `SYNC` | 🔍/⚙/📥| Sync & import from other NetAlertX instances | | Script | [📚snmp_discovery](/front/plugins/snmp_discovery/) |
|
||||
| `UNDIS` | 🔍/📥 | Create dummy devices | | Script | [📚undiscoverables](/front/plugins/undiscoverables/) |
|
||||
| `UNFIMP` | 🔍/📥 | UniFi device import & sync | | Script | [📚unifi_import](/front/plugins/unifi_import/) |
|
||||
| `VNDRPDT` | ⚙ | Vendor database update | | Script | [📚vendor_update](/front/plugins/vendor_update/) |
|
||||
| `WEBHOOK` | ▶️ | Webhook notifications | | Script | [📚_publisher_webhook](/front/plugins/_publisher_webhook/) |
|
||||
| `WEBMON` | ♻ | Website down monitoring | | Script | [📚website_monitor](/front/plugins/website_monitor/)
|
||||
|
||||
| ID | Type | Description | Features | Required | Data source | Detailed docs |
|
||||
|---------------|---------|--------------------------------------------|----------|----------|--------------------|---------------------------------------------------------------|
|
||||
| `APPRISE` | ▶️ | Apprise notification proxy | | | Script | [_publisher_apprise](/front/plugins/_publisher_apprise/) |
|
||||
| `ARPSCAN` | 🔍 | ARP-scan on current network | | | Script | [arp_scan](/front/plugins/arp_scan/) |
|
||||
| `CSVBCKP` | ⚙ | CSV devices backup | | | Script | [csv_backup](/front/plugins/csv_backup/) |
|
||||
| `DBCLNP` | ⚙ | Database cleanup | | Yes* | Script | [db_cleanup](/front/plugins/db_cleanup/) |
|
||||
| `DDNS` | ⚙ | DDNS update | | | Script | [ddns_update](/front/plugins/ddns_update/) |
|
||||
| `DHCPLSS` | 🔍/📥 | Import devices from DHCP leases | | | Script | [dhcp_leases](/front/plugins/dhcp_leases/) |
|
||||
| `DHCPSRVS` | ♻ | DHCP servers | | | Script | [dhcp_servers](/front/plugins/dhcp_servers/) |
|
||||
| `INTRNT` | 🔍 | Internet IP scanner | | | Script | [internet_ip](/front/plugins/internet_ip/) |
|
||||
| `INTRSPD` | ♻ | Internet speed test | | | Script | [internet_speedtest](/front/plugins/internet_speedtest/) |
|
||||
| `MAINT` | ⚙ | Maintenance of logs, etc. | | | Script | [maintenance](/front/plugins/maintenance/) |
|
||||
| `MQTT` | ▶️ | MQTT for synching to Home Assistant | | | Script | [_publisher_mqtt](/front/plugins/_publisher_mqtt/) |
|
||||
| `NBTSCAN` | ♻ | Nbtscan (NetBIOS-based) name resolution | | | Script | [nbtscan_scan](/front/plugins/nbtscan_scan/) |
|
||||
| `NEWDEV` | ⚙ | New device template | | Yes | Template | [newdev_template](/front/plugins/newdev_template/) |
|
||||
| `NMAP` | ♻ | Nmap port scanning & discovery | | | Script | [nmap_scan](/front/plugins/nmap_scan/) |
|
||||
| `NMAPDEV` | 🔍 | Nmap dev scan on current network | | | Script | [nmap_dev_scan](/front/plugins/nmap_dev_scan/) |
|
||||
| `NSLOOKUP` | ♻ | NSLookup (DNS-based) name resolution | | | Script | [nslookup_scan](/front/plugins/nslookup_scan/) |
|
||||
| `NTFPRCS` | ⚙ | Notification processing | | Yes | Template | [notification_processing](/front/plugins/notification_processing/)|
|
||||
| `NTFY` | ▶️ | NTFY notifications | | | Script | [_publisher_ntfy](/front/plugins/_publisher_ntfy/) |
|
||||
| `OMDSDN` | 📥 | OMADA TP-Link import | 📊🔄 | | Script | [omada_sdn_imp](/front/plugins/omada_sdn_imp/) |
|
||||
| `PHOLUS` | ♻ | Pholus name resolution | | | Script | [pholus_scan](/front/plugins/pholus_scan/) |
|
||||
| `PIHOLE` | 🔍/📥 | Pi-hole device import & sync | | | SQLite DB | [pihole_scan](/front/plugins/pihole_scan/) |
|
||||
| `PUSHSAFER` | ▶️ | Pushsafer notifications | | | Script | [_publisher_pushsafer](/front/plugins/_publisher_pushsafer/) |
|
||||
| `PUSHOVER` | ▶️ | Pushover notifications | | | Script | [_publisher_pushover](/front/plugins/_publisher_pushover/) |
|
||||
| `SETPWD` | ⚙ | Set password | | Yes | Template | [set_password](/front/plugins/set_password/) |
|
||||
| `SMTP` | ▶️ | Email notifications | | | Script | [_publisher_email](/front/plugins/_publisher_email/) |
|
||||
| `SNMPDSC` | 🔍/📥 | SNMP device import & sync | | | Script | [snmp_discovery](/front/plugins/snmp_discovery/) |
|
||||
| `SYNC` | 🔍/⚙/📥| Sync & import from NetAlertX instances | 📊🔄 | | Script | [sync](/front/plugins/sync/) |
|
||||
| `UNDIS` | 🔍/📥 | Create dummy devices | | | Script | [undiscoverables](/front/plugins/undiscoverables/) |
|
||||
| `UNFIMP` | 🔍/📥 | UniFi device import & sync | | | Script | [unifi_import](/front/plugins/unifi_import/) |
|
||||
| `VNDRPDT` | ⚙ | Vendor database update | | | Script | [vendor_update](/front/plugins/vendor_update/) |
|
||||
| `WEBHOOK` | ▶️ | Webhook notifications | | | Script | [_publisher_webhook](/front/plugins/_publisher_webhook/) |
|
||||
| `WEBMON` | ♻ | Website down monitoring | | | Script | [website_monitor](/front/plugins/website_monitor/) |
|
||||
|
||||
|
||||
> \* The database cleanup plugin (`DBCLNP`) is not _required_ but the app will become unusable after a while if not executed.
|
||||
>
|
||||
@@ -75,11 +77,19 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
|
||||
| system | ⚙ | Providing core system functionality. | `schedule` / always on | ✖/✔ | Script / Template |
|
||||
| other | ♻ | Other scanners, e.g. for name resolution | misc | ✖ | Script / Template |
|
||||
|
||||
## Features
|
||||
|
||||
| Icon | Description |
|
||||
|------|---------------------------------------------------------------|
|
||||
| 📊 | Auto-imports the network topology diagram |
|
||||
| 🔄 | Has the option to sync some data back into the plugin source |
|
||||
|
||||
|
||||
## ✅Enabling plugins
|
||||
|
||||
Plugins can be enabled via Settings, and can be disabled as needed.
|
||||
|
||||
1. Research which plugin you'd like to use below and then load the required plugins in Settings via the `LOADED_PLUGINS` setting.
|
||||
1. Research which plugin you'd like to use and load the required plugins in Settings via the `LOADED_PLUGINS` setting.
|
||||
1. Save the changes and review the Settings of the newly loaded plugins.
|
||||
1. Change the `<prefix>_RUN` Setting to the recommended or custom value as per the documentation of the given setting
|
||||
- If using `schedule` on a `🔍 dev scanner` plugin, make sure the schedules are the same across all `🔍 dev scanner` plugins
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
{
|
||||
"code_name": "folder_name",
|
||||
"unique_prefix": "",
|
||||
"plugin_type": "core|general|system|scanner|other|publisher",
|
||||
"code_name": "__template",
|
||||
"unique_prefix": "TMP",
|
||||
"plugin_type": "device_scanner",
|
||||
"execution_order" : "Layer_0",
|
||||
"enabled": true,
|
||||
"data_source": "script|app-db-query|template|sqlite-db-query",
|
||||
"data_source": "script",
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
@@ -39,7 +40,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
@@ -66,7 +72,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "*/5 * * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -85,7 +96,12 @@
|
||||
},
|
||||
{
|
||||
"function": "text_example",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -105,7 +121,16 @@
|
||||
},
|
||||
{
|
||||
"function": "boolean_example",
|
||||
"type": "boolean",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -122,9 +147,89 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "list_example",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{ "placeholder": "Enter value" },
|
||||
{ "suffix": "_in" },
|
||||
{ "cssClasses": "col-sm-10" },
|
||||
{ "prefillValue": "null" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": ["_in"] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-12" },
|
||||
{ "onClick": "addList(this, false)" },
|
||||
{ "getStringKey": "Gen_Add" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeAllOptions(this)" },
|
||||
{ "getStringKey": "Gen_Remove_All" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeFromList(this)" },
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["existing_entry_1", "existing_entry_2"],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Setting name"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Description / simple setup instructions"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "multiselect_example_from_setting",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"element": "select",
|
||||
"elementOptions": ["multiple"],
|
||||
"transformers": []
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": [],
|
||||
"options": ["{value}"],
|
||||
@@ -151,7 +256,12 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"element": "input",
|
||||
"elementOptions": ["readonly"],
|
||||
"transformers": []
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/<plugin folder>/rename_me.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -170,7 +280,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 30,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -255,7 +374,7 @@
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"mapped_to_column": "cur_SyncHubNodeName",
|
||||
"mapped_to_column": "cur_Type",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -265,14 +384,14 @@
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Sync Node"
|
||||
"string": "Device Type"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -280,7 +399,7 @@
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device GUID"
|
||||
"string": "N/A"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -288,7 +407,7 @@
|
||||
"column": "Dummy",
|
||||
"mapped_to_column": "cur_ScanMethod",
|
||||
"mapped_to_column_data": {
|
||||
"value": "sync"
|
||||
"value": "Example Plugin"
|
||||
},
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
|
||||
@@ -6,7 +6,6 @@ import sys
|
||||
import json
|
||||
import sqlite3
|
||||
|
||||
|
||||
# Define the installation path and extend the system path for plugin imports
|
||||
INSTALL_PATH = "/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
@@ -47,20 +46,20 @@ def main():
|
||||
#"database_column_definitions": [
|
||||
# {
|
||||
# "column": "Object_PrimaryID", <--------- the value I save into primaryId
|
||||
# "mapped_to_column": "cur_MAC", <--------- gets unserted into the CurrentScan DB table column cur_MAC
|
||||
# "mapped_to_column": "cur_MAC", <--------- gets inserted into the CurrentScan DB table column cur_MAC
|
||||
#
|
||||
for device in device_data:
|
||||
plugin_objects.add_object(
|
||||
primaryId = device['some_id'],
|
||||
secondaryId = device['some_id'],
|
||||
watched1 = device['some_id'],
|
||||
watched2 = device['some_id'],
|
||||
watched3 = device['some_id'],
|
||||
watched4 = device['some_id'],
|
||||
primaryId = device['mac_address'],
|
||||
secondaryId = device['ip_address'],
|
||||
watched1 = device['hostname'],
|
||||
watched2 = device['vendor'],
|
||||
watched3 = device['device_type'],
|
||||
watched4 = device['last_seen'],
|
||||
extra = '',
|
||||
foreignKey = device['some_id'])
|
||||
foreignKey = device['mac_address'])
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] New entries: "{len(new_devices)}"'])
|
||||
mylog('verbose', [f'[{pluginName}] New entries: "{len(device_data)}"'])
|
||||
|
||||
# log result
|
||||
plugin_objects.write_result_file()
|
||||
@@ -75,7 +74,34 @@ def get_device_data(some_setting):
|
||||
# do some processing, call exteranl APIs, and return a device_data list
|
||||
# ...
|
||||
#
|
||||
# Sample data for testing purposes, you can adjust the processing in main() as needed
|
||||
# ... before adding it to the plugin_objects.add_object(...)
|
||||
device_data = [
|
||||
{
|
||||
'device_id': 'device1',
|
||||
'mac_address': '00:11:22:33:44:55',
|
||||
'ip_address': '192.168.1.2',
|
||||
'hostname': 'iPhone 12',
|
||||
'vendor': 'Apple Inc.',
|
||||
'device_type': 'Smartphone',
|
||||
'last_seen': '2024-06-27 10:00:00',
|
||||
'port': '1',
|
||||
'network_id': 'network1'
|
||||
},
|
||||
{
|
||||
'device_id': 'device2',
|
||||
'mac_address': '00:11:22:33:44:66',
|
||||
'ip_address': '192.168.1.3',
|
||||
'hostname': 'Moto G82',
|
||||
'vendor': 'Motorola Inc.',
|
||||
'device_type': 'Laptop',
|
||||
'last_seen': '2024-06-27 10:05:00',
|
||||
'port': '',
|
||||
'network_id': 'network1'
|
||||
}
|
||||
]
|
||||
|
||||
# Return the data to be detected by teh main application
|
||||
return device_data
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
82
front/plugins/__test/test.py
Executable file
82
front/plugins/__test/test.py
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python
|
||||
# Just a testing library plugin for development purposes
|
||||
import json
|
||||
import subprocess
|
||||
import argparse
|
||||
import os
|
||||
import pathlib
|
||||
import sys
|
||||
from datetime import datetime
|
||||
import time
|
||||
import re
|
||||
import hashlib
|
||||
import sqlite3
|
||||
|
||||
|
||||
# Register NetAlertX directories
|
||||
INSTALL_PATH="/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
# NetAlertX modules
|
||||
import conf
|
||||
from const import apiPath, confFileName
|
||||
from plugin_utils import getPluginObject
|
||||
from plugin_helper import Plugin_Objects
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ, get_setting_value, bytes_to_string, sanitize_string, cleanDeviceName
|
||||
from notification import Notification_obj
|
||||
from database import DB, get_device_stats
|
||||
|
||||
|
||||
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||
RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log')
|
||||
|
||||
|
||||
# Initialize the Plugin obj output file
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
# Create an MD5 hash object
|
||||
md5_hash = hashlib.md5()
|
||||
|
||||
pluginName = 'TESTONLY'
|
||||
|
||||
# globals
|
||||
|
||||
|
||||
def main():
|
||||
# START
|
||||
mylog('verbose', [f'[{pluginName}] In script'])
|
||||
|
||||
# SPACE FOR TESTING 🔽
|
||||
|
||||
str = "ABC-MBP._another.localdomain."
|
||||
# cleanDeviceName(str, match_IP)
|
||||
# result = cleanDeviceName(str, True)
|
||||
|
||||
regexes = get_setting_value('NEWDEV_NAME_CLEANUP_REGEX')
|
||||
|
||||
print(regexes)
|
||||
subnets = get_setting_value('SCAN_SUBNETS')
|
||||
|
||||
print(subnets)
|
||||
|
||||
for rgx in regexes:
|
||||
mylog('trace', ["[cleanDeviceName] applying regex : " + rgx])
|
||||
mylog('trace', ["[cleanDeviceName] name before regex : " + str])
|
||||
|
||||
str = re.sub(rgx, "", str)
|
||||
mylog('trace', ["[cleanDeviceName] name after regex : " + str])
|
||||
|
||||
mylog('debug', ["[cleanDeviceName] output: " + str])
|
||||
|
||||
|
||||
# SPACE FOR TESTING 🔼
|
||||
|
||||
# END
|
||||
mylog('verbose', [f'[{pluginName}] result "{str}"'])
|
||||
|
||||
|
||||
|
||||
|
||||
# -------------INIT---------------------
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@@ -2,7 +2,12 @@
|
||||
|
||||
[Apprise](https://hub.docker.com/r/caronc/apprise) is a notification gateway/publisher that allows you to push notifications to 80+ different services.
|
||||
|
||||
## Notes
|
||||
|
||||
You need to bring your own separate Apprise instance to use this publisher gateway. I suggest this [Apprise image](https://hub.docker.com/r/caronc/apprise).
|
||||
|
||||
### Usage
|
||||
|
||||
- Go to settings and fill in relevant details.
|
||||
- Use the Apprise container's URL in the `APPRISE_HOST` setting.
|
||||
|
||||
|
||||
@@ -288,7 +288,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["test"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": ["disabled", "on_notification"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -315,7 +320,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/_publisher_apprise/apprise.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -342,7 +356,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 10,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -373,7 +396,12 @@
|
||||
},
|
||||
{
|
||||
"function": "HOST",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -400,7 +428,12 @@
|
||||
},
|
||||
{
|
||||
"function": "URL",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -427,7 +460,12 @@
|
||||
},
|
||||
{
|
||||
"function": "PAYLOAD",
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "html",
|
||||
"options": ["html", "text"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -444,7 +482,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Select the payoad type sent to Apprise. For example <code>html</code> works well with emails, <code>text</code> with chat apps, such as Telegram."
|
||||
"string": "Select the payload type sent to Apprise. For example <code>html</code> works well with emails, <code>text</code> with chat apps, such as Telegram."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
@@ -454,7 +492,16 @@
|
||||
},
|
||||
{
|
||||
"function": "SIZE",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1024,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -288,7 +288,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["test"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": ["disabled", "on_notification"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -315,7 +320,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/_publisher_email/email_smtp.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -342,7 +356,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 20,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -373,7 +396,12 @@
|
||||
},
|
||||
{
|
||||
"function": "SERVER",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -400,7 +428,16 @@
|
||||
},
|
||||
{
|
||||
"function": "PORT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 587,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -427,7 +464,16 @@
|
||||
},
|
||||
{
|
||||
"function": "SKIP_LOGIN",
|
||||
"type": "boolean",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -454,7 +500,12 @@
|
||||
},
|
||||
{
|
||||
"function": "USER",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -481,7 +532,16 @@
|
||||
},
|
||||
{
|
||||
"function": "PASS",
|
||||
"type": "password",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "password" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -508,7 +568,16 @@
|
||||
},
|
||||
{
|
||||
"function": "SKIP_TLS",
|
||||
"type": "boolean",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -535,7 +604,16 @@
|
||||
},
|
||||
{
|
||||
"function": "FORCE_SSL",
|
||||
"type": "boolean",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -562,7 +640,12 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_TO",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "user@gmail.com",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -589,7 +672,12 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_FROM",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "NetAlertX <user@gmail.com>",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -56,6 +56,19 @@ def main():
|
||||
# Retrieve new notifications
|
||||
new_notifications = notifications.getNew()
|
||||
|
||||
# mylog('verbose', [f'[{pluginName}] new_notifications: ', new_notifications])
|
||||
# mylog('verbose', [f'[{pluginName}] SMTP_SERVER: ', get_setting_value("SMTP_SERVER")])
|
||||
# mylog('verbose', [f'[{pluginName}] SMTP_PORT: ', get_setting_value("SMTP_PORT")])
|
||||
# mylog('verbose', [f'[{pluginName}] SMTP_SKIP_LOGIN: ', get_setting_value("SMTP_SKIP_LOGIN")])
|
||||
# mylog('verbose', [f'[{pluginName}] SMTP_USER: ', get_setting_value("SMTP_USER")])
|
||||
# mylog('verbose', [f'[{pluginName}] SMTP_PASS: ', get_setting_value("SMTP_PASS")])
|
||||
|
||||
# mylog('verbose', [f'[{pluginName}] SMTP_SKIP_TLS: ', get_setting_value("SMTP_SKIP_TLS")])
|
||||
# mylog('verbose', [f'[{pluginName}] SMTP_FORCE_SSL: ', get_setting_value("SMTP_FORCE_SSL")])
|
||||
# mylog('verbose', [f'[{pluginName}] SMTP_REPORT_TO: ', get_setting_value("SMTP_REPORT_TO")])
|
||||
# mylog('verbose', [f'[{pluginName}] SMTP_REPORT_FROM: ', get_setting_value("SMTP_REPORT_FROM")])
|
||||
|
||||
|
||||
# Process the new notifications (see the Notifications DB table for structure or check the /api/table_notifications.json endpoint)
|
||||
for notification in new_notifications:
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "A plugin to publish a notification via the Apprise gateway."
|
||||
"string": "A plugin to publish a notification via MQTT to Home Assistant."
|
||||
}
|
||||
],
|
||||
"params": [
|
||||
@@ -278,7 +278,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["test"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
@@ -312,7 +317,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/_publisher_mqtt/mqtt.py devices={devices}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -339,7 +353,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "0 2 * * 3",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -374,7 +393,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 20,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -405,7 +433,12 @@
|
||||
},
|
||||
{
|
||||
"function": "BROKER",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -432,7 +465,16 @@
|
||||
},
|
||||
{
|
||||
"function": "PORT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1883,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -459,7 +501,12 @@
|
||||
},
|
||||
{
|
||||
"function": "USER",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -486,7 +533,16 @@
|
||||
},
|
||||
{
|
||||
"function": "PASSWORD",
|
||||
"type": "password",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "password" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -513,7 +569,16 @@
|
||||
},
|
||||
{
|
||||
"function": "SEND_STATS",
|
||||
"type": "boolean",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": true,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -532,7 +597,12 @@
|
||||
},
|
||||
{
|
||||
"function": "DEVICE_ID",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "netalertx",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -551,7 +621,12 @@
|
||||
},
|
||||
{
|
||||
"function": "DEVICE_NAME",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "NetAlertX",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -570,7 +645,16 @@
|
||||
},
|
||||
{
|
||||
"function": "SEND_DEVICES",
|
||||
"type": "boolean",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": true,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -587,9 +671,38 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "DEVICES_SQL",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "select rowid, * from Devices where dev_Name not in ({s-quote}null{s-quote}, {s-quote}(name not found){s-quote}, {s-quote}(unknown){s-quote})",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Devices SQL"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The SQL condition used to select which Devices are sent via MQTT. Please note that you need to use <code>{s-quote}</code> for single quotes replacement and double-quotes are not supported."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "QOS",
|
||||
"type": "integer.select",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [0, 1, 2],
|
||||
"localized": ["name", "description"],
|
||||
@@ -616,7 +729,12 @@
|
||||
},
|
||||
{
|
||||
"function": "VERSION",
|
||||
"type": "integer.select",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"options": [1, 2],
|
||||
"localized": ["name", "description"],
|
||||
@@ -635,7 +753,16 @@
|
||||
},
|
||||
{
|
||||
"function": "DELAY_SEC",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 2,
|
||||
"options": [2, 3, 4, 5],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -13,6 +13,7 @@ import paho.mqtt.client as mqtt
|
||||
# from paho.mqtt import client as mqtt_client
|
||||
# from paho.mqtt import CallbackAPIVersion as mqtt_CallbackAPIVersion
|
||||
import hashlib
|
||||
import sqlite3
|
||||
|
||||
|
||||
# Register NetAlertX directories
|
||||
@@ -27,7 +28,7 @@ from plugin_helper import Plugin_Objects
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ, get_setting_value, bytes_to_string, sanitize_string
|
||||
from notification import Notification_obj
|
||||
from database import DB, get_all_devices, get_device_stats
|
||||
from database import DB, get_device_stats
|
||||
|
||||
|
||||
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||
@@ -340,10 +341,10 @@ def mqtt_start(db):
|
||||
# Generate device-specific MQTT messages if enabled
|
||||
if get_setting_value('MQTT_SEND_DEVICES') == True:
|
||||
|
||||
# Specific devices
|
||||
# Specific devices processing
|
||||
|
||||
# Get all devices
|
||||
devices = get_all_devices(db)
|
||||
devices = db.read(get_setting_value('MQTT_DEVICES_SQL').replace('{s-quote}',"'"))
|
||||
|
||||
sec_delay = len(devices) * int(get_setting_value('MQTT_DELAY_SEC'))*5
|
||||
|
||||
|
||||
@@ -242,7 +242,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["test"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": ["disabled", "on_notification"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -269,7 +274,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/_publisher_ntfy/ntfy.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -296,7 +310,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 10,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -327,7 +350,12 @@
|
||||
},
|
||||
{
|
||||
"function": "HOST",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "https://ntfy.sh",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -354,7 +382,12 @@
|
||||
},
|
||||
{
|
||||
"function": "TOPIC",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -381,7 +414,12 @@
|
||||
},
|
||||
{
|
||||
"function": "USER",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -408,7 +446,16 @@
|
||||
},
|
||||
{
|
||||
"function": "PASSWORD",
|
||||
"type": "password",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "password" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -435,7 +482,12 @@
|
||||
},
|
||||
{
|
||||
"function": "PRIORITY",
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "urgent",
|
||||
"options": ["urgent", "high", "default", "low", "min"],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -242,7 +242,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["test"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": ["disabled", "on_notification"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -269,7 +274,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/_publisher_pushover/pushover.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -296,7 +310,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 10,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -323,7 +346,12 @@
|
||||
},
|
||||
{
|
||||
"function": "USER_KEY",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "USER_KEY",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -342,7 +370,12 @@
|
||||
},
|
||||
{
|
||||
"function": "APP_TOKEN",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "APP_TOKEN",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -361,7 +394,12 @@
|
||||
},
|
||||
{
|
||||
"function": "DEVICE_NAME",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "DEVICE_NAME",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -242,7 +242,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["test"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": ["disabled", "on_notification"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -269,7 +274,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/_publisher_pushsafer/pushsafer.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -296,7 +310,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 10,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -327,7 +350,12 @@
|
||||
},
|
||||
{
|
||||
"function": "TOKEN",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "ApiKey",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -242,7 +242,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["test"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": ["disabled", "on_notification"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -269,7 +274,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/_publisher_webhook/webhook.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -296,7 +310,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 10,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -327,7 +350,12 @@
|
||||
},
|
||||
{
|
||||
"function": "URL",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -354,7 +382,12 @@
|
||||
},
|
||||
{
|
||||
"function": "PAYLOAD",
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "json",
|
||||
"options": ["json", "html", "text"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -381,7 +414,12 @@
|
||||
},
|
||||
{
|
||||
"function": "REQUEST_METHOD",
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "GET",
|
||||
"options": ["GET", "POST", "PUT"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -408,7 +446,16 @@
|
||||
},
|
||||
{
|
||||
"function": "SIZE",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1024,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -435,7 +482,12 @@
|
||||
},
|
||||
{
|
||||
"function": "SECRET",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"code_name": "arp_scan",
|
||||
"unique_prefix": "ARPSCAN",
|
||||
"execution_order" : "Layer_2",
|
||||
"plugin_type": "device_scanner",
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
@@ -69,8 +70,13 @@
|
||||
"settings": [
|
||||
{
|
||||
"function": "RUN",
|
||||
"type": "text.select",
|
||||
"default_value": "schedule",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
"once",
|
||||
@@ -111,7 +117,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/arp_scan/script.py userSubnets={subnets}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -146,7 +161,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 300,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -181,7 +205,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "*/5 * * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -216,7 +245,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1", "Watched_Value2"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -256,7 +294,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new"],
|
||||
"options": [
|
||||
"new",
|
||||
@@ -296,7 +343,12 @@
|
||||
},
|
||||
{
|
||||
"function": "ARGS",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "sudo arp-scan --ignoredups --retry=6",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -58,7 +58,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "schedule",
|
||||
"options": [
|
||||
"disabled",
|
||||
@@ -99,7 +104,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/csv_backup/script.py overwrite={overwrite} location={location}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -134,7 +148,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "0 2 * * 3",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -169,7 +188,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 30,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -204,7 +232,16 @@
|
||||
},
|
||||
{
|
||||
"function": "overwrite",
|
||||
"type": "boolean",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -239,7 +276,12 @@
|
||||
},
|
||||
{
|
||||
"function": "location",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "/app/config",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -47,7 +47,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "schedule",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -74,7 +79,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/db_cleanup/script.py pluginskeephistory={pluginskeephistory} hourstokeepnewdevice={hourstokeepnewdevice} daystokeepevents={daystokeepevents} pholuskeepdays={pholuskeepdays}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -109,7 +123,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "*/30 * * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -144,7 +163,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 30,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -179,7 +207,16 @@
|
||||
},
|
||||
{
|
||||
"function": "NOTIFI_HIST",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 100,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -76,7 +76,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -107,7 +112,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/ddns_update/script.py prev_ip={prev_ip} DDNS_UPDATE_URL={DDNS_UPDATE_URL} DDNS_USER={DDNS_USER} DDNS_PASSWORD={DDNS_PASSWORD} DDNS_DOMAIN={DDNS_DOMAIN} ",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -142,7 +156,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "*/5 * * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -177,7 +196,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 30,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -212,7 +240,12 @@
|
||||
},
|
||||
{
|
||||
"function": "DOMAIN",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "your_domain.freeddns.org",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -247,7 +280,12 @@
|
||||
},
|
||||
{
|
||||
"function": "USER",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "dynu_user",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -282,7 +320,16 @@
|
||||
},
|
||||
{
|
||||
"function": "PASSWORD",
|
||||
"type": "password",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "password" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "A0000000B0000000C0000000D0000000",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -317,7 +364,12 @@
|
||||
},
|
||||
{
|
||||
"function": "UPDATE_URL",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "https://api.dynu.com/nic/update?",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -352,7 +404,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -388,7 +449,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new", "watched-changed"],
|
||||
"options": [
|
||||
"new",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"code_name": "dhcp_leases",
|
||||
"unique_prefix": "DHCPLSS",
|
||||
"plugin_type": "device_scanner",
|
||||
"execution_order" : "Layer_3",
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
"data_filters": [
|
||||
@@ -414,7 +415,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
@@ -455,7 +461,12 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/dhcp_leases/script.py paths={paths}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -490,7 +501,63 @@
|
||||
},
|
||||
{
|
||||
"function": "paths_to_check",
|
||||
"type": "list",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{ "placeholder": "Enter value" },
|
||||
{ "suffix": "_in" },
|
||||
{ "cssClasses": "col-sm-10" },
|
||||
{ "prefillValue": "null" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": ["_in"] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-12" },
|
||||
{ "onClick": "addList(this, false)" },
|
||||
{ "getStringKey": "Gen_Add" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeAllOptions(this)" },
|
||||
{ "getStringKey": "Gen_Remove_All" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeFromList(this)" },
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["/mnt/dhcp1.leases", "/mnt/dhcp2.leases"],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -511,21 +578,18 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Add all dhcp.leases mapped paths to watch. Enter full path within the container, e.g. <code>/mnt/dhcp2.leases</code>. You must map these files accordingly in your <code>docker-compose.yml</code> file. (If you are mapping a PiHole dhcp.leases file the path in the container must contain <code>pihole</code>, e.g.: <code>:/etc/pihole/dhcp.leases</code>)"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Agregue todas las rutas asignadas de dhcp.leases para observar. Ingrese la ruta completa dentro del contenedor, p.e. <code>/mnt/dhcp2.leases</code>. Debe asignar estos archivos en consecuencia en su archivo <code>docker-compose.yml</code>. (Si está asignando un archivo PiHole dhcp.leases, la ruta en el contenedor debe contener <code>pihole</code>, por ejemplo: <code>:/etc/pihole/dhcp.leases</code>)"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Alle zu überwachenden dhcp.leases-Pfade hinzufügen. Den absoluten Pfad innerhalb des Containers angeben, z.B. <code>/mnt/dchp2.leases</code>. Diese Dateien müssen korrekt in der <code>docker-compose.yml</code> gemapped werden. Wird eine PiHole dhcp.leases-Datei in den Container gemapped, so muss der Pfad im Container <code>pihole</code> inkludieren, z.B. <code>:/etc/pihole/dhcp.leases</code>"
|
||||
"string": "Add all dhcp.leases mapped paths to watch. Enter full path within the container, e.g. <code>/mnt/dhcp2.leases</code>. You must map these files accordingly in your <code>docker-compose.yml</code> file. Supports pihole, dnsmasq, and generic formats. <br><br> For dnsmasq or pihole the path in the container must contain <code>pihole</code> or <code>dnsmasq</code>; e.g.: <code>:/etc/pihole/dhcp.leases</code>). See the above docs for details."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "0 2 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -560,7 +624,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 5,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -595,7 +668,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1", "Watched_Value4"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -635,7 +717,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new", "watched-changed"],
|
||||
"options": [
|
||||
"new",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"code_name": "dhcp_servers",
|
||||
"unique_prefix": "DHCPSRVS",
|
||||
"plugin_type": "other",
|
||||
"execution_order" : "Layer_3",
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
"show_ui": true,
|
||||
@@ -307,7 +308,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
@@ -340,7 +346,12 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/dhcp_servers/script.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -367,7 +378,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "0 2 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -394,7 +410,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 10,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -425,7 +450,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -457,7 +491,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new", "watched-changed"],
|
||||
"options": ["new", "watched-changed", "watched-not-changed"],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -153,7 +153,16 @@
|
||||
"string": "Device ID Parameter"
|
||||
}
|
||||
],
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "1",
|
||||
"localized": ["name"]
|
||||
},
|
||||
@@ -164,7 +173,16 @@
|
||||
"string": "Event Type Parameter"
|
||||
}
|
||||
],
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "device_down",
|
||||
"localized": ["name"]
|
||||
},
|
||||
@@ -175,7 +193,16 @@
|
||||
"string": "Repetition Count Parameter"
|
||||
}
|
||||
],
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 3,
|
||||
"localized": ["name"]
|
||||
}
|
||||
@@ -216,7 +243,12 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "UPDATE Devices SET dev_AlertDeviceDown = {KNWN_dev_AlertDeviceDown}, dev_AlertEvents = {KNWN_dev_AlertEvents} WHERE dev_MAC in ({target_macs})",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -235,7 +267,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Name",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "(unknown)",
|
||||
"options": [],
|
||||
@@ -255,7 +296,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Owner",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 30,
|
||||
"default_value": "House",
|
||||
"override_value": {
|
||||
@@ -278,7 +324,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_DeviceType",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 30,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -298,7 +349,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Vendor",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 250,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -318,7 +378,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Favorite",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"override_value": {
|
||||
"override": false
|
||||
@@ -340,7 +409,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Group",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 10,
|
||||
"default_value": "",
|
||||
"override_value": {
|
||||
@@ -363,7 +437,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Comments",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -382,7 +461,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_FirstConnection",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -402,7 +490,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_LastConnection",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -422,7 +519,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_LastIP",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -442,7 +548,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_StaticIP",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"override_value": {
|
||||
"override": true
|
||||
@@ -464,7 +579,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_ScanCycle",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"override_value": {
|
||||
"override": true
|
||||
@@ -486,7 +610,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_LogEvents",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"override_value": {
|
||||
"override": false
|
||||
@@ -508,7 +641,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_AlertEvents",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"override_value": {
|
||||
"override": true
|
||||
@@ -530,7 +672,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_AlertDeviceDown",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -549,7 +700,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_SkipRepeated",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -568,7 +728,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_LastNotification",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -588,7 +757,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_PresentLastScan",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -607,7 +785,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_NewDevice",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": true,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -626,7 +813,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Location",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 250,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -646,7 +838,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Archived",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -665,7 +866,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Network_Node_MAC_ADDR",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -684,7 +890,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Network_Node_port",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -703,7 +918,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Icon",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"code_name": "internet_ip",
|
||||
"unique_prefix": "INTRNT",
|
||||
"plugin_type": "device_scanner",
|
||||
"execution_order" : "Layer_3",
|
||||
"enabled": true,
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
@@ -63,8 +64,13 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"default_value": "schedule",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan"],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -94,7 +100,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/internet_ip/script.py prev_ip={prev_ip} INTRNT_DIG_GET_IP_ARG={INTRNT_DIG_GET_IP_ARG}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -129,7 +144,12 @@
|
||||
},
|
||||
{
|
||||
"function": "DIG_GET_IP_ARG",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "-4 myip.opendns.com @resolver1.opendns.com",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -164,7 +184,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "*/5 * * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -199,7 +224,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 30,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -234,7 +268,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RETRIES",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 3,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -253,7 +296,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -279,7 +331,7 @@
|
||||
"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 Previous IP (not recommended)</li><li><code>Watched_Value2</code> unused</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Previous IP (not recommended)</li><li><code>Watched_Value2</code> unused</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> type </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
@@ -289,7 +341,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new", "watched-changed"],
|
||||
"options": [
|
||||
"new",
|
||||
@@ -426,6 +487,22 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"mapped_to_column": "cur_Type",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Type"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Dummy",
|
||||
"mapped_to_column": "cur_ScanMethod",
|
||||
|
||||
@@ -71,7 +71,7 @@ def main():
|
||||
watched1 = f'Previous IP: {PREV_IP}',
|
||||
watched2 = cmd_output.replace('\n',''),
|
||||
watched3 = retries_needed,
|
||||
watched4 = '',
|
||||
watched4 = 'Gateway',
|
||||
extra = f'Previous IP: {PREV_IP}',
|
||||
foreignKey = 'Internet')
|
||||
|
||||
|
||||
@@ -377,7 +377,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -408,7 +413,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/internet_speedtest/script.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -443,7 +457,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "*/30 * * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -478,7 +497,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 60,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -513,7 +541,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": [],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -549,7 +586,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": [],
|
||||
"options": [
|
||||
"new",
|
||||
|
||||
@@ -159,7 +159,12 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "UPDATE Devices SET dev_AlertDeviceDown = {KNWN_dev_AlertDeviceDown}, dev_AlertEvents = {KNWN_dev_AlertEvents} WHERE dev_MAC in ({target_macs})",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -178,7 +183,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Name",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "(unknown)",
|
||||
"options": [],
|
||||
@@ -198,7 +212,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Owner",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 30,
|
||||
"default_value": "House",
|
||||
"override_value": {
|
||||
@@ -221,7 +240,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_DeviceType",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 30,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -241,7 +265,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Vendor",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 250,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -261,7 +294,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Favorite",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"override_value": {
|
||||
"override": false
|
||||
@@ -283,7 +325,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Group",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 10,
|
||||
"default_value": "",
|
||||
"override_value": {
|
||||
@@ -306,7 +353,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Comments",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -325,7 +377,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_FirstConnection",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -345,7 +406,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_LastConnection",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -365,7 +435,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_LastIP",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -385,7 +464,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_StaticIP",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"override_value": {
|
||||
"override": true
|
||||
@@ -407,7 +495,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_ScanCycle",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"override_value": {
|
||||
"override": true
|
||||
@@ -429,7 +526,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_LogEvents",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"override_value": {
|
||||
"override": false
|
||||
@@ -451,7 +557,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_AlertEvents",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"override_value": {
|
||||
"override": true
|
||||
@@ -473,7 +588,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_AlertDeviceDown",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -492,7 +616,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_SkipRepeated",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -511,7 +644,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_LastNotification",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -531,7 +673,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_PresentLastScan",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -550,7 +701,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_NewDevice",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": true,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -569,7 +729,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Location",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 250,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -589,7 +754,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Archived",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -608,7 +782,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Network_Node_MAC_ADDR",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -627,7 +806,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Network_Node_port",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -646,7 +834,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Icon",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -29,7 +29,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "schedule",
|
||||
"options": [
|
||||
"disabled",
|
||||
@@ -62,7 +67,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/maintenance/maintenance.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -97,7 +111,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "0 2 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -132,7 +151,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 30,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -167,7 +195,16 @@
|
||||
},
|
||||
{
|
||||
"function": "LOG_LENGTH",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 250000,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
7
front/plugins/nbtscan_scan/README.md
Executable file
7
front/plugins/nbtscan_scan/README.md
Executable file
@@ -0,0 +1,7 @@
|
||||
## Overview
|
||||
|
||||
Plugin for device name discovery via the [nbtscan](https://linuxcommandlibrary.com/man/nbtscan) network utility supporting NetBIOS.
|
||||
|
||||
### Usage
|
||||
|
||||
- Check the Settings page for details.
|
||||
338
front/plugins/nbtscan_scan/config.json
Executable file
338
front/plugins/nbtscan_scan/config.json
Executable file
@@ -0,0 +1,338 @@
|
||||
{
|
||||
"code_name": "nbtscan_scan",
|
||||
"unique_prefix": "NBTSCAN",
|
||||
"plugin_type": "other",
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
"execution_order" : "Layer_3",
|
||||
"show_ui": true,
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"display_name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "NBTSCAN (Name discovery)"
|
||||
}
|
||||
],
|
||||
"icon": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "<i class=\"fa-solid fa-search\"></i>"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "A plugin to discover device names via NetBIOS."
|
||||
}
|
||||
],
|
||||
"params": [
|
||||
{
|
||||
"name": "ips",
|
||||
"type": "sql",
|
||||
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC",
|
||||
"timeoutMultiplier": true
|
||||
}
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
"before_name_updates",
|
||||
"on_new_device",
|
||||
"once",
|
||||
"schedule",
|
||||
"always_after_scan"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "When to run"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Cuándo ejecutar"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Wann laufen"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "When the plugin should be executed. If enabled this will execute the scan until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Setting this to <code>on_new_device</code> or a daily <code>schedule</code> is recommended.<br/><br/> Depends on the <a onclick=\"toggleAllSettings()\" href=\"#SCAN_SUBNETS\"><code>SCAN_SUBNETS</code> setting</a>."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/nbtscan_scan/nbtscan.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Command"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Comando"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Befehl"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Command to run. This can not be changed"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Comando a ejecutar. Esto no se puede cambiar"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Befehl zum Ausführen. Dies kann nicht geändert werden"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "*/30 * * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Schedule"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Schedule"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Schedule"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Only enabled if you select <code>schedule</code> in the <a href=\"#NBTSCAN_RUN\"><code>NBTSCAN_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."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Solo está habilitado si selecciona <code>schedule</code> en la configuración <a href=\"#NBTSCAN_RUN\"><code>NBTSCAN_RUN</code></a>. Asegúrese de ingresar la programación en el formato similar a cron correcto (por ejemplo, valide en <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Por ejemplo, ingresar <code>0 4 * * *</code> ejecutará el escaneo después de las 4 a.m. en el <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</ código> que configuró arriba</a>. Se ejecutará la PRÓXIMA vez que pase el tiempo."
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Nur aktiviert, wenn Sie <code>schedule</code> in der <a href=\"#NBTSCAN_RUN\"><code>NBTSCAN_RUN</code>-Einstellung</a> auswählen. Stellen Sie sicher, dass Sie den Zeitplan im richtigen Cron-ähnlichen Format eingeben (z. B. validieren unter <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Wenn Sie beispielsweise <code>0 4 * * *</code> eingeben, wird der Scan nach 4 Uhr morgens in der <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</ ausgeführt. Code> den Sie oben festgelegt haben</a>. Wird das NÄCHSTE Mal ausgeführt, wenn die Zeit vergeht."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 10,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Run timeout"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Tiempo límite de ejecución"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Zeitüberschreitung"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Tiempo máximo en segundos para esperar a que finalice el script. Si se supera este tiempo, el script se cancela."
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Maximale Zeit in Sekunden, die auf den Abschluss des Skripts gewartet werden soll. Bei Überschreitung dieser Zeit wird das Skript abgebrochen."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "MAC"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "MAC"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "IP"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "IP"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Server"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Name"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Created"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Changed"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"css_classes": "col-sm-1",
|
||||
"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>"
|
||||
},
|
||||
{
|
||||
"equals": "missing-in-last-scan",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-question'></i></div>"
|
||||
}
|
||||
],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Status"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
139
front/plugins/nbtscan_scan/nbtscan.py
Executable file
139
front/plugins/nbtscan_scan/nbtscan.py
Executable file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
import sys
|
||||
import json
|
||||
import sqlite3
|
||||
import subprocess
|
||||
|
||||
# Define the installation path and extend the system path for plugin imports
|
||||
INSTALL_PATH = "/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||
from plugin_utils import get_plugins_configs
|
||||
from logger import mylog
|
||||
from const import pluginsPath, fullDbPath
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from notification import write_notification
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
|
||||
# Define the current path and log file paths
|
||||
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log')
|
||||
|
||||
# Initialize the Plugin obj output file
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
|
||||
pluginName = 'NBTSCAN'
|
||||
|
||||
def main():
|
||||
mylog('verbose', [f'[{pluginName}] In script'])
|
||||
|
||||
# timeout = get_setting_value('NBLOOKUP_RUN_TIMEOUT')
|
||||
timeout = 20
|
||||
|
||||
# Create a database connection
|
||||
db = DB() # instance of class DB
|
||||
db.open()
|
||||
|
||||
# Initialize the Plugin obj output file
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
|
||||
# Create a Device_obj instance
|
||||
device_handler = Device_obj(db)
|
||||
|
||||
# Retrieve devices
|
||||
unknown_devices = device_handler.getUnknown()
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] Unknown devices count: {len(unknown_devices)}'])
|
||||
|
||||
# TEST
|
||||
# execute_name_lookup('192.168.1.121', timeout)
|
||||
|
||||
for device in unknown_devices:
|
||||
domain_name, dns_server = execute_name_lookup(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
|
||||
|
||||
#===============================================================================
|
||||
# Execute scan
|
||||
#===============================================================================
|
||||
def execute_name_lookup (ip, timeout):
|
||||
"""
|
||||
Execute the NBLOOKUP command on IP.
|
||||
"""
|
||||
|
||||
args = ['nbtscan', ip]
|
||||
|
||||
# Execute command
|
||||
output = ""
|
||||
|
||||
try:
|
||||
# try runnning a subprocess with a forced (timeout) in case the subprocess hangs
|
||||
output = subprocess.check_output (args, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(timeout), text=True)
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] DEBUG OUTPUT : {output}'])
|
||||
|
||||
domain_name = ''
|
||||
dns_server = ''
|
||||
|
||||
# Split the output into lines
|
||||
lines = output.splitlines()
|
||||
|
||||
# Look for the first line containing a valid NetBIOS name entry
|
||||
index = 0
|
||||
for line in lines:
|
||||
if 'Doing NBT name scan' not in line and ip in line:
|
||||
# Split the line and extract the primary NetBIOS name
|
||||
parts = line.split()
|
||||
if parts:
|
||||
domain_name = parts[1]
|
||||
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] Domain Name: {domain_name}'])
|
||||
|
||||
return domain_name, dns_server
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
# An error occurred, handle it
|
||||
# if "NXDOMAIN" in e.output:
|
||||
# mylog('verbose', [f'[{pluginName}]', f"No PTR record found for IP: {ip}"])
|
||||
# else:
|
||||
mylog('verbose', [f'[{pluginName}]', e.output])
|
||||
# Handle other errors here
|
||||
# mylog('verbose', [f'[{pluginName}] ⚠ ERROR - check logs'])
|
||||
|
||||
except subprocess.TimeoutExpired as timeErr:
|
||||
mylog('verbose', [f'[{pluginName}] TIMEOUT - the process forcefully terminated as timeout reached'])
|
||||
|
||||
if output == "": # check if the subprocess failed
|
||||
mylog('verbose', [f'[{pluginName}] Scan: FAIL - check logs'])
|
||||
else:
|
||||
mylog('verbose', [f'[{pluginName}] Scan: SUCCESS'])
|
||||
|
||||
return '', ''
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -28,7 +28,63 @@
|
||||
"settings": [
|
||||
{
|
||||
"function": "ignored_MACs",
|
||||
"type": "list",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{ "placeholder": "Enter value" },
|
||||
{ "suffix": "_in" },
|
||||
{ "cssClasses": "col-sm-10" },
|
||||
{ "prefillValue": "null" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": ["_in"] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-12" },
|
||||
{ "onClick": "addList(this, false)" },
|
||||
{ "getStringKey": "Gen_Add" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeAllOptions(this)" },
|
||||
{ "getStringKey": "Gen_Remove_All" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeFromList(this)" },
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": [],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -47,7 +103,63 @@
|
||||
},
|
||||
{
|
||||
"function": "ignored_IPs",
|
||||
"type": "list",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{ "placeholder": "Enter value" },
|
||||
{ "suffix": "_in" },
|
||||
{ "cssClasses": "col-sm-10" },
|
||||
{ "prefillValue": "null" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": ["_in"] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-12" },
|
||||
{ "onClick": "addList(this, false)" },
|
||||
{ "getStringKey": "Gen_Add" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeAllOptions(this)" },
|
||||
{ "getStringKey": "Gen_Remove_All" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeFromList(this)" },
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": [],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -64,9 +176,104 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "NAME_CLEANUP_REGEX",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{ "placeholder": "Enter value" },
|
||||
{ "suffix": "_in" },
|
||||
{ "cssClasses": "col-sm-10" },
|
||||
{ "prefillValue": "null" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-sm-3" },
|
||||
{ "onClick": "removeAllOptions(this)" },
|
||||
{ "getStringKey": "Gen_Remove_All" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-sm-3" },
|
||||
{ "onClick": "removeFromList(this)" },
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": ["_in"] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-sm-2" },
|
||||
{ "onClick": "addList(this, false)" },
|
||||
{ "getStringKey": "Gen_Add" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": ["base64"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": [
|
||||
"XC5fYWlycGxheQ==",
|
||||
"XC5fdGNw",
|
||||
"XC5sb2NhbGRvbWFpbg==",
|
||||
"XC5sb2NhbA==",
|
||||
"XC5fZXNwaG9tZWxpYg==",
|
||||
"XC5fZ29vZ2xlY2FzdA==",
|
||||
"XC5sYW4=",
|
||||
"XC5ob21l",
|
||||
"LVthLWZBLUYwLTldezMyfQ==",
|
||||
"Iy4q"
|
||||
],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Name Cleanup REGEX"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "All the newly discovered device names are clened up by applying the following REGEX expression in this order. All the below are replaced by a blank string."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_MAC",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -86,7 +293,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Name",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "(unknown)",
|
||||
"options": [],
|
||||
@@ -106,7 +322,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Owner",
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 30,
|
||||
"default_value": "",
|
||||
"options": ["{value}"],
|
||||
@@ -133,7 +354,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_DeviceType",
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 30,
|
||||
"default_value": "",
|
||||
"options": ["{value}"],
|
||||
@@ -165,7 +391,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Vendor",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 250,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -185,7 +420,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Favorite",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -204,7 +448,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Group",
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 10,
|
||||
"default_value": "",
|
||||
"options": ["{value}"],
|
||||
@@ -231,7 +480,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Comments",
|
||||
"type": "string",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -250,7 +504,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_FirstConnection",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -270,7 +533,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_LastConnection",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -290,7 +562,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_LastIP",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -310,7 +591,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_StaticIP",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -329,7 +619,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_ScanCycle",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -348,7 +647,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_LogEvents",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -367,7 +675,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_AlertEvents",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -386,7 +703,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_AlertDeviceDown",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -405,7 +731,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_SkipRepeated",
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": ["{value}"],
|
||||
"options_params": [
|
||||
@@ -431,7 +762,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_LastNotification",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -451,7 +791,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_PresentLastScan",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -470,7 +819,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_NewDevice",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -489,7 +847,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Location",
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 250,
|
||||
"default_value": "",
|
||||
"options": ["{value}"],
|
||||
@@ -516,7 +879,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Archived",
|
||||
"type": "integer.checkbox",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -535,7 +907,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Network_Node_MAC_ADDR",
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": ["{value}"],
|
||||
"options_params": [
|
||||
@@ -566,7 +943,16 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Network_Node_port",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -585,7 +971,12 @@
|
||||
},
|
||||
{
|
||||
"function": "dev_Icon",
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": ["{value}"],
|
||||
"options_params": [
|
||||
@@ -608,25 +999,6 @@
|
||||
"string": "The icon associated with the device. Check the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md\" target=\"_blank\">documentation on icons</a> for more details."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "LESS_NAME_CLEANUP",
|
||||
"type": "integer.checkbox",
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Less Name Cleanup"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Check to start using the new code for cleaning device names. Removes all labels starting with underscore and removes network domain and search list."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"required": [
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"code_name": "nmap_dev_scan",
|
||||
"unique_prefix": "NMAPDEV",
|
||||
"plugin_type": "device_scanner",
|
||||
"execution_order" : "Layer_3",
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
"mapped_to_table": "CurrentScan",
|
||||
@@ -45,7 +46,12 @@
|
||||
"settings": [
|
||||
{
|
||||
"function": "RUN",
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
@@ -87,7 +93,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/nmap_dev_scan/nmap_dev.py ",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -122,7 +137,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 300,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -157,7 +181,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "*/5 * * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -192,7 +221,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": [],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -232,7 +270,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new"],
|
||||
"options": [
|
||||
"new",
|
||||
@@ -272,7 +319,12 @@
|
||||
},
|
||||
{
|
||||
"function": "ARGS",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "sudo nmap -sn -PR -oX - ",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -84,7 +84,7 @@ def execute_scan(subnets_list, timeout):
|
||||
for interface in subnets_list:
|
||||
nmap_output = execute_scan_on_interface(interface, timeout)
|
||||
|
||||
mylog('verbose', [f"[{pluginName}] nmap_output: ", nmap_output])
|
||||
# mylog('verbose', [f"[{pluginName}] nmap_output XML: ", nmap_output])
|
||||
|
||||
if nmap_output: # Proceed only if nmap output is not empty
|
||||
# Parse the XML output using python-nmap
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"code_name": "nmap_scan",
|
||||
"unique_prefix": "NMAP",
|
||||
"plugin_type": "other",
|
||||
"execution_order" : "Layer_4",
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
"data_filters": [
|
||||
@@ -354,7 +355,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
@@ -387,7 +393,12 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/nmap_scan/script.py ips={ips} macs={macs} timeout={timeout} args={args}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -414,7 +425,12 @@
|
||||
},
|
||||
{
|
||||
"function": "ARGS",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "-p -10000",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -441,7 +457,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "0 2 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -468,7 +489,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 30,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -495,7 +525,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -527,7 +566,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new", "watched-changed"],
|
||||
"options": ["new", "watched-changed", "watched-not-changed"],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -29,7 +29,16 @@
|
||||
"settings": [
|
||||
{
|
||||
"function": "INCLUDED_SECTIONS",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new_devices", "down_devices", "events"],
|
||||
"options": [
|
||||
"new_devices",
|
||||
@@ -70,7 +79,16 @@
|
||||
},
|
||||
{
|
||||
"function": "alert_down_time",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 5,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -89,7 +107,12 @@
|
||||
},
|
||||
{
|
||||
"function": "new_dev_condition",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -108,7 +131,12 @@
|
||||
},
|
||||
{
|
||||
"function": "event_condition",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"code_name": "nslookup_scan",
|
||||
"unique_prefix": "NSLOOKUP",
|
||||
"plugin_type": "other",
|
||||
"execution_order" : "Layer_4",
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
"show_ui": true,
|
||||
@@ -36,8 +37,13 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"default_value": "before_name_updates",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
"before_name_updates",
|
||||
@@ -70,7 +76,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/nslookup_scan/nslookup.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -105,7 +120,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "*/30 * * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -140,7 +160,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 10,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -1,18 +1,33 @@
|
||||
## Overview
|
||||
|
||||
PLugin functionality overview and links to external resources if relevant. Include use cases if available.
|
||||
The OMADA SDN plugin aims at synchronizing data between NetAlertX and a TPLINK OMADA SND controler by leveraging a tplink omada python library.
|
||||
#### features:
|
||||
1. extract list of OMADA Clients from OMADA and sync them up with NetAlertX
|
||||
2. extract list of OAMDA Devices (switches and access points) and sync them up with NetAlertX
|
||||
|
||||
> [!TIP]
|
||||
> Some tip.
|
||||
> some omada devices are apparently not fully compatible with the API which might lead to partial results.
|
||||
|
||||
### Quick setup guide
|
||||
|
||||
To set up the plugin correctly, make sure...
|
||||
1. You SHOULD (ie: strongly recommend) set up an account in your OMADA SDN console dedicated to NetAlertX OMADA_SDN plugin.
|
||||
- you should set USER TYPE = Local USer
|
||||
- you should set USER ROLE = Administrator (if you use a read-only role you won't be able to sync names from NetAlerX to OMADA SDN)
|
||||
- you can set Site Privileges = All Sites (or limit it to specific sites )
|
||||
|
||||
2. populate the variables in NetAlertX as instructed in the config plugin page.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Required Settings
|
||||
|
||||
- When to run `PREF_RUN`
|
||||
-
|
||||
- OMDSDN_url
|
||||
- OMDSDN_sites
|
||||
- OMDSDN_username
|
||||
- OMDSDN_password
|
||||
- OMDSDN_force_overwrite
|
||||
|
||||
|
||||
### Usage
|
||||
|
||||
@@ -20,4 +35,37 @@ To set up the plugin correctly, make sure...
|
||||
|
||||
### Notes
|
||||
|
||||
- Additional notes, limitations, Author info.
|
||||
#### features not implemented yet:
|
||||
3. extract list of OAMDA router Devices (er605...) and sync them up with NetAlertX
|
||||
(I need to setup my own er605 however due to its limitations I have no use for it, and due to limitations of opensense dhcp servers, I can't deploy it yet without breaking dhcp self registration into opnsense unbound - see below)
|
||||
|
||||
#### know limitations:
|
||||
OMADA SDN limitation fixed by the plugin:
|
||||
0. OMADA SDN can't use DNS for names and keep using MAC ref: https://community.tp-link.com/en/business/forum/topic/503782
|
||||
- when you use an OMADA user Role = Administrator, the plugin will attempt to fix OMADA's shortcoming and populat the NAME field from NetAlertX (from DNS/DHCP/...)
|
||||

|
||||
-
|
||||
|
||||
can not fix some of tplinks OMADA SDN own limitations/bugs:
|
||||
1. OMADA SDN switches uplinks/downlinks is broken if the default router is not an OMADA native device
|
||||
- (I try to circumvent that through a tree parsing heuristic but your mileage might vary...)
|
||||
- ref: https://community.tp-link.com/en/business/forum/topic/673628
|
||||
2. OMADA SDN clients are sometimes mapped to the wrong switch/port... for instance:
|
||||
- client -> access_switch1/port1 -> core_switch2/port2 sometimes shows as client -> core_switch2/port2
|
||||
- it is unclear if this issue is realted to (1)
|
||||
3. OMADA er605 routers do not self register DHCP names with a remote unbound DNS (nor embded DNS):
|
||||
- ref: https://community.tp-link.com/en/business/forum/topic/542472
|
||||
- it looks like some release candidate firmware might provide this feature... I will test when opnsesne Kea self registration get fixed as well(4)and I can get it dhcp proxy to work.
|
||||
4. Opnsense dhcp doesn't support relay and self-registration at the same time...
|
||||
- opnsense legacy ISC dhcp server doesn't support dhcp proxies: ref: https://forum.opnsense.org/index.php?topic=34254.0
|
||||
- opnsense new kea dhcp server doesn't support dns self registration (yet) ref: https://github.com/opnsense/core/pull/7362
|
||||
5. incompatible devices:
|
||||
- OMADA EAP245 - to be fair to tp-link, this access point works inside OMADA SDN, so it might be an issue with our omada python library but we can't extract data from it.
|
||||
|
||||
|
||||
|
||||
|
||||
### Other infos
|
||||
|
||||
- Author : Flying Toto
|
||||
- Date : 04-Jul-2024 - version 1.0
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"code_name": "omada_sdn_imp",
|
||||
"unique_prefix": "OMDSDN",
|
||||
"plugin_type": "device_scanner",
|
||||
"execution_order" : "Layer_0",
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
"mapped_to_table": "CurrentScan",
|
||||
@@ -39,15 +40,15 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
"once",
|
||||
"schedule",
|
||||
"always_after_scan"
|
||||
],
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan"],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
@@ -72,7 +73,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
|
||||
"default_value": "*/5 * * * *",
|
||||
"options": [],
|
||||
@@ -100,7 +106,12 @@
|
||||
},
|
||||
{
|
||||
"function": "url",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -114,33 +125,93 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Enter full URL with protocol <code>https://CHANGEME_omada.mylocaldomain</code>."
|
||||
"string": "Enter full URL with protocol <code>https://CHANGEME_omada.mylocaldomain:PORT</code>."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "site",
|
||||
"type": "text",
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"function": "sites",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{ "placeholder": "Enter value" },
|
||||
{ "suffix": "_in" },
|
||||
{ "cssClasses": "col-sm-10" },
|
||||
{ "prefillValue": "null" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": ["_in"] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-12" },
|
||||
{ "onClick": "addList(this, false)" },
|
||||
{ "getStringKey": "Gen_Add" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeAllOptions(this)" },
|
||||
{ "getStringKey": "Gen_Remove_All" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeFromList(this)" },
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": [],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "OMADA site"
|
||||
"string": "OMADA sites"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Omada SDN site id. You can get it by..."
|
||||
"string": "Omada SDN site IDs. For now, we only process the first site listed since NetAlertX's other probes won't traverse across NAT and routers. But if needed please submit an issue in github with your specific use case for consideration: <code>https://github.com/jokob-sk/NetAlertX/issues </code> "
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "username",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -160,7 +231,16 @@
|
||||
},
|
||||
{
|
||||
"function": "password",
|
||||
"type": "password",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "password" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -174,13 +254,50 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Omada SDN instance password"
|
||||
"string": "Omada SDN instance password."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "force_overwrite",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Force overwrite"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The plugin synchronizes names from NetAlertX to OMADA Clients. By default NetAlertX will only populate missing names in OMADASDN devices (i.e.: where the name is defaulting to the device MAC address); with this setting toggled, it will overwrite existing values regardless."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/omada_sdn_imp/omada_sdn.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -215,7 +332,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 30,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -247,6 +373,76 @@
|
||||
"string": "Maximale Zeit in Sekunden, die auf den Abschluss des Skripts gewartet werden soll. Bei Überschreitung dieser Zeit wird das Skript abgebrochen."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"default_value": [],
|
||||
"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 Hostname </li><li><code>Watched_Value2</code> is Parent Node </li><li><code>Watched_Value3</code> is Port </li><li><code>Watched_Value4</code> is SSID </li></ul>"
|
||||
}
|
||||
],
|
||||
"function": "WATCH",
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Watched"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Visto"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
],
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": ["new", "watched-changed"],
|
||||
"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."
|
||||
}
|
||||
],
|
||||
"function": "REPORT_ON",
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Report on"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
"new",
|
||||
"watched-changed",
|
||||
"watched-not-changed",
|
||||
"missing-in-last-scan"
|
||||
],
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"database_column_definitions": [
|
||||
@@ -364,7 +560,7 @@
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"mapped_to_column": "cur_NetworkSite",
|
||||
"mapped_to_column": "cur_Type",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
|
||||
BIN
front/plugins/omada_sdn_imp/omada_account_sample.png
Executable file
BIN
front/plugins/omada_sdn_imp/omada_account_sample.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 107 KiB |
@@ -1,12 +1,33 @@
|
||||
#!/usr/bin/env python
|
||||
__author__ = "ffsb"
|
||||
__version__ = "0.1" #initial
|
||||
__version__ = "0.2" # added logic to retry omada api call once as it seems to sometimes fail for some reasons, and error handling logic...
|
||||
__version__ = "0.3" # split devices API calls to allow multithreading but had to stop due to concurency issues.
|
||||
__version__ = "0.6" # found issue with multithreading - my omada calls redirect stdout which gets clubbered by normal stdout... not sure how to fix for now...
|
||||
# query OMADA SDN to populate NetAlertX witch omada switches, access points, clients.
|
||||
# try to identify and populate their connections by switch/accesspoints and ports/SSID
|
||||
# try to differentiate root bridges from accessory
|
||||
|
||||
|
||||
#
|
||||
# sample code to update unbound on opnsense - for reference...
|
||||
# curl -X POST -d '{"host":{"enabled":"1","hostname":"test","domain":"testdomain.com","rr":"A","mxprio":"","mx":"","server":"10.0.1.1","description":""}}' -H "Content-Type: application/json" -k -u $OPNS_KEY:$OPNS_SECRET https://$IPFW/api/unbound/settings/AddHostOverride
|
||||
#
|
||||
import os
|
||||
import pathlib
|
||||
import sys
|
||||
import json
|
||||
import sqlite3
|
||||
import tplink_omada_client
|
||||
import importlib.util
|
||||
import time
|
||||
import io
|
||||
import re
|
||||
import concurrent.futures
|
||||
|
||||
|
||||
#import netifaces
|
||||
|
||||
# Define the installation path and extend the system path for plugin imports
|
||||
INSTALL_PATH = "/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
@@ -22,26 +43,168 @@ from notification import write_notification
|
||||
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log')
|
||||
OMADA_API_RETURN_FILE = os.path.join(CUR_PATH, 'omada_api_return')
|
||||
|
||||
# Initialize the Plugin obj output file
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
#
|
||||
# sample target output:
|
||||
# 0 MAC, 1 IP, 2 Name, 3 switch/AP, 4 port/SSID, 5 TYPE
|
||||
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-6F', '192.168.0.217', '1A-2B-3C-4D-5E-6F', '17', '40-AE-30-A5-A7-50, 'Switch']"
|
||||
|
||||
# Constants for array indices
|
||||
MAC, IP, NAME, SWITCH_AP, PORT_SSID, TYPE = range(6)
|
||||
|
||||
# sample omada devices input format:
|
||||
#
|
||||
# 0.MAC 1.IP 2.type 3.status 4.name 5.model
|
||||
#40-AE-30-A5-A7-50 192.168.0.11 ap CONNECTED office_Access_point EAP773(US) v1.0
|
||||
#B0-95-75-46-0C-39 192.168.0.4 switch CONNECTED pantry12 T1600G-52PS v4.0
|
||||
dMAC, dIP, dTYPE, dSTATUS, dNAME, dMODEL = range(6)
|
||||
|
||||
# sample omada clients input format:
|
||||
# 0 MAC, 1 IP, 2 Name, 3 switch/AP, 4 port/SSID,
|
||||
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-6F', '192.168.0.217', '1A-2B-3C-4D-5E-6F', 'myssid_name2', '(office_Access_point)']"
|
||||
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-01', '192.168.0.153', 'frontyard_ESP_29E753', 'pantry12', '(48)']"
|
||||
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-02', '192.168.0.1', 'bastion', 'office24', '(23)']"
|
||||
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-03', '192.168.0.226', 'brick', 'myssid_name3', '(office_Access_point)']"
|
||||
cMAC, cIP, cNAME, cSWITCH_AP, cPORT_SSID = range(5)
|
||||
|
||||
OMDLOGLEVEL = 'debug'
|
||||
pluginName = 'OMDSDN'
|
||||
#
|
||||
# translate MAC address from standard ieee model to ietf draft
|
||||
# AA-BB-CC-DD-EE-FF to aa:bb:cc:dd:ee:ff
|
||||
# tplink adheres to ieee, Nax adheres to ietf
|
||||
def ieee2ietf_mac_formater(inputmac):
|
||||
return(inputmac.lower().replace('-',':'))
|
||||
|
||||
def ietf2ieee_mac_formater(inputmac):
|
||||
return(inputmac.upper().replace(':','-'))
|
||||
|
||||
def get_mac_from_IP(target_IP):
|
||||
from scapy.all import ARP, Ether, srp
|
||||
try:
|
||||
arp_request = ARP(pdst=target_IP)
|
||||
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
|
||||
packet = ether/arp_request
|
||||
result = srp(packet, timeout=3, verbose=0)[0]
|
||||
if result:
|
||||
return result[0][1].hwsrc
|
||||
else:
|
||||
return None
|
||||
except Exception as e:
|
||||
mylog('minimal', [f'[{pluginName}] get_mac_from_IP ERROR:{e}'])
|
||||
return None
|
||||
|
||||
|
||||
|
||||
#
|
||||
# wrapper to call the omada python library's own wrapper
|
||||
# it returns the output as a multiline python string
|
||||
#
|
||||
def callomada(myargs):
|
||||
arguments=" ".join(myargs)
|
||||
mylog('verbose', [f'[{pluginName}] callomada:{arguments}'])
|
||||
from tplink_omada_client.cli import main as omada
|
||||
from contextlib import redirect_stdout
|
||||
omada_output = ''
|
||||
retries = 2
|
||||
while omada_output == '' and retries > 1:
|
||||
retries = retries - 1
|
||||
try:
|
||||
mf = io.StringIO()
|
||||
with redirect_stdout(mf):
|
||||
bar = omada(myargs)
|
||||
omada_output = mf.getvalue()
|
||||
except Exception as e:
|
||||
mylog('minimal', [f'[{pluginName}] ERROR WHILE CALLING callomada:{arguments}\n {mf}'])
|
||||
omada_output= ''
|
||||
return(omada_output)
|
||||
|
||||
#
|
||||
# extract all the mac addresses from a multilines text...
|
||||
# return a list of MAC as 'string'
|
||||
#
|
||||
def extract_mac_addresses(text):
|
||||
mac_pattern = r"([0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2})"
|
||||
mac_addresses = re.findall(mac_pattern, text)
|
||||
return ["".join(parts) for parts in mac_addresses]
|
||||
|
||||
def find_default_gateway_ip ():
|
||||
#import netifaces
|
||||
#gw = netifaces.gateways()
|
||||
#return(gw['default'][netifaces.AF_INET][0])
|
||||
from scapy.all import conf, Route, sr1, IP, ICMP
|
||||
default_route = conf.route.route("0.0.0.0")
|
||||
return default_route[2] if default_route[2] else None
|
||||
|
||||
|
||||
#return('192.168.0.1')
|
||||
|
||||
|
||||
def add_uplink (uplink_mac, switch_mac, device_data_bymac, sadevices_linksbymac,port_byswitchmac_byclientmac):
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}] trying to add uplink="{uplink_mac}" to switch="{switch_mac}"'])
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}] before adding:"{device_data_bymac[switch_mac]}"'])
|
||||
if device_data_bymac[switch_mac][SWITCH_AP] == 'null':
|
||||
device_data_bymac[switch_mac][SWITCH_AP] = uplink_mac
|
||||
if device_data_bymac[switch_mac][TYPE] == 'Switch' and device_data_bymac[uplink_mac][TYPE] == 'Switch':
|
||||
port_to_uplink = port_byswitchmac_byclientmac[switch_mac][uplink_mac]
|
||||
#find_port_of_uplink_switch(switch_mac, uplink_mac)
|
||||
else:
|
||||
port_to_uplink=device_data_bymac[uplink_mac][PORT_SSID]
|
||||
device_data_bymac[switch_mac][PORT_SSID] = port_to_uplink
|
||||
# mylog(OMDLOGLEVEL, [f'[{pluginName}] after adding:"{device_data_bymac[switch_mac]}"'])
|
||||
for link in sadevices_linksbymac[switch_mac]:
|
||||
if device_data_bymac[link][SWITCH_AP] == 'null' and device_data_bymac[switch_mac][TYPE] == 'Switch':
|
||||
add_uplink(switch_mac, link, device_data_bymac, sadevices_linksbymac,port_byswitchmac_byclientmac)
|
||||
|
||||
|
||||
pluginName = '<unique_prefix>'
|
||||
|
||||
# ----------------------------------------------
|
||||
# Main initialization
|
||||
def main():
|
||||
mylog('verbose', [f'[{pluginName}] In script'])
|
||||
|
||||
start_time = time.time()
|
||||
mylog('verbose', [f'[{pluginName}] starting execution'])
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
db = DB() # instance of class DB
|
||||
db.open()
|
||||
# Create a Device_obj instance
|
||||
device_handler = Device_obj(db)
|
||||
# Retrieve configuration settings
|
||||
some_setting = get_setting_value('OMDSDN_url')
|
||||
# these should be self-explanatory
|
||||
omada_sites = []
|
||||
omada_username = get_setting_value('OMDSDN_username')
|
||||
omada_password = get_setting_value('OMDSDN_password')
|
||||
omada_sites = get_setting_value('OMDSDN_sites')
|
||||
omada_site = omada_sites[0]
|
||||
omada_url = get_setting_value('OMDSDN_url')
|
||||
|
||||
omada_login = callomada(['-t','myomada','target','--url',omada_url,'--user',omada_username,
|
||||
'--password',omada_password,'--site',omada_site,'--set-default'])
|
||||
mylog('verbose', [f'[{pluginName}] login to omada result is: {omada_login}'])
|
||||
|
||||
clients_list = callomada(['-t','myomada','clients'])
|
||||
mylog('verbose', [f'[{pluginName}] clients found:"{clients_list.count("\n")}"\n{clients_list}'])
|
||||
|
||||
switches_and_aps = callomada(['-t','myomada','devices'])
|
||||
mylog('verbose', [f'[{pluginName}] omada devices (switches, access points) found:"{switches_and_aps.count("\n")}" \n {switches_and_aps}'])
|
||||
|
||||
|
||||
#some_setting = get_setting_value('OMDSDN_url')
|
||||
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}] some_setting value {some_setting}'])
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] ffsb'])
|
||||
|
||||
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] some_setting calue {some_setting}'])
|
||||
|
||||
# retrieve data
|
||||
device_data = get_device_data(some_setting)
|
||||
device_data = get_device_data(clients_list, switches_and_aps, device_handler)
|
||||
|
||||
# Process the data into native application tables
|
||||
mylog('verbose', [f'[{pluginName}] New entries to create: "{len(device_data)}"'])
|
||||
if len(device_data) > 0:
|
||||
|
||||
# insert devices into the lats_result.log
|
||||
@@ -50,36 +213,238 @@ def main():
|
||||
# {
|
||||
# "column": "Object_PrimaryID", <--------- the value I save into primaryId
|
||||
# "mapped_to_column": "cur_MAC", <--------- gets unserted into the CurrentScan DB table column cur_MAC
|
||||
#
|
||||
for device in device_data:
|
||||
plugin_objects.add_object(
|
||||
primaryId = device['some_id'], # MAC
|
||||
secondaryId = device['some_id'], # IP
|
||||
watched1 = device['some_id'], # NAME/HOSTNAME
|
||||
watched2 = device['some_id'], # PARENT NETWORK NODE MAC
|
||||
watched3 = device['some_id'], # PORT
|
||||
watched4 = device['some_id'], # SSID
|
||||
extra = device['some_id'], # SITENAME (cur_NetworkSite) or VENDOR (cur_Vendor) (PICK one and adjust config.json -> "column": "Extra")
|
||||
foreignKey = device['some_id']) # usually MAC
|
||||
# watched1 = 'null' ,
|
||||
# figure a way to run my udpate script delayed
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] New entries: "{len(new_devices)}"'])
|
||||
for device in device_data:
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] main parsing device: "{device}"'])
|
||||
myport = device[PORT_SSID] if device[PORT_SSID].isdigit() else ''
|
||||
myssid = device[PORT_SSID] if not device[PORT_SSID].isdigit() else ''
|
||||
ParentNetworkNode = ieee2ietf_mac_formater(device[SWITCH_AP]) if device[SWITCH_AP] != 'Internet' else 'Internet'
|
||||
mymac = ieee2ietf_mac_formater(device[MAC])
|
||||
plugin_objects.add_object(
|
||||
primaryId = mymac, # MAC
|
||||
secondaryId = device[IP], # IP
|
||||
watched1 = device[NAME], # NAME/HOSTNAME
|
||||
watched2 = ParentNetworkNode, # PARENT NETWORK NODE MAC
|
||||
watched3 = myport, # PORT
|
||||
watched4 = myssid, # SSID
|
||||
extra = device[TYPE],
|
||||
#omada_site, # SITENAME (cur_NetworkSite) or VENDOR (cur_Vendor) (PICK one and adjust config.json -> "column": "Extra")
|
||||
foreignKey = device[MAC].lower().replace('-',':')) # usually MAC
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] New entries: "{mymac:<18}, {device[IP]:<16}, {device[NAME]:<63}, {ParentNetworkNode:<18}, {myport:<4}, {myssid:<32}, {device[TYPE]}"'])
|
||||
mylog('verbose', [f'[{pluginName}] New entries: "{len(device_data)}"'])
|
||||
|
||||
# log result
|
||||
plugin_objects.write_result_file()
|
||||
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}] TEST name from MAC: {device_handler.getValueWithMac('dev_Name','00:e2:59:00:a0:8e')}'])
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}] TEST MAC from IP: {get_mac_from_IP('192.168.0.1')} also {ietf2ieee_mac_formater(get_mac_from_IP('192.168.0.1'))}'])
|
||||
end_time = time.time()
|
||||
mylog('verbose', [f'[{pluginName}] execution completed in {end_time - start_time:.2f} seconds'])
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
def get_omada_devices_details(msadevice_data):
|
||||
mthisswitch = msadevice_data[dMAC]
|
||||
mtype = msadevice_data[dTYPE]
|
||||
mswitch_detail = ''
|
||||
mswitch_dump = ''
|
||||
if mtype == 'ap':
|
||||
mswitch_detail = callomada(['access-point', mthisswitch])
|
||||
elif mtype == 'switch':
|
||||
mswitch_detail = callomada(['switch', mthisswitch])
|
||||
mswitch_dump = callomada(['-t','myomada','switch','-d',mthisswitch])
|
||||
else:
|
||||
mswitch_detail = ''
|
||||
nswitch_dump = ''
|
||||
return mswitch_detail, mswitch_dump
|
||||
|
||||
|
||||
|
||||
# ----------------------------------------------
|
||||
# retrieve data
|
||||
def get_device_data(some_setting):
|
||||
def get_device_data(omada_clients_output,switches_and_aps,device_handler):
|
||||
|
||||
device_data = []
|
||||
|
||||
# sample omada devices input format:
|
||||
# 0.MAC 1.IP 2.type 3.status 4.name 5.model
|
||||
#40-AE-30-A5-A7-50 192.168.0.11 ap CONNECTED office_Access_point EAP773(US) v1.0
|
||||
#B0-95-75-46-0C-39 192.168.0.4 switch CONNECTED pantry12 T1600G-52PS v4.0
|
||||
#
|
||||
# sample target output:
|
||||
# 0 MAC, 1 IP, 2 Name, 3 switch/AP, 4 port/SSID, 5 TYPE
|
||||
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-6F', '192.168.0.217', '1A-2B-3C-4D-5E-6F', '17', '40-AE-30-A5-A7-50, 'Switch']"
|
||||
#constants
|
||||
sadevices_macbyname = {}
|
||||
sadevices_macbymac = {}
|
||||
sadevices_linksbymac = {}
|
||||
port_byswitchmac_byclientmac = {}
|
||||
device_data_bymac = {}
|
||||
device_data_mac_byip = {}
|
||||
omada_force_overwrite = get_setting_value('OMDSDN_force_overwrite')
|
||||
switch_details = {}
|
||||
switch_dumps = {}
|
||||
|
||||
sadevices = switches_and_aps.splitlines()
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] switches_and_aps rows: "{len(sadevices)}"'])
|
||||
|
||||
for sadevice in sadevices:
|
||||
sadevice_data = sadevice.split()
|
||||
thisswitch = sadevice_data[dMAC]
|
||||
thistype = sadevice_data[dTYPE]
|
||||
switch_details[thisswitch], switch_dumps[thisswitch] = get_omada_devices_details(sadevice_data)
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] switches details collected "{len(switch_details)}"'])
|
||||
mylog('verbose', [f'[{pluginName}] dump details collected "{len(switch_details)}"'])
|
||||
# Using ThreadPoolExecutor for parallel execution
|
||||
|
||||
for sadevice in sadevices:
|
||||
sadevice_data = sadevice.split()
|
||||
thisswitch = sadevice_data[dMAC]
|
||||
sadevices_macbyname[sadevice_data[4]] = thisswitch
|
||||
if sadevice_data[dTYPE] == 'ap':
|
||||
sadevice_type = 'AP'
|
||||
#sadevice_details = callomada(['access-point', thisswitch])
|
||||
sadevice_details = switch_details[thisswitch]
|
||||
if sadevice_details == '':
|
||||
sadevice_links = [thisswitch]
|
||||
else:
|
||||
sadevice_links = extract_mac_addresses(sadevice_details)
|
||||
sadevices_linksbymac[thisswitch] = sadevice_links[1:]
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}]adding switch details: "{sadevice_details}"'])
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}]links are: "{sadevice_links}"'])
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}]linksbymac are: "{sadevices_linksbymac[thisswitch]}"'])
|
||||
elif sadevice_data[dTYPE] == 'switch':
|
||||
sadevice_type = 'Switch'
|
||||
#sadevice_details=callomada(['switch', thisswitch])
|
||||
sadevice_details = switch_details[thisswitch]
|
||||
if sadevice_details == '':
|
||||
sadevice_links = [thisswitch]
|
||||
else:
|
||||
sadevice_links=extract_mac_addresses(sadevice_details)
|
||||
sadevices_linksbymac[thisswitch] = sadevice_links[1:]
|
||||
# recovering the list of switches connected to sadevice switch and on which port...
|
||||
#switchdump = callomada(['-t','myomada','switch','-d',thisswitch])
|
||||
switchdump = switch_dumps[thisswitch]
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] switchdump: {switchdump}'])
|
||||
port_byswitchmac_byclientmac[thisswitch] = {}
|
||||
for link in sadevices_linksbymac[thisswitch]:
|
||||
port_pattern = r"(?:{[^}]*\"port\"\: )([0-9]+)(?=[^}]*"+re.escape(link)+r")"
|
||||
myport = re.findall(port_pattern, switchdump,re.DOTALL)
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}] switchdump: link={link} myport:{myport}'])
|
||||
port_byswitchmac_byclientmac[thisswitch][link] = myport[0] if myport else ''
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}]links are: "{sadevice_links}"'])
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}]linksbymac are: "{sadevices_linksbymac[thisswitch]}"'])
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}]ports of each links are: "{port_byswitchmac_byclientmac[thisswitch]}"'])
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}]adding switch details: "{sadevice_details}"'])
|
||||
else:
|
||||
sadevice_type = 'null'
|
||||
sadevice_details='null'
|
||||
device_data_bymac[thisswitch] = [thisswitch, sadevice_data[dIP], sadevice_data[dNAME], 'null', 'null',sadevice_type]
|
||||
device_data_mac_byip[sadevice_data[dIP]] = thisswitch
|
||||
foo=[thisswitch, sadevice_data[1], sadevice_data[4], 'null', 'null']
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}]adding switch: "{foo}"'])
|
||||
|
||||
|
||||
|
||||
|
||||
# sadevices_macbymac[thisswitch] = thisswitch
|
||||
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] switch_macbyname: "{sadevices_macbyname}"'])
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] switches: "{device_data_bymac}"'])
|
||||
|
||||
|
||||
# do some processing, call exteranl APIs, and return a device list
|
||||
# ...
|
||||
#
|
||||
# sample omada clients input format:
|
||||
# 0 MAC, 1 IP, 2 Name, 3 switch/AP, 4 port/SSID,
|
||||
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-6F', '192.168.0.217', '1A-2B-3C-4D-5E-6F', 'myssid_name2', '(office_Access_point)']"
|
||||
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-01', '192.168.0.153', 'frontyard_ESP_29E753', 'pantry12', '(48)']"
|
||||
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-02', '192.168.0.1', 'bastion', 'office24', '(23)']"
|
||||
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-03', '192.168.0.226', 'brick', 'myssid_name3', '(office_Access_point)']"
|
||||
|
||||
# sample target output:
|
||||
# 0 MAC, 1 IP, 2 Name, 3 MAC of switch/AP, 4 port/SSID, 5 TYPE
|
||||
#17:27:10 [<unique_prefix>] token: "['1A-2B-3C-4D-5E-6F', '192.168.0.217', 'brick', 'office_Access_point','myssid_name2', , 'Switch']"
|
||||
|
||||
return device_data
|
||||
odevices = omada_clients_output.splitlines()
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] omada_clients_outputs rows: "{len(odevices)}"'])
|
||||
for odevice in odevices:
|
||||
odevice_data = odevice.split()
|
||||
odevice_data_reordered = [ MAC, IP, NAME, SWITCH_AP, PORT_SSID, TYPE]
|
||||
odevice_data_reordered[MAC]=odevice_data[cMAC]
|
||||
odevice_data_reordered[IP]=odevice_data[cIP]
|
||||
real_naxname = device_handler.getValueWithMac('dev_Name',ieee2ietf_mac_formater(odevice_data[cMAC]))
|
||||
|
||||
#
|
||||
# if the name stored in Nax for a device is empty or the MAC addres or has some parenthhesis or is the same as in omada
|
||||
# don't bother updating omada's name at all.
|
||||
#
|
||||
|
||||
naxname = real_naxname
|
||||
if real_naxname != None:
|
||||
if '(' in real_naxname:
|
||||
# removing parenthesis and domains from the name
|
||||
naxname = real_naxname.split('(')[0]
|
||||
if naxname != None and '.' in naxname:
|
||||
naxname = naxname.split('.')[0]
|
||||
if naxname in ( None, 'null', '' ):
|
||||
naxname = odevice_data[cNAME] if odevice_data[cNAME] != '' else odevice_data[cMAC]
|
||||
naxname = naxname.strip()
|
||||
mylog('debug', [f'[{pluginName}] TEST name from MAC: {naxname}'])
|
||||
if odevice_data[cNAME] in (odevice_data[cMAC], 'null', ''):
|
||||
mylog('verbose', [f'[{pluginName}] updating omada server because odevice_data is: {odevice_data[cNAME]} and naxname is: "{naxname}"'])
|
||||
callomada(['set-client-name', odevice_data[cMAC], naxname])
|
||||
odevice_data_reordered[NAME] = naxname
|
||||
else:
|
||||
if omada_force_overwrite and naxname != odevice_data[cNAME] :
|
||||
mylog('verbose', [f'[{pluginName}] updating omada server because odevice_data is: "{odevice_data[cNAME]} and naxname is: "{naxname}"'])
|
||||
callomada(['set-client-name', odevice_data[cMAC], naxname])
|
||||
odevice_data_reordered[NAME] = naxname
|
||||
mightbeport = odevice_data[cPORT_SSID].lstrip('(')
|
||||
mightbeport = mightbeport.rstrip(')')
|
||||
if mightbeport.isdigit():
|
||||
odevice_data_reordered[SWITCH_AP] = odevice_data[cSWITCH_AP]
|
||||
odevice_data_reordered[PORT_SSID] = mightbeport
|
||||
else:
|
||||
odevice_data_reordered[SWITCH_AP] = mightbeport
|
||||
odevice_data_reordered[PORT_SSID] = odevice_data[cSWITCH_AP]
|
||||
|
||||
# replacing the switch name with its MAC...
|
||||
try:
|
||||
mightbemac = sadevices_macbyname[odevice_data_reordered[SWITCH_AP]]
|
||||
odevice_data_reordered[SWITCH_AP] = mightbemac
|
||||
except KeyError:
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] could not find the mac adddress for: "{odevice_data_reordered[SWITCH_AP]}"'])
|
||||
# adding the type
|
||||
odevice_data_reordered[TYPE] = 'null'
|
||||
device_data_bymac[odevice_data_reordered[MAC]] = odevice_data_reordered
|
||||
device_data_mac_byip[odevice_data_reordered[IP]] = odevice_data_reordered[MAC]
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] tokens: "{odevice_data}"'])
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] tokens_reordered: "{odevice_data_reordered}"'])
|
||||
# populating the uplinks nodes of the omada switches and access points manually
|
||||
# since OMADA SDN makes is unreliable if the gateway is not their own tplink hardware...
|
||||
|
||||
|
||||
# step1 let's find the the default router
|
||||
#
|
||||
default_router_ip = find_default_gateway_ip()
|
||||
default_router_mac = ietf2ieee_mac_formater(get_mac_from_IP(default_router_ip))
|
||||
device_data_bymac[default_router_mac][TYPE] = 'Firewall'
|
||||
# step2 let's find the first switch and set the default router parent to internet
|
||||
first_switch=device_data_bymac[default_router_mac][SWITCH_AP]
|
||||
device_data_bymac[default_router_mac][SWITCH_AP] = 'Internet'
|
||||
# step3 let's set the switch connected to the default gateway uplink to the default gateway and hardcode port to 1 for now:
|
||||
#device_data_bymac[first_switch][SWITCH_AP]=default_router_mac
|
||||
#device_data_bymac[first_switch][SWITCH_AP][PORT_SSID] = '1'
|
||||
# step4, let's go recursively through switches other links to mark update their uplinks
|
||||
# and pray it ends one day...
|
||||
#
|
||||
add_uplink(default_router_mac,first_switch, device_data_bymac,sadevices_linksbymac,port_byswitchmac_byclientmac)
|
||||
return device_data_bymac.values()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -62,8 +62,13 @@
|
||||
"settings": [
|
||||
{
|
||||
"function": "RUN",
|
||||
"type": "text.select",
|
||||
"default_value": "on_new_device",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
"once",
|
||||
@@ -96,7 +101,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/pholus_scan/script.py userSubnets={subnets} timeoutSec={timeout}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -123,7 +137,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 300,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -150,7 +173,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "30 3 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -177,7 +205,16 @@
|
||||
},
|
||||
{
|
||||
"function": "DAYS_DATA",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 30,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -204,7 +241,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1", "Watched_Value2"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -236,7 +282,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new"],
|
||||
"options": [
|
||||
"new",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"code_name": "pihole_scan",
|
||||
"unique_prefix": "PIHOLE",
|
||||
"plugin_type": "device_scanner",
|
||||
"execution_order" : "Layer_2",
|
||||
"enabled": true,
|
||||
"data_source": "sqlite-db-query",
|
||||
"mapped_to_table": "CurrentScan",
|
||||
@@ -60,7 +61,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
@@ -93,7 +99,12 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "SELECT n.hwaddr AS Object_PrimaryID, {s-quote}null{s-quote} AS Object_SecondaryID, datetime() AS DateTime, na.ip AS Watched_Value1, n.lastQuery AS Watched_Value2, na.name AS Watched_Value3, n.macVendor AS Watched_Value4, {s-quote}null{s-quote} AS Extra, n.hwaddr AS ForeignKey FROM EXTERNAL_PIHOLE.Network AS n LEFT JOIN EXTERNAL_PIHOLE.Network_Addresses AS na ON na.network_id = n.id WHERE n.hwaddr NOT LIKE {s-quote}ip-%{s-quote} AND n.hwaddr is not {s-quote}00:00:00:00:00:00{s-quote} AND na.ip is not null",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -120,7 +131,12 @@
|
||||
},
|
||||
{
|
||||
"function": "DB_PATH",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "/etc/pihole/pihole-FTL.db",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -147,7 +163,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "*/30 * * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -164,17 +185,26 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Only enabled if you select <code>schedule</code> in the <a href=\"#ARPSCAN_RUN\"><code>ARPSCAN_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>*/30 * * * *</code> will run the scan every 30 minutes. Will be run NEXT time the time passes. <br/> It's recommended to use the same schedule interval for all plugins responsible for discovering new devices."
|
||||
"string": "Only enabled if you select <code>schedule</code> in the <a href=\"#PIHOLE_RUN\"><code>PIHOLE_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>*/30 * * * *</code> will run the scan every 30 minutes. Will be run NEXT time the time passes. <br/> It's recommended to use the same schedule interval for all plugins responsible for discovering new devices."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Solo está habilitado si selecciona <code>schedule</code> en la configuración <a href=\"#ARPSCAN_RUN\"><code>ARPSCAN_RUN</code></a>. Asegúrese de ingresar la programación en el formato similar a cron correcto (por ejemplo, valide en <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Por ejemplo, ingresar <code>*/30 * * * *</code> ejecutará el escaneo cada 30 minutos. Se ejecutará la PRÓXIMA vez que pase el tiempo. <br/> Se recomienda utilizar el mismo intervalo de programación para todos los complementos que analizan su red."
|
||||
"string": "Solo está habilitado si selecciona <code>schedule</code> en la configuración <a href=\"#PIHOLE_RUN\"><code>PIHOLE_RUN</code></a>. Asegúrese de ingresar la programación en el formato similar a cron correcto (por ejemplo, valide en <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Por ejemplo, ingresar <code>*/30 * * * *</code> ejecutará el escaneo cada 30 minutos. Se ejecutará la PRÓXIMA vez que pase el tiempo. <br/> Se recomienda utilizar el mismo intervalo de programación para todos los complementos que analizan su red."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1", "Watched_Value2"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -206,7 +236,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new"],
|
||||
"options": [
|
||||
"new",
|
||||
|
||||
@@ -79,6 +79,22 @@ def decodeBase64(inputParamBase64):
|
||||
|
||||
return result
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
def normalize_mac(mac):
|
||||
# Split the MAC address by colon (:) or hyphen (-) and convert each part to uppercase
|
||||
parts = mac.upper().split(':')
|
||||
|
||||
# If the MAC address is split by hyphen instead of colon
|
||||
if len(parts) == 1:
|
||||
parts = mac.upper().split('-')
|
||||
|
||||
# Normalize each part to have exactly two hexadecimal digits
|
||||
normalized_parts = [part.zfill(2) for part in parts]
|
||||
|
||||
# Join the parts with colon (:)
|
||||
normalized_mac = ':'.join(normalized_parts)
|
||||
|
||||
return normalized_mac
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
class Plugin_Object:
|
||||
|
||||
@@ -47,7 +47,16 @@
|
||||
"settings": [
|
||||
{
|
||||
"function": "enable_password",
|
||||
"type": "boolean",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -66,7 +75,16 @@
|
||||
},
|
||||
{
|
||||
"function": "password",
|
||||
"type": "password.SHA256",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "password" }],
|
||||
"transformers": ["sha256"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "123456",
|
||||
"options": [],
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
## Overview
|
||||
|
||||
A plugin for importing devices from an SNMP enabled router or switch. Using SNMP offers an efficient way to discover IPv4 devices across one or more networks/subnets/vlans.
|
||||
A plugin for importing devices from an SNMP-enabled router or switch. Using SNMP offers an efficient way to discover IPv4 devices across one or more networks/subnets/vlans.
|
||||
|
||||
### Usage
|
||||
|
||||
Specify the following settings in the Settings section of NetAlertX:
|
||||
|
||||
- `SNMPDSC_routers` - A list of `snmpwalk` commands to execute against IP addresses of roputers/switches with SNMP turned on. For example:
|
||||
- `SNMPDSC_routers` - A list of `snmpwalk` commands to execute against IP addresses of routers/switches with SNMP turned on. For example:
|
||||
|
||||
- `snmpwalk -v 2c -c public -OXsq 192.168.1.1 .1.3.6.1.2.1.3.1.1.2`
|
||||
- `snmpwalk -v 2c -c public -Oxsq 192.168.1.1 .1.3.6.1.2.1.3.1.1.2` (note: lower case `x`)
|
||||
|
||||
|
||||
If unsure, please check [snmpwalk examples](https://www.comparitech.com/net-admin/snmpwalk-examples-windows-linux/).
|
||||
|
||||
### Setup Cisco IOS
|
||||
|
||||
Enable IOS SNMP service and restrict to selected (internal) IP/Subnet.
|
||||
@@ -35,5 +37,24 @@ show snmp
|
||||
### Notes
|
||||
|
||||
- Only IPv4 supported.
|
||||
- The SNMP OID `.1.1.1.3.6.1.2.1.3.1.1.2` is specifically for devices IPv4 ARP table. This OID has been tested on Cisco ISRs and other L3 devices. Support may vary between other vendors / devices.
|
||||
- Expected output (ingestion) in format `iso.3.6.1.2.1.3.1.1.2.3.1.192.168.1.2 "6C 6C 6C 6C 6C 6C "`.
|
||||
- The SNMP OID `.1.1.1.3.6.1.2.1.3.1.1.2` is specifically for devices IPv4 ARP table. This OID has been tested on Cisco ISRs and other L3 devices. Support may vary between other vendors/devices.
|
||||
- Expected output (ingestion) in formats:
|
||||
|
||||
- `iso.3.6.1.2.1.3.1.1.2.3.1.192.168.1.2 "6C 6C 6C 6C 6C 6C "`.
|
||||
- `ipNetToMediaPhysAddress[3][192.168.1.9] 6C:6C:6C:6C:6C:b6C1`.
|
||||
|
||||
|
||||
### Finding your OID
|
||||
|
||||
- Ssh into the router (in this example the IP of the router is `192.168.1.1`)
|
||||
- On the router execute `snmptranslate -On -IR ipNetToMediaPhysAddress` (This is a UniFi router example, and the `object_id` is `ipNetToMediaPhysAddress`. This might vary between vendors, google your router manufacturer examples.)
|
||||
|
||||
```bash
|
||||
jokob@SecurityGateway-USG:~$ snmptranslate -On -IR ipNetToMediaPhysAddress
|
||||
.1.3.6.1.2.1.4.22.1.2
|
||||
```
|
||||
|
||||
- Use the `snmpwalk -v 2c -OXsq -c public 192.168.1.1 .1.3.6.1.2.1.4.22.1.2` command in NetAlertX
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"code_name": "snmp_discovery",
|
||||
"unique_prefix": "SNMPDSC",
|
||||
"plugin_type": "device_scanner",
|
||||
"execution_order" : "Layer_1",
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
"data_filters": [
|
||||
@@ -339,7 +340,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
@@ -372,7 +378,12 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/snmp_discovery/script.py routers={s-quote}{routers}{s-quote}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -399,7 +410,63 @@
|
||||
},
|
||||
{
|
||||
"function": "routers",
|
||||
"type": "list",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{ "placeholder": "Enter value" },
|
||||
{ "suffix": "_in" },
|
||||
{ "cssClasses": "col-sm-10" },
|
||||
{ "prefillValue": "null" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": ["_in"] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-12" },
|
||||
{ "onClick": "addList(this, false)" },
|
||||
{ "getStringKey": "Gen_Add" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeAllOptions(this)" },
|
||||
{ "getStringKey": "Gen_Remove_All" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeFromList(this)" },
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": [
|
||||
"snmpwalk -v 2c -c public -OXsq 192.168.1.1 .1.3.6.1.2.1.3.1.1.2"
|
||||
],
|
||||
@@ -428,7 +495,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "0 2 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -455,7 +527,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 5,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -486,7 +567,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -518,7 +608,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new", "watched-changed"],
|
||||
"options": [
|
||||
"new",
|
||||
|
||||
@@ -11,7 +11,7 @@ import sys
|
||||
INSTALL_PATH="/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64, handleEmpty
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64, handleEmpty, normalize_mac
|
||||
from logger import mylog
|
||||
from helper import timeNowTZ
|
||||
from const import logPath, applicationPath
|
||||
@@ -25,7 +25,7 @@ def main():
|
||||
mylog('verbose', ['[SNMPDSC] In script '])
|
||||
|
||||
# init global variables
|
||||
global ROUTERS
|
||||
global snmpWalkCmds
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='This plugin is used to discover devices via the arp table(s) of a RFC1213 compliant router or switch.')
|
||||
@@ -35,18 +35,20 @@ def main():
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
|
||||
if values.routers:
|
||||
ROUTERS = values.routers.split('=')[1].replace('\'','')
|
||||
snmpWalkCmds = values.routers.split('=')[1].replace('\'','')
|
||||
|
||||
|
||||
if ',' in ROUTERS:
|
||||
routers = ROUTERS.split(',')
|
||||
if ',' in snmpWalkCmds:
|
||||
commands = snmpWalkCmds.split(',')
|
||||
else:
|
||||
routers = [ROUTERS]
|
||||
commands = [snmpWalkCmds]
|
||||
|
||||
for router in routers:
|
||||
mylog('verbose', ['[SNMPDSC] Router snmpwalk command: ', router])
|
||||
for cmd in commands:
|
||||
mylog('verbose', ['[SNMPDSC] Router snmpwalk command: ', cmd])
|
||||
timeoutSec = 10
|
||||
snmpwalkArgs = router.split(' ')
|
||||
# split the string, remove white spaces around each item, and exclude any empty strings
|
||||
snmpwalkArgs = [arg.strip() for arg in cmd.split(' ') if arg.strip()]
|
||||
|
||||
|
||||
# Execute N probes and insert in list
|
||||
probes = 1 # N probes
|
||||
@@ -60,11 +62,9 @@ def main():
|
||||
|
||||
for line in lines:
|
||||
|
||||
tmpSplt = line.split('"')
|
||||
|
||||
tmpSplt = line.split('"')
|
||||
|
||||
if len(tmpSplt) == 3:
|
||||
|
||||
|
||||
ipStr = tmpSplt[0].split('.')[-4:] # Get the last 4 elements to extract the IP
|
||||
macStr = tmpSplt[1].strip().split(' ') # Remove leading/trailing spaces from MAC
|
||||
@@ -86,6 +86,26 @@ def main():
|
||||
else:
|
||||
mylog('verbose', [f'[SNMPDSC] ipStr does not seem to contain a valid IP:', ipStr])
|
||||
|
||||
|
||||
elif line.startswith('ipNetToMediaPhysAddress'):
|
||||
# Format: snmpwalk -OXsq output
|
||||
parts = line.split()
|
||||
if len(parts) == 2:
|
||||
|
||||
ipAddress = parts[0].split('[')[-1][:-1]
|
||||
macAddress = normalize_mac(parts[1])
|
||||
|
||||
mylog('verbose', [f'[SNMPDSC] IP: {ipAddress} MAC: {macAddress}'])
|
||||
|
||||
plugin_objects.add_object(
|
||||
primaryId = handleEmpty(macAddress),
|
||||
secondaryId = handleEmpty(ipAddress.strip()),
|
||||
watched1 = '(unknown)',
|
||||
watched2 = handleEmpty(snmpwalkArgs[6]),
|
||||
extra = handleEmpty(line),
|
||||
foreignKey = handleEmpty(macAddress)
|
||||
)
|
||||
|
||||
mylog('verbose', ['[SNMPDSC] Entries found: ', len(plugin_objects)])
|
||||
|
||||
plugin_objects.write_result_file()
|
||||
|
||||
@@ -39,7 +39,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
@@ -74,7 +79,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
|
||||
"default_value": "*/5 * * * *",
|
||||
"options": [],
|
||||
@@ -102,7 +112,12 @@
|
||||
},
|
||||
{
|
||||
"function": "api_token",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -122,7 +137,12 @@
|
||||
},
|
||||
{
|
||||
"function": "encryption_key",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -142,7 +162,12 @@
|
||||
},
|
||||
{
|
||||
"function": "hub_url",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
@@ -163,7 +188,12 @@
|
||||
},
|
||||
{
|
||||
"function": "node_name",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
@@ -183,7 +213,16 @@
|
||||
},
|
||||
{
|
||||
"function": "devices",
|
||||
"type": "boolean",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -202,7 +241,16 @@
|
||||
},
|
||||
{
|
||||
"function": "plugins",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": [],
|
||||
"options": ["{value}"],
|
||||
@@ -229,7 +277,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/sync/sync.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -264,7 +321,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 30,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -376,14 +442,6 @@
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Vendor"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Proveedor"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Hersteller"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -28,7 +28,16 @@
|
||||
"settings": [
|
||||
{
|
||||
"function": "shown_cards",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": [
|
||||
"my_devices",
|
||||
@@ -64,7 +73,16 @@
|
||||
},
|
||||
{
|
||||
"function": "hide_empty",
|
||||
"type": "boolean",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -25,3 +25,6 @@ Allowing Un-Discoverable devices like hubs, switches or APs to be added to the n
|
||||
### Known Limitations
|
||||
- Un-Discoverable Devices always show as offline. That is expected as they can not be discovered by NetAlertX.
|
||||
- All IPs are set to 0.0.0.0 therefore the "Random MAC" icon might show up.
|
||||
|
||||
Made with ❤ by [@Data-Monkey](https://github.com/Data-Monkey) 🙏
|
||||
|
||||
|
||||
@@ -60,7 +60,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -95,7 +100,12 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/undiscoverables/script.py devices={devices}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -130,7 +140,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 10,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -165,7 +184,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": [],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -200,7 +228,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": [],
|
||||
"options": [
|
||||
"new",
|
||||
@@ -240,7 +277,63 @@
|
||||
},
|
||||
{
|
||||
"function": "devices_to_import",
|
||||
"type": "list",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{ "placeholder": "Enter value" },
|
||||
{ "suffix": "_in" },
|
||||
{ "cssClasses": "col-sm-10" },
|
||||
{ "prefillValue": "null" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": ["_in"] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-12" },
|
||||
{ "onClick": "addList(this, false)" },
|
||||
{ "getStringKey": "Gen_Add" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeAllOptions(this)" },
|
||||
{ "getStringKey": "Gen_Remove_All" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeFromList(this)" },
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["dummy_router"],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -275,7 +368,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "*/5 * * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"show_ui": true,
|
||||
"unique_prefix": "UNFIMP",
|
||||
"plugin_type": "device_scanner",
|
||||
"execution_order" : "Layer_1",
|
||||
"data_source": "script",
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"display_name": [
|
||||
@@ -483,7 +484,12 @@
|
||||
"always_after_scan",
|
||||
"on_new_device"
|
||||
],
|
||||
"type": "text.select"
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": "python3 /app/front/plugins/unifi_import/script.py username={username} password={password} host={host} sites={sites} port={port} verifyssl={verifyssl} version={version} fullimport={fullimport}",
|
||||
@@ -518,7 +524,12 @@
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"type": "text"
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": "",
|
||||
@@ -545,7 +556,12 @@
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"type": "text"
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": "",
|
||||
@@ -572,7 +588,16 @@
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"type": "password"
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "password" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": "192.168.1.1",
|
||||
@@ -599,7 +624,12 @@
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"type": "text"
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": "8443",
|
||||
@@ -626,7 +656,12 @@
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"type": "text"
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": "false",
|
||||
@@ -653,11 +688,21 @@
|
||||
}
|
||||
],
|
||||
"options": ["true", "false"],
|
||||
"type": "text.select"
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "version",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "v4",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -707,7 +752,63 @@
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"type": "list"
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{ "placeholder": "Enter value" },
|
||||
{ "suffix": "_in" },
|
||||
{ "cssClasses": "col-sm-10" },
|
||||
{ "prefillValue": "null" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": ["_in"] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-12" },
|
||||
{ "onClick": "addList(this, false)" },
|
||||
{ "getStringKey": "Gen_Add" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeAllOptions(this)" },
|
||||
{ "getStringKey": "Gen_Remove_All" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeFromList(this)" },
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": "0 2 * * *",
|
||||
@@ -734,7 +835,12 @@
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"type": "text"
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": 5,
|
||||
@@ -769,7 +875,16 @@
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"type": "integer"
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": ["Watched_Value1", "Watched_Value4"],
|
||||
@@ -801,7 +916,16 @@
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
],
|
||||
"type": "text.multiselect"
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": ["new", "watched-changed"],
|
||||
@@ -833,7 +957,16 @@
|
||||
"watched-not-changed",
|
||||
"missing-in-last-scan"
|
||||
],
|
||||
"type": "text.multiselect"
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": "disabled",
|
||||
@@ -868,7 +1001,12 @@
|
||||
}
|
||||
],
|
||||
"options": ["disabled", "once", "always"],
|
||||
"type": "text.select"
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -41,7 +41,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "schedule",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan"],
|
||||
"localized": ["name", "description"],
|
||||
@@ -72,7 +77,16 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/vendor_update/script.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -107,7 +121,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "0 4 * * 3",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -142,7 +161,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 600,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -177,7 +205,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -213,7 +250,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new", "watched-changed"],
|
||||
"options": [
|
||||
"new",
|
||||
|
||||
@@ -344,7 +344,12 @@
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": "text.select",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
@@ -377,7 +382,12 @@
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/website_monitor/script.py urls={urls}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -404,7 +414,12 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "0 2 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -431,7 +446,12 @@
|
||||
},
|
||||
{
|
||||
"function": "API_SQL",
|
||||
"type": "text",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "SELECT * FROM plugin_website_monitor",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -458,7 +478,16 @@
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 5,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -489,7 +518,16 @@
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
@@ -521,7 +559,16 @@
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["new", "watched-changed"],
|
||||
"options": [
|
||||
"new",
|
||||
@@ -553,7 +600,63 @@
|
||||
},
|
||||
{
|
||||
"function": "urls_to_check",
|
||||
"type": "list",
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [
|
||||
{ "placeholder": "Enter value" },
|
||||
{ "suffix": "_in" },
|
||||
{ "cssClasses": "col-sm-10" },
|
||||
{ "prefillValue": "null" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": ["_in"] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-12" },
|
||||
{ "onClick": "addList(this, false)" },
|
||||
{ "getStringKey": "Gen_Add" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeAllOptions(this)" },
|
||||
{ "getStringKey": "Gen_Remove_All" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-xs-6" },
|
||||
{ "onClick": "removeFromList(this)" },
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["https://google.com", "https://duck.com"],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
@@ -580,7 +683,16 @@
|
||||
},
|
||||
{
|
||||
"function": "SQL_internet_ip",
|
||||
"type": "readonly",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet'",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
@@ -30,7 +30,16 @@
|
||||
"settings": [
|
||||
{
|
||||
"function": "AppEvents_hist",
|
||||
"type": "integer",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 5000,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user