From fa8795588a49e14a1d9a33d8f52e2c0879abb3ee Mon Sep 17 00:00:00 2001 From: leondavi Date: Fri, 14 Jul 2023 03:05:41 +0300 Subject: [PATCH 1/2] [JSONGEN] Add ip scanner --- src_py/nerlPlanner/Definitions.py | 8 ++- src_py/nerlPlanner/Handlers.py | 10 +++ src_py/nerlPlanner/Pinger.py | 105 ++++++++++++++++++++++++++++++ src_py/nerlPlanner/main.py | 67 +++++++++++-------- 4 files changed, 162 insertions(+), 28 deletions(-) create mode 100644 src_py/nerlPlanner/Pinger.py diff --git a/src_py/nerlPlanner/Definitions.py b/src_py/nerlPlanner/Definitions.py index 0f87b898..d62c4223 100644 --- a/src_py/nerlPlanner/Definitions.py +++ b/src_py/nerlPlanner/Definitions.py @@ -31,4 +31,10 @@ KEY_WORKERS_BUTTON_VIEW = '-KEY-WORKERS-BUTTON-VIEW-' KEY_WORKERS_BUTTON_REMOVE = '-KEY-WORKERS-BUTTON-REMOVE-' KEY_WORKERS_LIST_BOX = '-KEY-WORKERS-LIST-BOX-' -KEY_WORKERS_INFO_BAR = '-KEY-WORKERS-INFO-BAR-' \ No newline at end of file +KEY_WORKERS_INFO_BAR = '-KEY-WORKERS-INFO-BAR-' + +KEY_DEVICES_SCANNER_BUTTON = '-KEY-DEVICES-SCANNER-BUTTON-' +KEY_DEVICES_ONLINE_LIST_COMBO_BOX = '-KEY-DEVICES-ONLINE-LIST-COMBO-BOX-' +KEY_DEVICES_SCANNER_INPUT_LAN_MASK = '-KEY-DEVICES-SCANNER-INPUT-LAN-MASK-' +KEY_DEVICES_IP_INPUT = '-KEY-DEVICES-IP-INPUT-' +KEY_DEVICES_NAME_INPUT = '-KEY-DEVICES-NAME-' \ No newline at end of file diff --git a/src_py/nerlPlanner/Handlers.py b/src_py/nerlPlanner/Handlers.py index d85c7e2b..a26357f4 100644 --- a/src_py/nerlPlanner/Handlers.py +++ b/src_py/nerlPlanner/Handlers.py @@ -25,6 +25,10 @@ workers_new_worker_dict = None worker_name_selection = None +# devices +device_name = None +device_ip = None + def reset_instances(): json_architecture_instance = JsonArchitecture() @@ -123,5 +127,11 @@ def workers_handler(window, event, values): sg.popup_ok(f"selection or name issue", keep_on_top=True, title="Loading Issue") +def devices_handler(window, event, values): + device_name = values[KEY_DEVICES_NAME_INPUT] + device_ip = values[KEY_DEVICES_IP_INPUT] + + + def update_current_json_file_path(jsonPath): print(jsonPath) \ No newline at end of file diff --git a/src_py/nerlPlanner/Pinger.py b/src_py/nerlPlanner/Pinger.py new file mode 100644 index 00000000..44a96ce4 --- /dev/null +++ b/src_py/nerlPlanner/Pinger.py @@ -0,0 +1,105 @@ +# Import modules +import subprocess +import ipaddress +import PySimpleGUI as sg +from Definitions import * +from JsonElements import * + +BAR_MAX = 100 +KEY_DEV_SCAN_BAR = '-KEY-DEV-SCAN-BAR-' + +def pinger(net_addr, devices_online_list, ScannerWindow, i): + devices_online_list = [] + # Prompt the user to input a network address + net_addr = '192.168.0.0/24' + # Create the network + ip_net = ipaddress.ip_network(net_addr) + + # Get all hosts on that network + all_hosts = list(ip_net.hosts()) + + + # For each IP address in the subnet, + # run the ping command with subprocess.popen interface + for i in range(len(all_hosts)): + output = subprocess.Popen(['ping', '-c','1','-W','0.5', str(all_hosts[i])], stdout=subprocess.PIPE).communicate()[0] + + if "Destination host unreachable" in output.decode('utf-8'): + pass + #print(str(all_hosts[i]), "is Offline") + elif "Request timed out" in output.decode('utf-8'): + pass + #print(str(all_hosts[i]), "is Offline") + elif "0 received, 100% packet loss" in output.decode('utf-8'): + pass + #print(str(all_hosts[i]), "is Offline") + else: + #print(str(all_hosts[i]), "is Online") + devices_online_list.append(str(all_hosts[i])) + ScannerWindow[KEY_DEV_SCAN_BAR].update((i+1)/len(all_hosts)) + return + +devices_input_lan_mask = '' +def online_scanner_handler(window, event, values, devices_online_hosts_list): + global devices_input_lan_mask + + if event == KEY_DEVICES_SCANNER_INPUT_LAN_MASK: + devices_input_lan_mask = values[KEY_DEVICES_SCANNER_INPUT_LAN_MASK] + + if event == KEY_DEVICES_SCANNER_BUTTON and '/' in devices_input_lan_mask: + dev_ip = Ipv4(devices_input_lan_mask.split('/')[0]) + if dev_ip.error(): + sg.popup_ok(f"input lan ip issue!", keep_on_top=True, title="Wrong Input") + online_devices_scanner_dialog(devices_input_lan_mask, devices_online_hosts_list) + + if devices_online_hosts_list: + window[KEY_DEVICES_ONLINE_LIST_COMBO_BOX].update(value = devices_online_hosts_list[0], values = devices_online_hosts_list) + else: + window[KEY_DEVICES_ONLINE_LIST_COMBO_BOX].update(value = 'not found') + + if event == KEY_DEVICES_ONLINE_LIST_COMBO_BOX: + window[KEY_DEVICES_IP_INPUT].update(values[KEY_DEVICES_ONLINE_LIST_COMBO_BOX]) + + +def online_devices_scanner_dialog(net_lan : str, devices_online_list : list): + host_idx = 0 + # layout the Window + scanner_layout = [[sg.Text('A custom progress meter')], + [sg.ProgressBar(BAR_MAX, orientation='h', size=(20,20), key=KEY_DEV_SCAN_BAR)], + [sg.Cancel()]] + + ScannerWindow = sg.Window(title="Worker", layout=[scanner_layout],modal=True, keep_on_top=True) + + # Create the network + ip_net = ipaddress.ip_network(net_lan) + + # Get all hosts on that network + all_hosts = list(ip_net.hosts()) + + while True: + event, values = ScannerWindow.read(timeout=10) + if event == 'Cancel' or event == sg.WIN_CLOSED: + break + + if host_idx < len(all_hosts): + output = subprocess.Popen(['ping', '-c','1','-W','0.5', str(all_hosts[host_idx])], stdout=subprocess.PIPE).communicate()[0] + + if "Destination host unreachable" in output.decode('utf-8'): + pass + #print(str(all_hosts[i]), "is Offline") + elif "Request timed out" in output.decode('utf-8'): + pass + #print(str(all_hosts[i]), "is Offline") + elif "0 received, 100% packet loss" in output.decode('utf-8'): + pass + #print(str(all_hosts[i]), "is Offline") + else: + #print(str(all_hosts[i]), "is Online") + devices_online_list.append(str(all_hosts[host_idx])) + ScannerWindow[KEY_DEV_SCAN_BAR].update(100*(host_idx+1)/len(all_hosts)) + host_idx += 1 + else: + break + + devices_online_list = list(set(devices_online_list)) + ScannerWindow.close() \ No newline at end of file diff --git a/src_py/nerlPlanner/main.py b/src_py/nerlPlanner/main.py index d7d5e6c2..2fbc9c64 100644 --- a/src_py/nerlPlanner/main.py +++ b/src_py/nerlPlanner/main.py @@ -3,10 +3,14 @@ from Definitions import * from WinWorkerDialog import WinWorkerDialog from JsonElements import * +from Pinger import * import logging sg.theme('LightGray4') +# globals +devices_online_hosts_list = ['127.0.0.1'] + # Specific Fields Frame settingsFields = [ [sg.Text('Frequency '), sg.InputText(size=10, key=KEY_SETTINGS_FREQUENCY_INPUT, enable_events=True), sg.Text('Default frequency for sensors')], [sg.Text('Batch Size'), sg.InputText(size=10, key=KEY_SETTINGS_BATCH_SIZE_INPUT, enable_events=True), sg.Text('# of samples in a message')], @@ -27,16 +31,22 @@ # Devices DevicesNamesList = [] devicesListFields = [[sg.Text("Devices List")], - [sg.Listbox(DevicesNamesList, size=(30,8))]] + [sg.Listbox(DevicesNamesList, size=(30,6))]] +devicesEntitiesList = [[sg.Text("Device Entities")], + [sg.Listbox(DevicesNamesList, size=(30,6))]] devicesListFrame = sg.Frame("", devicesListFields) -devicesFields = [[sg.Button("Add", size=(15)), sg.Button("Load",size=(15))], - [sg.Button("Ping",size=(15)), sg.Button("Remove",size=(15))], - [sg.Text("name: "), sg.InputText(size=20)], - [sg.Text("ip: "), sg.InputText(size=20)], - [sg.Text("entities:"), sg.InputText(size=(20,5))]] +devicesEntitiesListFrame = sg.Frame("", devicesEntitiesList) + +devicesFields = [[sg.Button("Add", size=(10)), sg.Button("Load",size=(10)), sg.Button("Remove",size=(10))], + [sg.Button("Scan",size=(10), key=KEY_DEVICES_SCANNER_BUTTON, enable_events=True),sg.Text("lan: "), + sg.InputText('x.x.x.x/mask',size=20, enable_events=True, key=KEY_DEVICES_SCANNER_INPUT_LAN_MASK), + sg.Combo(devices_online_hosts_list,enable_events=True, key=KEY_DEVICES_ONLINE_LIST_COMBO_BOX)], + [sg.Text("device name: "), sg.InputText(size=20, enable_events = True, key=KEY_DEVICES_NAME_INPUT)], + [sg.Text("ip address: "), sg.InputText('x.x.x.x', size=20, enable_events=True, key=KEY_DEVICES_IP_INPUT)], + [sg.InputText('selected entity', size=(15)), sg.Combo('entities', size=(15)), sg.Button("add", size=(15))]] davicesFieldsFrame = sg.Frame("",devicesFields, expand_x=True) -devicesFrame = sg.Frame("Devices",layout=[[davicesFieldsFrame],[devicesListFrame]], expand_x=True) +devicesFrame = sg.Frame("Devices",layout=[[davicesFieldsFrame],[devicesListFrame, devicesEntitiesListFrame]], expand_x=True) # Workers workersNamesList = [] @@ -59,26 +69,20 @@ workersFrame = sg.Frame("Workers",layout=[[workersFieldsFrame],[workersListFrame]], expand_x=True) -# Entities -EntitiesNamesList = [] -EntitiesListFields = [[sg.Text("Entities List")],[sg.Listbox(EntitiesNamesList, size=(25,14) )] - ] -EntitiesListFrame = sg.Frame("", EntitiesListFields) - # Clients ClientsFields = [ - [sg.Button("Add"), sg.Button("Load")], + [sg.Button("Add", size=(10)), sg.Button("Load", size=(10)), sg.Button("Remove", size=(10)) ], [sg.Text("name: "), sg.InputText(size=15)], [sg.Text("port: "), sg.InputText(size=15)], - [sg.Button("Remove")] + [sg.Button("Add Worker", size=(15)) ,sg.Button("Remove Worker", size=(15))] ] -ClientsFieldsFrame = sg.Frame("",ClientsFields) +ClientsFieldsFrame = sg.Frame("",ClientsFields, expand_x=True) # Client's workers list in multiline -ClientWorkersList = [[sg.Text("workers "), sg.Multiline(size=(20,6))]] +ClientWorkersList = [[sg.Text("workers "), sg.Listbox([],size=(20,6)), sg.Combo("workers", size=(15))]] ClientWorkersFrame = sg.Frame("",ClientWorkersList) -ClientsFieldsFrames = sg.Frame("Clients",layout=[[ClientsFieldsFrame,ClientWorkersFrame]], expand_x=True) +ClientsFieldsFrames = sg.Frame("Clients",layout=[[ClientsFieldsFrame,ClientWorkersFrame]]) # Routers RoutersFields = [ @@ -86,7 +90,7 @@ [sg.Text("name: "), sg.InputText(size=15), sg.Text("policy "), sg.InputText(size=15)], [sg.Text("port: "), sg.InputText(size=15)], ] -RoutersFieldsFrame = sg.Frame("Routers",RoutersFields, expand_x=True) +RoutersFieldsFrame = sg.Frame("Routers",RoutersFields) # Sources SourcesFields = [ @@ -94,11 +98,19 @@ [sg.Text("name: "), sg.InputText(size=15), sg.Text("frequency: "), sg.InputText(size=15)], [sg.Text("port: "), sg.InputText(size=15)], ] -SourcesFieldsFrame = sg.Frame("Sources",SourcesFields, expand_x=True) +SourcesFieldsFrame = sg.Frame("Sources",SourcesFields) # Entities Frame -EntitiesFieldsFrame = sg.Frame("", layout=[[ClientsFieldsFrames, RoutersFieldsFrame],[SourcesFieldsFrame]], expand_x=True) -EntitiesFrame = sg.Frame("Entities - HTTP Cowboy instances",layout=[[EntitiesFieldsFrame]], expand_x=True) +EntitiesNamesList = [] +EntitiesListFields = [[sg.Text("Clients", expand_x=True), sg.Text("Routers", expand_x=True), sg.Text("Sources", expand_x=True)], + [sg.Listbox(EntitiesNamesList, size=(20,14) ), sg.Listbox(EntitiesNamesList, size=(20,14) ), sg.Listbox(EntitiesNamesList, size=(20,14) )] + ] +EntitiesFieldsFrame = sg.Frame("", layout=[[ClientsFieldsFrames],[SourcesFieldsFrame, RoutersFieldsFrame]]) +EntitiesListFrame = sg.Frame("", EntitiesListFields) +EntitiesFrame = sg.Frame("Entities - HTTP Cowboy instances",layout=[[EntitiesFieldsFrame, EntitiesListFrame]]) + + + # Json File Control @@ -115,18 +127,19 @@ main_window = sg.Window(title=WINDOW_TITLE, layout=[[sg.Image(NERLNET_LOGO_PATH, expand_x=True)], [sg.Text(f'Nerlnet Planner v-{VERSION}')], [settingsFrame, jsonCtrlFrame], - [workersFrame, devicesFrame ], - [EntitiesFrame, EntitiesListFrame - ]]) - - + [EntitiesFrame], + [workersFrame, devicesFrame ] + ]) while True: event, values = main_window.read(timeout=50) settings_handler(event,values) workers_handler(main_window,event,values) + online_scanner_handler(main_window, event, values, devices_online_hosts_list) # lan scan for online devices + if event == sg.WIN_CLOSED or event == 'Cancel': # if user closes window or clicks cancel break + if event == JSON_CONTROL_LOAD_FILE_BROWSE_EVENT_KEY: update_current_json_file_path(values[JSON_CONTROL_LOAD_FILE_BROWSE_EVENT_KEY]) if event == WIN_WORKER_DIALOG_EVENT_KEY: From 5ba57bc95dc29781124ea896cdde78c0fd9cb4c2 Mon Sep 17 00:00:00 2001 From: leondavi Date: Fri, 14 Jul 2023 03:14:17 +0300 Subject: [PATCH 2/2] [JSONGEN] added selected notification of workers --- src_py/nerlPlanner/Handlers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_py/nerlPlanner/Handlers.py b/src_py/nerlPlanner/Handlers.py index a26357f4..df6c2460 100644 --- a/src_py/nerlPlanner/Handlers.py +++ b/src_py/nerlPlanner/Handlers.py @@ -117,7 +117,7 @@ def workers_handler(window, event, values): if event == KEY_WORKERS_LIST_BOX: worker_name_selection = values[KEY_WORKERS_LIST_BOX][0] - print(f"List box {worker_name_selection}") + window[KEY_WORKERS_INFO_BAR].update(f'{worker_name_selection} is selected') if event == KEY_WORKERS_LOAD_FROM_LIST_WORKER_BUTTON: if (worker_name_selection in workers_dict) and workers_new_worker_name: @@ -130,7 +130,7 @@ def workers_handler(window, event, values): def devices_handler(window, event, values): device_name = values[KEY_DEVICES_NAME_INPUT] device_ip = values[KEY_DEVICES_IP_INPUT] - + def update_current_json_file_path(jsonPath):