diff --git a/.env.omada.ffsb42 b/.env.omada.ffsb42
deleted file mode 120000
index 81e55650..00000000
--- a/.env.omada.ffsb42
+++ /dev/null
@@ -1 +0,0 @@
-../.env.omada.ffsb42
\ No newline at end of file
diff --git a/docker-compose.yml.ffsb42 b/docker-compose.yml.ffsb42
deleted file mode 120000
index 115af5fa..00000000
--- a/docker-compose.yml.ffsb42
+++ /dev/null
@@ -1 +0,0 @@
-../docker-compose.yml.ffsb42
\ No newline at end of file
diff --git a/docs/DEBUG_TIPS.md b/docs/DEBUG_TIPS.md
index 7c180037..dbb345ea 100755
--- a/docs/DEBUG_TIPS.md
+++ b/docs/DEBUG_TIPS.md
@@ -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 🔁
diff --git a/front/maintenance.php b/front/maintenance.php
index 813802d9..bc34f42e 100755
--- a/front/maintenance.php
+++ b/front/maintenance.php
@@ -706,9 +706,9 @@ function ImportPastedCSV()
var csv = $('#modal-input-textarea').val();
csvBase64 = btoa(csv)
// Execute
- $.get('php/server/devices.php?action=ImportCSV&content=', function(msg) {
- showMessage (msg);
- write_notification(`[Maintenance] Devices imported from pasted content`, 'info')
+ $.post('php/server/devices.php?action=ImportCSV', { content: csvBase64 }, function(msg) {
+ showMessage(msg);
+ write_notification(`[Maintenance] Devices imported from pasted content`, 'info');
});
}
diff --git a/front/php/server/devices.php b/front/php/server/devices.php
index 2219bc9b..64a6efd8 100755
--- a/front/php/server/devices.php
+++ b/front/php/server/devices.php
@@ -464,20 +464,19 @@ function ExportCSV() {
//------------------------------------------------------------------------------
function ImportCSV() {
+ global $db;
$file = '../../../config/devices.csv';
$data = "";
+ $skipped = "";
+ $error = "";
// check if content passed in query string
- if(isset ($_REQUEST['content']) && !empty ($_REQUEST['content']))
+ if(isset ($_POST['content']) && !empty ($_POST['content']))
{
-
// Decode the Base64 string
- $data = base64_decode($_REQUEST['content']);
+ $data = base64_decode($_POST['content']);
} else if (file_exists($file)) { // try to get the data form the file
- global $db;
- $skipped = "";
- $error = "";
// Read the CSV file
$data = file_get_contents($file);
diff --git a/front/php/templates/language/fr_fr.json b/front/php/templates/language/fr_fr.json
old mode 100644
new mode 100755
diff --git a/front/plugins/omada_sdn_imp/config.json b/front/plugins/omada_sdn_imp/config.json
index 531ba07f..3aff59b6 100755
--- a/front/plugins/omada_sdn_imp/config.json
+++ b/front/plugins/omada_sdn_imp/config.json
@@ -254,7 +254,7 @@
"description": [
{
"language_code": "en_us",
- "string": "Omada SDN instance password"
+ "string": "Omada SDN instance password."
}
]
},
@@ -282,7 +282,7 @@
"description": [
{
"language_code": "en_us",
- "string": "The plugin synchronizes names from NetAlertX to OMADA Clietnts. 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."
+ "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."
}
]
},
diff --git a/front/plugins/omada_sdn_imp/config.json.v6 b/front/plugins/omada_sdn_imp/config.json.v6
deleted file mode 100755
index f9648365..00000000
--- a/front/plugins/omada_sdn_imp/config.json.v6
+++ /dev/null
@@ -1,690 +0,0 @@
-{
- "code_name": "omada_sdn_imp",
- "unique_prefix": "OMDSDN",
- "plugin_type": "device_scanner",
- "enabled": true,
- "data_source": "script",
- "mapped_to_table": "CurrentScan",
- "data_filters": [
- {
- "compare_column": "Object_PrimaryID",
- "compare_operator": "==",
- "compare_field_id": "txtMacFilter",
- "compare_js_template": "'{value}'.toString()",
- "compare_use_quotes": true
- }
- ],
- "show_ui": true,
- "localized": ["display_name", "description", "icon"],
- "display_name": [
- {
- "language_code": "en_us",
- "string": "OMADA SDN import"
- }
- ],
- "description": [
- {
- "language_code": "en_us",
- "string": "Plugin to import data from OMADA SDN."
- }
- ],
- "icon": [
- {
- "language_code": "en_us",
- "string": ""
- }
- ],
- "params": [],
- "settings": [
- {
- "function": "RUN",
- "events": ["run"],
- "type": {
- "dataType": "string",
- "elements": [
- { "elementType": "select", "elementOptions": [], "transformers": [] }
- ]
- },
-
- "default_value": "disabled",
- "options": ["disabled", "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 scan should run. Good options are: schedule"
- }
- ]
- },
- {
- "function": "RUN_SCHD",
- "type": {
- "dataType": "string",
- "elements": [
- { "elementType": "input", "elementOptions": [], "transformers": [] }
- ]
- },
-
- "default_value": "*/5 * * * *",
- "options": [],
- "localized": ["name", "description"],
- "name": [
- {
- "language_code": "en_us",
- "string": "Schedule"
- }
- ],
- "description": [
- {
- "language_code": "en_us",
- "string": "Only enabled if you select schedule in the SYNC_RUN setting. Make sure you enter the schedule in the correct cron-like format (e.g. validate at crontab.guru). For example entering 0 4 * * * will run the scan after 4 am in the TIMEZONE you set above. Will be run NEXT time the time passes."
- },
- {
- "language_code": "es_es",
- "string": "Solo está habilitado si selecciona schedule en la configuración SYNC_RUN. Asegúrese de ingresar la programación en el formato similar a cron correcto (por ejemplo, valide en crontab.guru). Por ejemplo, ingresar 0 4 * * * ejecutará el escaneo después de las 4 a.m. en el TIMEZONE código> que configuró arriba. Se ejecutará la PRÓXIMA vez que pase el tiempo."
- },
- {
- "language_code": "de_de",
- "string": "Nur aktiviert, wenn Sie schedule in der SYNC_RUN-Einstellung auswählen. Stellen Sie sicher, dass Sie den Zeitplan im richtigen Cron-ähnlichen Format eingeben (z. B. validieren unter crontab.guru). Wenn Sie beispielsweise 0 4 * * * eingeben, wird der Scan nach 4 Uhr morgens in der TIMEZONE ausgeführt. Code> den Sie oben festgelegt haben. Wird das NÄCHSTE Mal ausgeführt, wenn die Zeit vergeht."
- }
- ]
- },
- {
- "function": "url",
- "type": {
- "dataType": "string",
- "elements": [
- { "elementType": "input", "elementOptions": [], "transformers": [] }
- ]
- },
- "maxLength": 50,
- "default_value": "",
- "options": [],
- "localized": ["name", "description"],
- "name": [
- {
- "language_code": "en_us",
- "string": "URL"
- }
- ],
- "description": [
- {
- "language_code": "en_us",
- "string": "Enter full URL with protocol https://CHANGEME_omada.mylocaldomain."
- }
- ]
- },
- {
- "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 sites"
- }
- ],
- "description": [
- {
- "language_code": "en_us",
- "string": "Omada SDN site IDs. You can get it by..."
- }
- ]
- },
- {
- "function": "username",
- "type": {
- "dataType": "string",
- "elements": [
- { "elementType": "input", "elementOptions": [], "transformers": [] }
- ]
- },
- "maxLength": 50,
- "default_value": "",
- "options": [],
- "localized": ["name", "description"],
- "name": [
- {
- "language_code": "en_us",
- "string": "User name"
- }
- ],
- "description": [
- {
- "language_code": "en_us",
- "string": "Omada SDN instance user name."
- }
- ]
- },
- {
- "function": "password",
- "type": {
- "dataType": "string",
- "elements": [
- {
- "elementType": "input",
- "elementOptions": [{ "type": "password" }],
- "transformers": []
- }
- ]
- },
- "maxLength": 50,
- "default_value": "",
- "options": [],
- "localized": ["name", "description"],
- "name": [
- {
- "language_code": "en_us",
- "string": "Password"
- }
- ],
- "description": [
- {
- "language_code": "en_us",
- "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. 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": {
- "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"],
- "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_TIMEOUT",
- "type": {
- "dataType": "integer",
- "elements": [
- {
- "elementType": "input",
- "elementOptions": [{ "type": "number" }],
- "transformers": []
- }
- ]
- },
- "default_value": 30,
- "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."
- }
- ]
- },
- {
- "default_value": [],
- "description": [
- {
- "language_code": "en_us",
- "string": "Send a notification if selected values change. Use CTRL + Click to select/deselect.
Watched_Value1 is Hostname Watched_Value2 is Parent Node Watched_Value3 is Port Watched_Value4 is SSID
"
- }
- ],
- "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. new means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. watched-changed means that selected Watched_ValueN 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": [
- {
- "column": "Object_PrimaryID",
- "mapped_to_column": "cur_MAC",
- "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"
- },
- {
- "language_code": "de_de",
- "string": "MAC"
- }
- ]
- },
- {
- "column": "Object_SecondaryID",
- "mapped_to_column": "cur_IP",
- "css_classes": "col-sm-2",
- "show": true,
- "type": "device_ip",
- "default_value": "",
- "options": [],
- "localized": ["name"],
- "name": [
- {
- "language_code": "en_us",
- "string": "IP"
- },
- {
- "language_code": "es_es",
- "string": "IP"
- },
- {
- "language_code": "de_de",
- "string": "IP"
- }
- ]
- },
- {
- "column": "Watched_Value1",
- "mapped_to_column": "cur_Name",
- "css_classes": "col-sm-2",
- "show": true,
- "type": "label",
- "default_value": "",
- "options": [],
- "localized": ["name"],
- "name": [
- {
- "language_code": "en_us",
- "string": "Name"
- }
- ]
- },
- {
- "column": "Watched_Value2",
- "mapped_to_column": "cur_NetworkNodeMAC",
- "css_classes": "col-sm-2",
- "show": true,
- "type": "label",
- "default_value": "",
- "options": [],
- "localized": ["name"],
- "name": [
- {
- "language_code": "en_us",
- "string": "Parent Network MAC"
- }
- ]
- },
- {
- "column": "Watched_Value3",
- "mapped_to_column": "cur_PORT",
- "css_classes": "col-sm-2",
- "show": true,
- "type": "label",
- "default_value": "",
- "options": [],
- "localized": ["name"],
- "name": [
- {
- "language_code": "en_us",
- "string": "Port"
- }
- ]
- },
- {
- "column": "Watched_Value4",
- "mapped_to_column": "cur_SSID",
- "css_classes": "col-sm-2",
- "show": true,
- "type": "label",
- "default_value": "",
- "options": [],
- "localized": ["name"],
- "name": [
- {
- "language_code": "en_us",
- "string": "SSID"
- }
- ]
- },
- {
- "column": "Extra",
- "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": "Site or Vendor"
- }
- ]
- },
- {
- "column": "Dummy",
- "mapped_to_column": "cur_ScanMethod",
- "mapped_to_column_data": {
- "value": "OMDSDN"
- },
- "css_classes": "col-sm-2",
- "show": true,
- "type": "label",
- "default_value": "",
- "options": [],
- "localized": ["name"],
- "name": [
- {
- "language_code": "en_us",
- "string": "Scan method"
- },
- {
- "language_code": "es_es",
- "string": "Método de escaneo"
- },
- {
- "language_code": "de_de",
- "string": "Scanmethode"
- }
- ]
- },
- {
- "column": "DateTimeCreated",
- "css_classes": "col-sm-2",
- "show": true,
- "type": "label",
- "default_value": "",
- "options": [],
- "localized": ["name"],
- "name": [
- {
- "language_code": "en_us",
- "string": "Created"
- },
- {
- "language_code": "es_es",
- "string": "Creado"
- },
- {
- "language_code": "de_de",
- "string": "Erstellt"
- }
- ]
- },
- {
- "column": "DateTimeChanged",
- "css_classes": "col-sm-2",
- "show": true,
- "type": "label",
- "default_value": "",
- "options": [],
- "localized": ["name"],
- "name": [
- {
- "language_code": "en_us",
- "string": "Changed"
- },
- {
- "language_code": "es_es",
- "string": "Cambiado"
- },
- {
- "language_code": "de_de",
- "string": "Geändert"
- }
- ]
- },
- {
- "column": "Status",
- "css_classes": "col-sm-1",
- "show": true,
- "type": "replace",
- "default_value": "",
- "options": [
- {
- "equals": "watched-not-changed",
- "replacement": ""
- },
- {
- "equals": "watched-changed",
- "replacement": "
"
- },
- {
- "equals": "new",
- "replacement": "
"
- },
- {
- "equals": "missing-in-last-scan",
- "replacement": "
"
- }
- ],
- "localized": ["name"],
- "name": [
- {
- "language_code": "en_us",
- "string": "Status"
- },
- {
- "language_code": "es_es",
- "string": "Estado"
- },
- {
- "language_code": "de_de",
- "string": "Status"
- }
- ]
- }
- ]
-}
diff --git a/front/plugins/omada_sdn_imp/omada_account_sample.png b/front/plugins/omada_sdn_imp/omada_account_sample.png
old mode 100644
new mode 100755
diff --git a/front/plugins/omada_sdn_imp/omada_sdn.py.0.3 b/front/plugins/omada_sdn_imp/omada_sdn.py.0.3
deleted file mode 100755
index 2adb2972..00000000
--- a/front/plugins/omada_sdn_imp/omada_sdn.py.0.3
+++ /dev/null
@@ -1,498 +0,0 @@
-#!/usr/bin/env python
-"""
-Omada SDN Query Script
-
-This script queries the OMADA SDN to populate NetAlertX with Omada switches, access points, and clients.
-It attempts to identify and populate their connections by switch/access points and ports/SSID,
-and tries to differentiate root bridges from accessories.
-
-Author: ffsb
-Version: 0.2 - Added logic to retry Omada API call once as it sometimes fails, and improved error handling.
-"""
-__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" # adding parallelism
-
-#
-# 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
-from queue import Queue
-import multiprocessing
-from multiprocessing import Pool, Manager
-import os
-
-# 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
-
-# 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 = 'OMDSDN'
-#
-# sample target output:
-# 0 MAC, 1 IP, 2 Name, 3 switch/AP, 4 port/SSID, 5 TYPE
-#17:27:10 [
] token: "['9C-04-A0-82-67-45', '192.168.0.217', '9C-04-A0-82-67-45', '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 ompapaoffice 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 [] token: "['9C-04-A0-82-67-45', '192.168.0.217', '9C-04-A0-82-67-45', 'froggies2', '(ompapaoffice)']"
-#17:27:10 [] token: "['50-02-91-29-E7-53', '192.168.0.153', 'frontyard_ESP_29E753', 'pantry12', '(48)']"
-#17:27:10 [] token: "['00-E2-59-00-A0-8E', '192.168.0.1', 'bastion', 'office24', '(23)']"
-#17:27:10 [] token: "['60-DD-8E-CA-A4-B3', '192.168.0.226', 'brick', 'froggies3', '(ompapaoffice)']"
-cMAC, cIP, cNAME, cSWITCH_AP, cPORT_SSID = range(5)
-
-OMDLOGLEVEL = 'verbose'
-
-def ieee2ietf_mac_formater(inputmac):
- """Translate MAC address from standard IEEE model to IETF draft."""
- return inputmac.lower().replace('-', ':')
-
-def ietf2ieee_mac_formater(inputmac):
- """Translate MAC address from IETF draft to standard IEEE model."""
- return inputmac.upper().replace(':', '-')
-
-def get_mac_from_IP(target_IP):
- """Get MAC address from IP using ARP."""
- 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
-
-def callomada(myargs):
- """Wrapper to call the Omada python library's own wrapper."""
- arguments = " ".join(myargs)
- mylog('verbose', [f'[{pluginName}] callomada START:{arguments}'])
- from tplink_omada_client.cli import main as omada
- from contextlib import redirect_stdout
-
- omada_output = ''
- retries = 2
- while omada_output == '' and retries > 0:
- retries -= 1
- try:
- mf = io.StringIO()
- with redirect_stdout(mf):
- omada(myargs)
- omada_output = mf.getvalue()
- except Exception as e:
- mylog('minimal', [f'[{pluginName}] ERROR WHILE CALLING callomada:{arguments}\n {e}'])
- omada_output = ''
- mylog('verbose', [f'[{pluginName}] callomada END:{arguments}'])
- return omada_output
-
-def extract_mac_addresses(text):
- """Extract all the MAC addresses from multiline 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})"
- return re.findall(mac_pattern, text)
-
-def find_default_gateway_ip():
- """Find the default gateway IP address."""
- from scapy.all import conf, Route
- default_route = conf.route.route("0.0.0.0")
- return default_route[2] if default_route[2] else None
-
-def add_uplink(uplink_mac, switch_mac, device_data_bymac, sadevices_linksbymac, port_byswitchmac_byclientmac):
- """Add uplink information to switches recursively."""
- 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]}"'])
- mylog(OMDLOGLEVEL, [f'[{pluginName}] this are the port_byswitchmac:"{port_byswitchmac_byclientmac[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]
- 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)
-
-def main():
- """Main function to execute the script."""
- start_time = time.time()
- mylog('verbose', [f'[{pluginName}] starting execution'])
-
- from database import DB
- from device import Device_obj
-
- db = DB()
- db.open()
- device_handler = Device_obj(db)
-
- # Retrieve configuration settings
- 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')
-
- # Login to Omada
- 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}'])
-
- # Get clients and devices
- 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}'])
-
- # Process data
- device_data = get_device_data(clients_list, switches_and_aps, device_handler)
-
- mylog('verbose', [f'[{pluginName}] New entries to create: "{len(device_data)}"'])
- if len(device_data) > 0:
- 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'
- plugin_objects.add_object(
- primaryId = ieee2ietf_mac_formater(device[MAC]),
- secondaryId = device[IP],
- watched1 = device[NAME] if device[NAME] != 'null' else '',
- watched2 = ParentNetworkNode,
- watched3 = myport,
- watched4 = myssid,
- extra = device[TYPE] if device[TYPE] != 'null' else '',
- foreignKey = ieee2ietf_mac_formater(device[MAC])
- )
- mylog(OMDLOGLEVEL, [f'[{pluginName}] New entries: "{len(device_data)}"'])
-
- # Write results
- plugin_objects.write_result_file()
-
- end_time = time.time()
- mylog('verbose', [f'[{pluginName}] execution completed in {end_time - start_time:.2f} seconds'])
-
- return 0
-'''
-# version 0.3b
-def get_omada_devices_details(sadevice_data,switch_details,switch_dumps):
- """Get device details from Omada. saved into a dictionary of strings"""
- mylog(OMDLOGLEVEL, [f'[{pluginName}]getting the omada devices details: "{sadevice_data}"'])
- thisswitch = sadevice_data[dMAC]
- if sadevice_data[dTYPE] == 'ap':
- switch_details[thisswitch] = callomada(['access-point', thisswitch])
- elif sadevice_data[dTYPE] == 'switch':
- switch_details[thisswitch] = callomada(['switch', thisswitch])
- switch_dumps[thisswitch] = callomada(['-t','myomada','switch','-d',thisswitch])
- else:
- switch_details[thisswitch] = 'null'
- switch_dumps[thisswitch] = 'null'
- return
-'''
-'''
-# version 0.3c
-def get_omada_devices_details(sadevice_data):
- mthisswitch = sadevice_data[dMAC]
- mswitch_detail = ''
- mswitch_dump = ''
- if sadevice_data[dTYPE] == 'ap':
- mswitch_detail = callomada(['access-point', mthisswitch])
- elif sadevice_data[dTYPE] == 'switch':
- mswitch_detail = callomada(['switch', mthisswitch])
- mswitch_dump = callomada(['-t','myomada','switch','-d',mthisswitch])
- else:
- mswitch_detail = 'null'
- nswitch_dump = 'null'
- return mthisswitch, mswitch_detail, mswitch_dump
-'''
-
-def get_omada_devices_details(sadevice_data):
- thisswitch = sadevice_data[dMAC]
- try:
- if sadevice_data[dTYPE] == 'ap':
- switch_detail = callomada(['access-point', thisswitch])
- return thisswitch, switch_detail, None
- elif sadevice_data[dTYPE] == 'switch':
- switch_detail = callomada(['switch', thisswitch])
- switch_dump = callomada(['-t','myomada','switch','-d',thisswitch])
- return thisswitch, switch_detail, switch_dump
- else:
- return thisswitch, 'null', 'null'
- except Exception as e:
- mylog('error', [f'[{pluginName}] Error processing {thisswitch}: {str(e)}'])
- return thisswitch, 'error', 'error'
-
-
-
-def get_device_data(omada_clients_output, switches_and_aps, device_handler):
- """Process and return device data from Omada output."""
- """
- switch_dumps = {}
- switch_details = {}
- 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')
- """
- manager = Manager()
- switch_dumps = manager.dict()
- switch_details = manager.dict()
- sadevices_macbyname = manager.dict()
- sadevices_macbymac = manager.dict()
- sadevices_linksbymac = manager.dict()
- port_byswitchmac_byclientmac = manager.dict()
- device_data_bymac = manager.dict()
- device_data_mac_byip = manager.dict()
- omada_force_overwrite = get_setting_value('OMDSDN_force_overwrite')
-
-
- sadevices = switches_and_aps.splitlines()
- mylog(OMDLOGLEVEL, [f'[{pluginName}] switches_and_aps rows: "{len(sadevices)}"'])
- '''
- for sadevice in sadevices:
- sadevice_data = sadevice.split()
- get_omada_devices_details(sadevice_data,switch_details,switch_dumps)
- '''
-
- '''
- # Create a ThreadPoolExecutor
- # version 0.3b
- with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
- # Submit tasks for each device
- futures = []
- for sadevice in sadevices:
- sadevice_data = sadevice.split()
- future = executor.submit(get_omada_devices_details, sadevice_data, switch_details, switch_dumps)
- futures.append(future)
-
- # Wait for all tasks to complete
- concurrent.futures.wait(futures)
- '''
- '''
- # version 0.3c
- # Create a ThreadPoolExecutor
- with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
- # Submit tasks for each device
- future_to_device = {executor.submit(get_omada_devices_details, sadevice.split()): sadevice for sadevice in sadevices}
-
- # Process results as they complete
- for future in concurrent.futures.as_completed(future_to_device):
- csadevice = future_to_device[future]
- try:
- mylog('verbose', [f'[{pluginName}] processing results of: {csadevice}'])
- cthisswitch, cswitch_detail, cswitch_dump = future.result()
- switch_details[cthisswitch] = cswitch_detail
- switch_dumps[cthisswitch] = cswitch_dump
- except Exception as exc:
- mylog('error', [f'[{pluginName}] {csadevice} generated an exception: {exc}'])
- '''
- # Use multiprocessing Pool
- with Pool(processes=3) as pool:
- results = pool.map(get_omada_devices_details, [sadevice.split() for sadevice in sadevices])
-
-
-
- mylog(OMDLOGLEVEL, [f'[{pluginName}] All API calls completed. Processing results...'])
-
- # Process results
- for thisswitch, switch_detail, switch_dump in results:
- switch_details[thisswitch] = switch_detail
- if switch_dump is not None:
- switch_dumps[thisswitch] = switch_dump
-
- mylog(OMDLOGLEVEL, [f'[{pluginName}] Finished collecting device details. Processing data...'])
-
-
-
- # Now process the collected data
-
-
- 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]
- 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)
- port_byswitchmac_byclientmac[thisswitch][link] = myport[0]
- 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
- # ...
- """ MAC = 0
- IP = 1
- NAME = 2
- SWITCH_AP = 3
- PORT_SSID = 4
- TYPE = 5 """
-
- # sample target output:
- # 0 MAC, 1 IP, 2 Name, 3 MAC of switch/AP, 4 port/SSID, 5 TYPE
- #17:27:10 [] token: "['9C-04-A0-82-67-45', '192.168.0.217', 'brick', 'ompapaoffice','froggies2', , 'Switch']"
-
- 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()
diff --git a/front/plugins/omada_sdn_imp/testre.py b/front/plugins/omada_sdn_imp/testre.py
deleted file mode 100644
index 544e7858..00000000
--- a/front/plugins/omada_sdn_imp/testre.py
+++ /dev/null
@@ -1,195 +0,0 @@
-import re
-
-""""
-how to rebuild and re-run...
-
-savefolder=~/naxdev/NetAlertX.v7
-cd ~/naxdev
-mv NetAlertX $savefolder
-gh repo clone FlyingToto/NetAlertX
-cd NetAlertX
-ln -s ../docker-compose.yml.ffsb42 .
-ln -s ../.env.omada.ffsb42 .
-cd front/plugins/omada_sdn_imp/
-cp -p $savefoder/front/plugins/omada_sdn_imp/omada_sdn.py* .
-cp -p $savefoder/front/plugins/omada_sdn_imp/README.md .
-cp -p $savefoder/front/plugins/omada_sdn_imp/omada_account_sample.png .
-cp -p $savefoder/front/plugins/omada_sdn_imp/testre.py .
-#cp -p $savefoder/front/plugins/omada_sdn_imp/config.json config.json.v6
-cd ~/naxdev/NetAlertX
-sudo docker-compose --env-file .env.omada.ffsb42 -f ./docker-compose.yml.ffsb42 up
-
-to gather data for Boris:
-today=$(date +%Y_%m_%d__%H_%M)
-mkdir /drives/c/temp/4boris/$today
-cd /drives/c/temp/4boris/$today
-scp hal:~/naxdev/logs/app.log .
-scp hal:~/naxdev/NetAlertX/front/plugins/omada_sdn_imp/* .
-gzip -c app.log > app_$today.log.gz
-
-
-scp hal:~/naxdev/NetAlertX/front/plugins/omada_sdn_imp/omada_sdn.py /drives/c/temp/4boris/
-"""
-
-
-
-
-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_pattern = r'([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})'
- #r"(([0-9A-F]{2}-){5}[0-9A-F]{2})"
- #r"([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})"
- #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]
-
-# Example usage:
-foo = """
-Name: office
-Address: 0C-80-63-69-C4-D1 (192.168.0.5)
-Status: CONNECTED (CONNECTED)
-Ports: 28
-Supports PoE: False
-Model: T1600G-28TS v3.0
-LED Setting: SITE_SETTINGS
-Uptime: 5day(s) 22h 39m 6s
-Uplink switch: D8-07-B6-71-FF-7F office24
-Downlink devices:
-- 40-AE-30-A5-A7-50 ompapaoffice
-- B0-95-75-46-0C-39 pantry12
-"""
-
-mac_list = extract_mac_addresses(foo)
-print("mac list",mac_list)
-# ['0C-80-63-69-C4-D1', 'D8-07-B6-71-FF-7F', '40-AE-30-A5-A7-50', 'B0-95-75-46-0C-39']
-# ['C4-:D1', 'FF-:7F', 'A7-:50', '0C-:39']
-
-linked_switches_and_ports_by_mac = {}
-
-
-foo = """"
-something
-some BOB12
-blah BOB23
---- BEGIN ---
-something else BOB12
-blah BOB23
---- END ---
-"""
-def extract_BOB_patterns(foo):
- pattern = r"BOB\d{2}(?=.*BEGIN)"
- matches = re.findall(pattern, foo, re.DOTALL)
- return matches
-
-BOBresult = extract_BOB_patterns(foo)
-print("BOB:",BOBresult) # Output: ['BOB12', 'BOB23']
-
-
-#0C-80-63-69-C4-D1
-clientmac_by_switchmac_by_switchportSSID = {}
-switch_mac_and_ports_by_clientmac = {}
-
-def extract_uplinks_mac_and_ports(tplink_device_dump):
- mac_switches = []
- 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})(?=.*BEGIN)"
- mac_addresses = re.findall(mac_pattern, tplink_device_dump,re.DOTALL)
- mac_switches = ["".join(parts) for parts in mac_addresses]
- print(" mac_switches1=",mac_switches)
- mymac = mac_switches[0]
- mylinks = mac_switches[1:]
- for mylink in mylinks:
- port_pattern = r"(?=\{.*\"port\"\: )([0-9]+)(?=.*"+re.escape(mylink)+r")"
- port_pattern = r"(?:{/s\"port\"\: )([0-9]+)(?:[!\}].*"+re.escape(mylink)+r")"
- #port_pattern = rf"{{.*?{found_mac}.*?port\s*:\s*(\d+).*?}}"
- #port_pattern = rf"{{.*?.*?port\s*:\s*(\d+)[!\\}]*{mylink}?}}"
- port_pattern = r"(?:\{[!\}]port/s:/s)([0-9]+\,)(?:[!\}]*"+re.escape(mylink)+r"[!\{]*\})"
- #port_pattern = r"(?:\{.*\"port\"\: )([0-9]+)(?=.*"+re.escape(mylink)+r")"
- port_pattern = r"(?:{[^}]*\"port\"\: )([0-9]+)(?=[^}]*"+re.escape(mylink)+r")"
-
- myport = re.findall(port_pattern, tplink_device_dump,re.DOTALL)
- print("myswitch=",mymac, "- link_switch=", mylink, "myport=", myport)
- return(0)
-
-
-'''
-with open('/tmp/switch.bigroom.dump.json', 'r') as file:
- foo3 = file_content = file.read()
-print("bigroom", end="")
-extract_uplinks_mac_and_ports(foo3)
-with open('/tmp/switch.office.dump.json', 'r') as file:
- foo4 = file_content = file.read()
-print("office", end="")
-extract_uplinks_mac_and_ports(foo4)
-'''
-
-import netifaces
-gw = netifaces.gateways()
-print(gw['default'][netifaces.AF_INET][0])
-
-
-d = {'a': ['0', 'Arthur'], 'b': ['foo', 'Belling']}
-
-print(d.items())
-print(d.keys())
-print(d.values())
-
-
-foo = 2
-#while foo > 0:
-# foo = 'toto'
-print("foo is ",foo)
-
-if foo in ( 'bar', '', 'null'):
- print("foo is bar")
-else:
- print("foo is not bar")
-
-foo='192-168-0-150.local'
-bar = foo.split('.')[0]
-print("bar=",bar,"-")
-bar2 = 'toto'
-print("bar2=",bar2,"-")
-
-
-
-import concurrent.futures
-import time
-import random
-
-def phello(arg):
- print('running phell',arg)
- delay = random.uniform(0, 6)
- time.sleep(delay)
- return f"parallel hello : {arg}", delay
-
-def testparalel():
- arguments = ["Alice", "Bob", "Charlie", "David"]
- results = {}
- results2 = {}
- para = 10
-
- # Using ThreadPoolExecutor for parallel execution
- with concurrent.futures.ThreadPoolExecutor(max_workers=para) as executor:
- # Submit tasks to the executor
- future_to_arg = {executor.submit(phello, arg): arg for arg in arguments}
-
- # Wait for all futures to complete
- done, _ = concurrent.futures.wait(future_to_arg)
-
- # Retrieve results
- for future in done:
- arg = future_to_arg[future]
- try:
- result, result2 = future.result()
- results[arg] = result
- results2[arg] = result2
- except Exception as exc:
- print(f"{arg} generated an exception: {exc}")
-
- # Print results after all threads have completed
- print("All threads completed. Results:")
- for arg, result in results.items():
- print(f"arg:{arg}, result={results[arg]}, result2={results2[arg]}")
-
-
-testparalel()
\ No newline at end of file