mirror of
https://github.com/KevinMidboe/mktxp-no-cli.git
synced 2025-10-29 17:50:23 +00:00
remote dhcp info resolution (wireless/capsman), more wifiwave2 support
This commit is contained in:
@@ -331,7 +331,7 @@ mktxp is running as pid 36704
|
|||||||
|
|
||||||
````
|
````
|
||||||
❯ mktxp -h
|
❯ mktxp -h
|
||||||
usage: MKTXP [-h] [--dir DIR] {info, edit, export, print, show, } ...
|
usage: MKTXP [-h] [--cfg-dir CFG_DIR] {info, edit, export, print, show, } ...
|
||||||
````
|
````
|
||||||
To learn more about individual commands, just run it with ```-h```:
|
To learn more about individual commands, just run it with ```-h```:
|
||||||
For example, to learn everything about ````mktxp show````:
|
For example, to learn everything about ````mktxp show````:
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ class MKTXPConfigKeys:
|
|||||||
|
|
||||||
FE_USER_KEY = 'user'
|
FE_USER_KEY = 'user'
|
||||||
FE_QUEUE_KEY = 'queue'
|
FE_QUEUE_KEY = 'queue'
|
||||||
|
FE_REMOTE_DHCP_ENTRY = 'remote_dhcp_entry'
|
||||||
|
|
||||||
MKTXP_SOCKET_TIMEOUT = 'socket_timeout'
|
MKTXP_SOCKET_TIMEOUT = 'socket_timeout'
|
||||||
MKTXP_INITIAL_DELAY = 'initial_delay_on_failure'
|
MKTXP_INITIAL_DELAY = 'initial_delay_on_failure'
|
||||||
@@ -88,6 +89,7 @@ class MKTXPConfigKeys:
|
|||||||
# Default values
|
# Default values
|
||||||
DEFAULT_API_PORT = 8728
|
DEFAULT_API_PORT = 8728
|
||||||
DEFAULT_API_SSL_PORT = 8729
|
DEFAULT_API_SSL_PORT = 8729
|
||||||
|
DEFAULT_FE_REMOTE_DHCP_ENTRY = 'None'
|
||||||
DEFAULT_MKTXP_PORT = 49090
|
DEFAULT_MKTXP_PORT = 49090
|
||||||
DEFAULT_MKTXP_SOCKET_TIMEOUT = 2
|
DEFAULT_MKTXP_SOCKET_TIMEOUT = 2
|
||||||
DEFAULT_MKTXP_INITIAL_DELAY = 120
|
DEFAULT_MKTXP_INITIAL_DELAY = 120
|
||||||
@@ -113,7 +115,7 @@ class MKTXPConfigKeys:
|
|||||||
SYSTEM_BOOLEAN_KEYS_YES = {MKTXP_BANDWIDTH_KEY}
|
SYSTEM_BOOLEAN_KEYS_YES = {MKTXP_BANDWIDTH_KEY}
|
||||||
SYSTEM_BOOLEAN_KEYS_NO = {MKTXP_VERBOSE_MODE, MKTXP_FETCH_IN_PARALLEL}
|
SYSTEM_BOOLEAN_KEYS_NO = {MKTXP_VERBOSE_MODE, MKTXP_FETCH_IN_PARALLEL}
|
||||||
|
|
||||||
STR_KEYS = (HOST_KEY, USER_KEY, PASSWD_KEY)
|
STR_KEYS = (HOST_KEY, USER_KEY, PASSWD_KEY, FE_REMOTE_DHCP_ENTRY)
|
||||||
MKTXP_INT_KEYS = (PORT_KEY, MKTXP_SOCKET_TIMEOUT, MKTXP_INITIAL_DELAY, MKTXP_MAX_DELAY,
|
MKTXP_INT_KEYS = (PORT_KEY, MKTXP_SOCKET_TIMEOUT, MKTXP_INITIAL_DELAY, MKTXP_MAX_DELAY,
|
||||||
MKTXP_INC_DIV, MKTXP_BANDWIDTH_TEST_INTERVAL, MKTXP_MIN_COLLECT_INTERVAL,
|
MKTXP_INC_DIV, MKTXP_BANDWIDTH_TEST_INTERVAL, MKTXP_MIN_COLLECT_INTERVAL,
|
||||||
MKTXP_MAX_WORKER_THREADS, MKTXP_MAX_SCRAPE_DURATION, MKTXP_TOTAL_MAX_SCRAPE_DURATION)
|
MKTXP_MAX_WORKER_THREADS, MKTXP_MAX_SCRAPE_DURATION, MKTXP_TOTAL_MAX_SCRAPE_DURATION)
|
||||||
@@ -130,7 +132,7 @@ class ConfigEntry:
|
|||||||
MKTXPConfigKeys.FE_FIREWALL_KEY, MKTXPConfigKeys.FE_MONITOR_KEY, MKTXPConfigKeys.FE_ROUTE_KEY, MKTXPConfigKeys.FE_WIRELESS_KEY, MKTXPConfigKeys.FE_WIRELESS_CLIENTS_KEY,
|
MKTXPConfigKeys.FE_FIREWALL_KEY, MKTXPConfigKeys.FE_MONITOR_KEY, MKTXPConfigKeys.FE_ROUTE_KEY, MKTXPConfigKeys.FE_WIRELESS_KEY, MKTXPConfigKeys.FE_WIRELESS_CLIENTS_KEY,
|
||||||
MKTXPConfigKeys.FE_IP_CONNECTIONS_KEY, MKTXPConfigKeys.FE_CAPSMAN_KEY, MKTXPConfigKeys.FE_CAPSMAN_CLIENTS_KEY, MKTXPConfigKeys.FE_POE_KEY, MKTXPConfigKeys.FE_NETWATCH_KEY,
|
MKTXPConfigKeys.FE_IP_CONNECTIONS_KEY, MKTXPConfigKeys.FE_CAPSMAN_KEY, MKTXPConfigKeys.FE_CAPSMAN_CLIENTS_KEY, MKTXPConfigKeys.FE_POE_KEY, MKTXPConfigKeys.FE_NETWATCH_KEY,
|
||||||
MKTXPConfigKeys.MKTXP_USE_COMMENTS_OVER_NAMES, MKTXPConfigKeys.FE_PUBLIC_IP_KEY, MKTXPConfigKeys.FE_IPV6_FIREWALL_KEY, MKTXPConfigKeys.FE_IPV6_NEIGHBOR_KEY,
|
MKTXPConfigKeys.MKTXP_USE_COMMENTS_OVER_NAMES, MKTXPConfigKeys.FE_PUBLIC_IP_KEY, MKTXPConfigKeys.FE_IPV6_FIREWALL_KEY, MKTXPConfigKeys.FE_IPV6_NEIGHBOR_KEY,
|
||||||
MKTXPConfigKeys.FE_USER_KEY, MKTXPConfigKeys.FE_QUEUE_KEY
|
MKTXPConfigKeys.FE_USER_KEY, MKTXPConfigKeys.FE_QUEUE_KEY, MKTXPConfigKeys.FE_REMOTE_DHCP_ENTRY
|
||||||
])
|
])
|
||||||
MKTXPSystemEntry = namedtuple('MKTXPSystemEntry', [MKTXPConfigKeys.PORT_KEY, MKTXPConfigKeys.MKTXP_SOCKET_TIMEOUT,
|
MKTXPSystemEntry = namedtuple('MKTXPSystemEntry', [MKTXPConfigKeys.PORT_KEY, MKTXPConfigKeys.MKTXP_SOCKET_TIMEOUT,
|
||||||
MKTXPConfigKeys.MKTXP_INITIAL_DELAY, MKTXPConfigKeys.MKTXP_MAX_DELAY,
|
MKTXPConfigKeys.MKTXP_INITIAL_DELAY, MKTXPConfigKeys.MKTXP_MAX_DELAY,
|
||||||
@@ -277,7 +279,12 @@ class MKTXPConfigHandler:
|
|||||||
new_keys.append(key) # read from disk next time
|
new_keys.append(key) # read from disk next time
|
||||||
|
|
||||||
for key in MKTXPConfigKeys.STR_KEYS:
|
for key in MKTXPConfigKeys.STR_KEYS:
|
||||||
config_entry_reader[key] = self.config[entry_name][key]
|
if self.config[entry_name].get(key):
|
||||||
|
config_entry_reader[key] = self.config[entry_name].get(key)
|
||||||
|
else:
|
||||||
|
config_entry_reader[key] = self._default_value_for_key(key)
|
||||||
|
new_keys.append(key) # read from disk next time
|
||||||
|
|
||||||
if key is MKTXPConfigKeys.PASSWD_KEY and type(config_entry_reader[key]) is list:
|
if key is MKTXPConfigKeys.PASSWD_KEY and type(config_entry_reader[key]) is list:
|
||||||
config_entry_reader[key] = ','.join(config_entry_reader[key])
|
config_entry_reader[key] = ','.join(config_entry_reader[key])
|
||||||
|
|
||||||
@@ -338,6 +345,7 @@ class MKTXPConfigHandler:
|
|||||||
return {
|
return {
|
||||||
MKTXPConfigKeys.SSL_KEY: lambda value: MKTXPConfigKeys.DEFAULT_API_SSL_PORT if value else MKTXPConfigKeys.DEFAULT_API_PORT,
|
MKTXPConfigKeys.SSL_KEY: lambda value: MKTXPConfigKeys.DEFAULT_API_SSL_PORT if value else MKTXPConfigKeys.DEFAULT_API_PORT,
|
||||||
MKTXPConfigKeys.PORT_KEY: lambda value: MKTXPConfigKeys.DEFAULT_MKTXP_PORT,
|
MKTXPConfigKeys.PORT_KEY: lambda value: MKTXPConfigKeys.DEFAULT_MKTXP_PORT,
|
||||||
|
MKTXPConfigKeys.FE_REMOTE_DHCP_ENTRY: lambda value: MKTXPConfigKeys.DEFAULT_FE_REMOTE_DHCP_ENTRY,
|
||||||
MKTXPConfigKeys.MKTXP_SOCKET_TIMEOUT: lambda value: MKTXPConfigKeys.DEFAULT_MKTXP_SOCKET_TIMEOUT,
|
MKTXPConfigKeys.MKTXP_SOCKET_TIMEOUT: lambda value: MKTXPConfigKeys.DEFAULT_MKTXP_SOCKET_TIMEOUT,
|
||||||
MKTXPConfigKeys.MKTXP_INITIAL_DELAY: lambda value: MKTXPConfigKeys.DEFAULT_MKTXP_INITIAL_DELAY,
|
MKTXPConfigKeys.MKTXP_INITIAL_DELAY: lambda value: MKTXPConfigKeys.DEFAULT_MKTXP_INITIAL_DELAY,
|
||||||
MKTXPConfigKeys.MKTXP_MAX_DELAY: lambda value: MKTXPConfigKeys.DEFAULT_MKTXP_MAX_DELAY,
|
MKTXPConfigKeys.MKTXP_MAX_DELAY: lambda value: MKTXPConfigKeys.DEFAULT_MKTXP_MAX_DELAY,
|
||||||
|
|||||||
@@ -47,5 +47,6 @@
|
|||||||
|
|
||||||
user = True # Active Users metrics
|
user = True # Active Users metrics
|
||||||
queue = True # Queues metrics
|
queue = True # Queues metrics
|
||||||
|
remote_dhcp_entry = None # Alternative mktxp entry for DHCP info resolution (capsman/wireless)
|
||||||
|
|
||||||
use_comments_over_names = True # when available, forces using comments over the interfaces names
|
use_comments_over_names = True # when available, forces using comments over the interfaces names
|
||||||
@@ -66,8 +66,8 @@ Selected metrics info can be printed on the command line. For more information,
|
|||||||
global_options_parser = ArgumentParser(add_help=False)
|
global_options_parser = ArgumentParser(add_help=False)
|
||||||
self.parse_global_options(global_options_parser)
|
self.parse_global_options(global_options_parser)
|
||||||
namespace, _ = global_options_parser.parse_known_args()
|
namespace, _ = global_options_parser.parse_known_args()
|
||||||
if namespace.dir:
|
if namespace.cfg_dir:
|
||||||
config_handler(CustomConfig(namespace.dir))
|
config_handler(CustomConfig(namespace.cfg_dir))
|
||||||
else:
|
else:
|
||||||
config_handler()
|
config_handler()
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ Selected metrics info can be printed on the command line. For more information,
|
|||||||
def parse_global_options(self, parser):
|
def parse_global_options(self, parser):
|
||||||
''' Parses global options
|
''' Parses global options
|
||||||
'''
|
'''
|
||||||
parser.add_argument('--dir', dest = 'dir',
|
parser.add_argument('--cfg-dir', dest = 'cfg_dir',
|
||||||
type = lambda d: self._is_valid_dir_path(parser, d),
|
type = lambda d: self._is_valid_dir_path(parser, d),
|
||||||
help = 'MKTXP config files directory (optional)')
|
help = 'MKTXP config files directory (optional)')
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,9 @@
|
|||||||
|
|
||||||
from mktxp.flow.processor.output import BaseOutputProcessor
|
from mktxp.flow.processor.output import BaseOutputProcessor
|
||||||
from mktxp.datasource.dhcp_ds import DHCPMetricsDataSource
|
from mktxp.datasource.dhcp_ds import DHCPMetricsDataSource
|
||||||
|
from mktxp.datasource.wireless_ds import WirelessMetricsDataSource
|
||||||
from mktxp.datasource.capsman_ds import CapsmanRegistrationsMetricsDataSource
|
from mktxp.datasource.capsman_ds import CapsmanRegistrationsMetricsDataSource
|
||||||
|
|
||||||
|
|
||||||
class CapsmanOutput:
|
class CapsmanOutput:
|
||||||
''' CAPsMAN CLI Output
|
''' CAPsMAN CLI Output
|
||||||
'''
|
'''
|
||||||
@@ -30,7 +30,8 @@ class CapsmanOutput:
|
|||||||
|
|
||||||
# translate / trim / augment registration records
|
# translate / trim / augment registration records
|
||||||
dhcp_lease_labels = ['host_name', 'comment', 'address', 'mac_address']
|
dhcp_lease_labels = ['host_name', 'comment', 'address', 'mac_address']
|
||||||
dhcp_lease_records = DHCPMetricsDataSource.metric_records(router_entry, metric_labels = dhcp_lease_labels, add_router_id = False)
|
dhcp_entry = WirelessMetricsDataSource.dhcp_entry(router_entry)
|
||||||
|
dhcp_lease_records = DHCPMetricsDataSource.metric_records(dhcp_entry, metric_labels = dhcp_lease_labels, add_router_id = False)
|
||||||
|
|
||||||
dhcp_rt_by_interface = {}
|
dhcp_rt_by_interface = {}
|
||||||
for registration_record in sorted(registration_records, key = lambda rt_record: rt_record['rx_signal'], reverse=True):
|
for registration_record in sorted(registration_records, key = lambda rt_record: rt_record['rx_signal'], reverse=True):
|
||||||
@@ -60,4 +61,3 @@ class CapsmanOutput:
|
|||||||
print(f'{server} clients: {len(dhcp_rt_by_interface[server])}')
|
print(f'{server} clients: {len(dhcp_rt_by_interface[server])}')
|
||||||
print(f'Total connected CAPsMAN clients: {output_records}', '\n')
|
print(f'Total connected CAPsMAN clients: {output_records}', '\n')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
from mktxp.flow.processor.output import BaseOutputProcessor
|
from mktxp.flow.processor.output import BaseOutputProcessor
|
||||||
from mktxp.datasource.dhcp_ds import DHCPMetricsDataSource
|
from mktxp.datasource.dhcp_ds import DHCPMetricsDataSource
|
||||||
from mktxp.datasource.wireless_ds import WirelessMetricsDataSource
|
from mktxp.datasource.wireless_ds import WirelessMetricsDataSource
|
||||||
|
from mktxp.flow.router_entries_handler import RouterEntriesHandler
|
||||||
|
|
||||||
|
|
||||||
class WirelessOutput:
|
class WirelessOutput:
|
||||||
@@ -30,7 +31,8 @@ class WirelessOutput:
|
|||||||
|
|
||||||
# translate / trim / augment registration records
|
# translate / trim / augment registration records
|
||||||
dhcp_lease_labels = ['host_name', 'comment', 'address', 'mac_address']
|
dhcp_lease_labels = ['host_name', 'comment', 'address', 'mac_address']
|
||||||
dhcp_lease_records = DHCPMetricsDataSource.metric_records(router_entry, metric_labels = dhcp_lease_labels, add_router_id = False)
|
dhcp_entry = WirelessMetricsDataSource.dhcp_entry(router_entry)
|
||||||
|
dhcp_lease_records = DHCPMetricsDataSource.metric_records(dhcp_entry, metric_labels = dhcp_lease_labels, add_router_id = False)
|
||||||
|
|
||||||
dhcp_rt_by_interface = {}
|
dhcp_rt_by_interface = {}
|
||||||
|
|
||||||
@@ -46,7 +48,8 @@ class WirelessOutput:
|
|||||||
|
|
||||||
output_records = 0
|
output_records = 0
|
||||||
registration_records = len(registration_records)
|
registration_records = len(registration_records)
|
||||||
output_entry = BaseOutputProcessor.OutputWiFiEntry
|
output_entry = BaseOutputProcessor.OutputWiFiWave2Entry \
|
||||||
|
if WirelessMetricsDataSource.wifiwave2_installed(router_entry) else BaseOutputProcessor.OutputWiFiEntry
|
||||||
output_table = BaseOutputProcessor.output_table(output_entry)
|
output_table = BaseOutputProcessor.output_table(output_entry)
|
||||||
|
|
||||||
for key in dhcp_rt_by_interface.keys():
|
for key in dhcp_rt_by_interface.keys():
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from mktxp.flow.processor.output import BaseOutputProcessor
|
|||||||
from mktxp.collector.base_collector import BaseCollector
|
from mktxp.collector.base_collector import BaseCollector
|
||||||
from mktxp.datasource.dhcp_ds import DHCPMetricsDataSource
|
from mktxp.datasource.dhcp_ds import DHCPMetricsDataSource
|
||||||
from mktxp.datasource.capsman_ds import CapsmanCapsMetricsDataSource, CapsmanRegistrationsMetricsDataSource, CapsmanInterfacesDatasource
|
from mktxp.datasource.capsman_ds import CapsmanCapsMetricsDataSource, CapsmanRegistrationsMetricsDataSource, CapsmanInterfacesDatasource
|
||||||
|
from mktxp.datasource.wireless_ds import WirelessMetricsDataSource
|
||||||
|
|
||||||
|
|
||||||
class CapsmanCollector(BaseCollector):
|
class CapsmanCollector(BaseCollector):
|
||||||
@@ -51,9 +52,11 @@ class CapsmanCollector(BaseCollector):
|
|||||||
|
|
||||||
# the client info metrics
|
# the client info metrics
|
||||||
if router_entry.config_entry.capsman_clients:
|
if router_entry.config_entry.capsman_clients:
|
||||||
|
|
||||||
# translate / trim / augment registration records
|
# translate / trim / augment registration records
|
||||||
dhcp_lease_labels = ['mac_address', 'address', 'host_name', 'comment']
|
dhcp_lease_labels = ['mac_address', 'address', 'host_name', 'comment']
|
||||||
dhcp_lease_records = DHCPMetricsDataSource.metric_records(router_entry, metric_labels = dhcp_lease_labels)
|
dhcp_entry = WirelessMetricsDataSource.dhcp_entry(router_entry)
|
||||||
|
dhcp_lease_records = DHCPMetricsDataSource.metric_records(dhcp_entry, metric_labels = dhcp_lease_labels)
|
||||||
for registration_record in registration_records:
|
for registration_record in registration_records:
|
||||||
BaseOutputProcessor.augment_record(router_entry, registration_record, dhcp_lease_records)
|
BaseOutputProcessor.augment_record(router_entry, registration_record, dhcp_lease_records)
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ class WLANCollector(BaseCollector):
|
|||||||
registration_records = WirelessMetricsDataSource.metric_records(router_entry, metric_labels = registration_labels)
|
registration_records = WirelessMetricsDataSource.metric_records(router_entry, metric_labels = registration_labels)
|
||||||
if registration_records:
|
if registration_records:
|
||||||
dhcp_lease_labels = ['mac_address', 'address', 'host_name', 'comment']
|
dhcp_lease_labels = ['mac_address', 'address', 'host_name', 'comment']
|
||||||
dhcp_lease_records = DHCPMetricsDataSource.metric_records(router_entry, metric_labels = dhcp_lease_labels)
|
dhcp_entry = WirelessMetricsDataSource.dhcp_entry(router_entry)
|
||||||
|
dhcp_lease_records = DHCPMetricsDataSource.metric_records(dhcp_entry, metric_labels = dhcp_lease_labels)
|
||||||
|
|
||||||
for registration_record in registration_records:
|
for registration_record in registration_records:
|
||||||
BaseOutputProcessor.augment_record(router_entry, registration_record, dhcp_lease_records)
|
BaseOutputProcessor.augment_record(router_entry, registration_record, dhcp_lease_records)
|
||||||
|
|||||||
@@ -19,14 +19,14 @@ from mktxp.datasource.wireless_ds import WirelessMetricsDataSource
|
|||||||
class CapsmanInfo:
|
class CapsmanInfo:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def capsman_path(router_entry):
|
def capsman_path(router_entry):
|
||||||
if WirelessMetricsDataSource.wireless_package(router_entry) == WirelessMetricsDataSource.WIFIWAVE2:
|
if WirelessMetricsDataSource.wifiwave2_installed(router_entry):
|
||||||
return '/interface/wifiwave2/capsman'
|
return '/interface/wifiwave2/capsman'
|
||||||
else:
|
else:
|
||||||
return '/caps-man'
|
return '/caps-man'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def registration_table_path(router_entry):
|
def registration_table_path(router_entry):
|
||||||
if WirelessMetricsDataSource.wireless_package(router_entry) == WirelessMetricsDataSource.WIFIWAVE2:
|
if WirelessMetricsDataSource.wifiwave2_installed(router_entry):
|
||||||
return '/interface/wifiwave2/registration-table'
|
return '/interface/wifiwave2/registration-table'
|
||||||
else:
|
else:
|
||||||
return '/caps-man/registration-table'
|
return '/caps-man/registration-table'
|
||||||
@@ -57,6 +57,12 @@ class CapsmanRegistrationsMetricsDataSource:
|
|||||||
try:
|
try:
|
||||||
registration_table_path = CapsmanInfo.registration_table_path(router_entry)
|
registration_table_path = CapsmanInfo.registration_table_path(router_entry)
|
||||||
registration_table_records = router_entry.api_connection.router_api().get_resource(f'{registration_table_path}').get()
|
registration_table_records = router_entry.api_connection.router_api().get_resource(f'{registration_table_path}').get()
|
||||||
|
|
||||||
|
# With wifiwave2, Mikrotik renamed the field 'rx_signal' to 'signal'
|
||||||
|
for record in registration_table_records:
|
||||||
|
if 'signal' in record:
|
||||||
|
record['rx_signal'] = record['signal']
|
||||||
|
|
||||||
return BaseDSProcessor.trimmed_records(router_entry, router_records = registration_table_records, metric_labels = metric_labels, add_router_id = add_router_id)
|
return BaseDSProcessor.trimmed_records(router_entry, router_records = registration_table_records, metric_labels = metric_labels, add_router_id = add_router_id)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print(f'Error getting CAPsMAN registration table info from router{router_entry.router_name}@{router_entry.config_entry.hostname}: {exc}')
|
print(f'Error getting CAPsMAN registration table info from router{router_entry.router_name}@{router_entry.config_entry.hostname}: {exc}')
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ class WirelessMetricsDataSource:
|
|||||||
WIFIWAVE2 = 'wifiwave2'
|
WIFIWAVE2 = 'wifiwave2'
|
||||||
WIRELESS = 'wireless'
|
WIRELESS = 'wireless'
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def metric_records(router_entry, *, metric_labels = None, add_router_id = True):
|
def metric_records(router_entry, *, metric_labels = None, add_router_id = True):
|
||||||
if metric_labels is None:
|
if metric_labels is None:
|
||||||
@@ -31,8 +30,7 @@ class WirelessMetricsDataSource:
|
|||||||
wireless_package = WirelessMetricsDataSource.wireless_package(router_entry)
|
wireless_package = WirelessMetricsDataSource.wireless_package(router_entry)
|
||||||
registration_table_records = router_entry.api_connection.router_api().get_resource(f'/interface/{wireless_package}/registration-table').get()
|
registration_table_records = router_entry.api_connection.router_api().get_resource(f'/interface/{wireless_package}/registration-table').get()
|
||||||
|
|
||||||
# Mikrotik renamed the field 'signal_strength' to 'signal' when using wifiwave2.
|
# With wifiwave2, Mikrotik renamed the field 'signal_strength' to 'signal'
|
||||||
# Rename this field back to 'signal_strength' to preserve backwards compatibility
|
|
||||||
for record in registration_table_records:
|
for record in registration_table_records:
|
||||||
if 'signal' in record:
|
if 'signal' in record:
|
||||||
record['signal_strength'] = record['signal']
|
record['signal_strength'] = record['signal']
|
||||||
@@ -49,3 +47,15 @@ class WirelessMetricsDataSource:
|
|||||||
ww2_installed = PackageMetricsDataSource.is_package_installed(router_entry, package_name = WirelessMetricsDataSource.WIFIWAVE2)
|
ww2_installed = PackageMetricsDataSource.is_package_installed(router_entry, package_name = WirelessMetricsDataSource.WIFIWAVE2)
|
||||||
router_entry.wifi_package = WirelessMetricsDataSource.WIFIWAVE2 if ww2_installed else WirelessMetricsDataSource.WIRELESS
|
router_entry.wifi_package = WirelessMetricsDataSource.WIFIWAVE2 if ww2_installed else WirelessMetricsDataSource.WIRELESS
|
||||||
return router_entry.wifi_package
|
return router_entry.wifi_package
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def wifiwave2_installed(router_entry):
|
||||||
|
return WirelessMetricsDataSource.wireless_package(router_entry) == WirelessMetricsDataSource.WIFIWAVE2
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def dhcp_entry(router_entry):
|
||||||
|
if router_entry.dhcp_entry:
|
||||||
|
return router_entry.dhcp_entry
|
||||||
|
return router_entry
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,9 +35,8 @@ class CollectorHandler:
|
|||||||
Thus, the total runtime of this function scales linearly with the number of registered routers.
|
Thus, the total runtime of this function scales linearly with the number of registered routers.
|
||||||
"""
|
"""
|
||||||
for router_entry in self.entries_handler.router_entries:
|
for router_entry in self.entries_handler.router_entries:
|
||||||
if not router_entry.api_connection.is_connected():
|
if not router_entry.is_connected():
|
||||||
# let's pick up on things in the next run
|
# let's pick up on things in the next run
|
||||||
router_entry.api_connection.connect()
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for collector_ID, collect_func in self.collector_registry.registered_collectors.items():
|
for collector_ID, collect_func in self.collector_registry.registered_collectors.items():
|
||||||
@@ -88,9 +87,8 @@ class CollectorHandler:
|
|||||||
print(f'Hit overall timeout while scraping router entry: {router_entry.router_id[MKTXPConfigKeys.ROUTERBOARD_NAME]}')
|
print(f'Hit overall timeout while scraping router entry: {router_entry.router_id[MKTXPConfigKeys.ROUTERBOARD_NAME]}')
|
||||||
break
|
break
|
||||||
|
|
||||||
if not router_entry.api_connection.is_connected():
|
if not router_entry.is_connected():
|
||||||
# let's pick up on things in the next run
|
# let's pick up on things in the next run
|
||||||
router_entry.api_connection.connect()
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Duration of individual scrapes
|
# Duration of individual scrapes
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ from collections import namedtuple
|
|||||||
from texttable import Texttable
|
from texttable import Texttable
|
||||||
from humanize import naturaldelta
|
from humanize import naturaldelta
|
||||||
from mktxp.cli.config.config import config_handler
|
from mktxp.cli.config.config import config_handler
|
||||||
|
from mktxp.datasource.wireless_ds import WirelessMetricsDataSource
|
||||||
|
from math import floor, log
|
||||||
|
|
||||||
|
|
||||||
class BaseOutputProcessor:
|
class BaseOutputProcessor:
|
||||||
@@ -27,18 +29,23 @@ class BaseOutputProcessor:
|
|||||||
OutputWiFiEntry = namedtuple('OutputWiFiEntry', ['dhcp_name', 'dhcp_address', 'mac_address', 'signal_strength', 'signal_to_noise', 'interface', 'tx_rate', 'rx_rate', 'uptime'])
|
OutputWiFiEntry = namedtuple('OutputWiFiEntry', ['dhcp_name', 'dhcp_address', 'mac_address', 'signal_strength', 'signal_to_noise', 'interface', 'tx_rate', 'rx_rate', 'uptime'])
|
||||||
OutputWiFiEntry.__new__.__defaults__ = ('',) * len(OutputWiFiEntry._fields)
|
OutputWiFiEntry.__new__.__defaults__ = ('',) * len(OutputWiFiEntry._fields)
|
||||||
|
|
||||||
|
OutputWiFiWave2Entry = namedtuple('OutputWiFiWave2Entry', ['dhcp_name', 'dhcp_address', 'mac_address', 'signal_strength', 'interface', 'tx_rate', 'rx_rate', 'uptime'])
|
||||||
|
OutputWiFiWave2Entry.__new__.__defaults__ = ('',) * len(OutputWiFiWave2Entry._fields)
|
||||||
|
|
||||||
OutputDHCPEntry = namedtuple('OutputDHCPEntry', ['host_name', 'server', 'mac_address', 'address', 'active_address', 'expires_after'])
|
OutputDHCPEntry = namedtuple('OutputDHCPEntry', ['host_name', 'server', 'mac_address', 'address', 'active_address', 'expires_after'])
|
||||||
OutputDHCPEntry.__new__.__defaults__ = ('',) * len(OutputDHCPEntry._fields)
|
OutputDHCPEntry.__new__.__defaults__ = ('',) * len(OutputDHCPEntry._fields)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def augment_record(router_entry, registration_record, dhcp_lease_records):
|
def augment_record(router_entry, registration_record, dhcp_lease_records):
|
||||||
try:
|
dhcp_name = registration_record.get('mac_address')
|
||||||
dhcp_lease_record = next((dhcp_lease_record for dhcp_lease_record in dhcp_lease_records if dhcp_lease_record.get('mac_address')==registration_record.get('mac_address')))
|
dhcp_address = 'No DHCP Record'
|
||||||
dhcp_name = BaseOutputProcessor.dhcp_name(router_entry, dhcp_lease_record)
|
if dhcp_lease_records:
|
||||||
dhcp_address = dhcp_lease_record.get('address', '')
|
try:
|
||||||
except StopIteration:
|
dhcp_lease_record = next((dhcp_lease_record for dhcp_lease_record in dhcp_lease_records if dhcp_lease_record.get('mac_address')==registration_record.get('mac_address')))
|
||||||
dhcp_name = registration_record.get('mac_address')
|
dhcp_name = BaseOutputProcessor.dhcp_name(router_entry, dhcp_lease_record)
|
||||||
dhcp_address = 'No DHCP Record'
|
dhcp_address = dhcp_lease_record.get('address', '')
|
||||||
|
except StopIteration:
|
||||||
|
pass
|
||||||
|
|
||||||
registration_record['dhcp_name'] = dhcp_name
|
registration_record['dhcp_name'] = dhcp_name
|
||||||
registration_record['dhcp_address'] = dhcp_address
|
registration_record['dhcp_address'] = dhcp_address
|
||||||
@@ -49,10 +56,13 @@ class BaseOutputProcessor:
|
|||||||
registration_record['rx_bytes'] = registration_record['bytes'].split(',')[1]
|
registration_record['rx_bytes'] = registration_record['bytes'].split(',')[1]
|
||||||
del registration_record['bytes']
|
del registration_record['bytes']
|
||||||
|
|
||||||
|
ww2_installed = WirelessMetricsDataSource.wifiwave2_installed(router_entry)
|
||||||
if registration_record.get('tx_rate'):
|
if registration_record.get('tx_rate'):
|
||||||
registration_record['tx_rate'] = BaseOutputProcessor.parse_rates(registration_record['tx_rate'])
|
registration_record['tx_rate'] = BaseOutputProcessor.parse_bitrates(registration_record['tx_rate']) \
|
||||||
|
if ww2_installed else BaseOutputProcessor.parse_rates(registration_record['tx_rate'])
|
||||||
if registration_record.get('rx_rate'):
|
if registration_record.get('rx_rate'):
|
||||||
registration_record['rx_rate'] = BaseOutputProcessor.parse_rates(registration_record['rx_rate'])
|
registration_record['rx_rate'] = BaseOutputProcessor.parse_bitrates(registration_record['rx_rate']) \
|
||||||
|
if ww2_installed else BaseOutputProcessor.parse_rates(registration_record['rx_rate'])
|
||||||
if registration_record.get('uptime'):
|
if registration_record.get('uptime'):
|
||||||
registration_record['uptime'] = naturaldelta(BaseOutputProcessor.parse_timedelta_seconds(registration_record['uptime']), months=True, minimum_unit='seconds')
|
registration_record['uptime'] = naturaldelta(BaseOutputProcessor.parse_timedelta_seconds(registration_record['uptime']), months=True, minimum_unit='seconds')
|
||||||
|
|
||||||
@@ -87,6 +97,12 @@ class BaseOutputProcessor:
|
|||||||
rc = wifi_rates_rgx.search(rate)
|
rc = wifi_rates_rgx.search(rate)
|
||||||
return f'{int(float(rc[1]))} {rc[2]}' if rc and len(rc.groups()) == 2 else rate
|
return f'{int(float(rc[1]))} {rc[2]}' if rc and len(rc.groups()) == 2 else rate
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse_bitrates(rate):
|
||||||
|
rate = int(rate)
|
||||||
|
power = floor(log(rate, 1000))
|
||||||
|
return f"{int(rate / 1000 ** power)} {['bps', 'Kbps', 'Mbps', 'Gbps'][int(power)]}"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def parse_timedelta(time):
|
def parse_timedelta(time):
|
||||||
duration_interval_rgx = config_handler.re_compiled.get('duration_interval_rgx')
|
duration_interval_rgx = config_handler.re_compiled.get('duration_interval_rgx')
|
||||||
@@ -126,6 +142,3 @@ class BaseOutputProcessor:
|
|||||||
table.header(outputEntry._fields)
|
table.header(outputEntry._fields)
|
||||||
table.set_cols_align(['l']+ ['c']*(len(outputEntry._fields)-1))
|
table.set_cols_align(['l']+ ['c']*(len(outputEntry._fields)-1))
|
||||||
return table
|
return table
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,19 +22,22 @@ class RouterEntriesHandler:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.router_entries = []
|
self.router_entries = []
|
||||||
for router_name in config_handler.registered_entries():
|
for router_name in config_handler.registered_entries():
|
||||||
entry = config_handler.config_entry(router_name)
|
router_entry = RouterEntriesHandler.router_entry(router_name, enabled_only = True)
|
||||||
if entry.enabled:
|
if router_entry:
|
||||||
self.router_entries.append(RouterEntry(router_name))
|
self.router_entries.append(router_entry)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def router_entry(entry_name, enabled_only = False):
|
def router_entry(entry_name, enabled_only = False):
|
||||||
router_entry = None
|
router_entry = None
|
||||||
|
|
||||||
for router_name in config_handler.registered_entries():
|
for router_name in config_handler.registered_entries():
|
||||||
if router_name == entry_name:
|
if router_name == entry_name:
|
||||||
if enabled_only:
|
config_entry = config_handler.config_entry(router_name)
|
||||||
entry = config_handler.config_entry(router_name)
|
if enabled_only and not config_entry.enabled:
|
||||||
if not entry.enabled:
|
|
||||||
break
|
break
|
||||||
|
|
||||||
router_entry = RouterEntry(router_name)
|
router_entry = RouterEntry(router_name)
|
||||||
|
router_entry.dhcp_entry = RouterEntriesHandler.router_entry(config_entry.remote_dhcp_entry)
|
||||||
break
|
break
|
||||||
|
|
||||||
return router_entry
|
return router_entry
|
||||||
|
|||||||
@@ -27,7 +27,10 @@ class RouterEntry:
|
|||||||
MKTXPConfigKeys.ROUTERBOARD_NAME: self.router_name,
|
MKTXPConfigKeys.ROUTERBOARD_NAME: self.router_name,
|
||||||
MKTXPConfigKeys.ROUTERBOARD_ADDRESS: self.config_entry.hostname
|
MKTXPConfigKeys.ROUTERBOARD_ADDRESS: self.config_entry.hostname
|
||||||
}
|
}
|
||||||
|
|
||||||
self.wifi_package = None
|
self.wifi_package = None
|
||||||
|
self.dhcp_entry = None
|
||||||
|
|
||||||
self.time_spent = { 'IdentityCollector': 0,
|
self.time_spent = { 'IdentityCollector': 0,
|
||||||
'SystemResourceCollector': 0,
|
'SystemResourceCollector': 0,
|
||||||
'HealthCollector': 0,
|
'HealthCollector': 0,
|
||||||
@@ -50,3 +53,17 @@ class RouterEntry:
|
|||||||
'UserCollector': 0,
|
'UserCollector': 0,
|
||||||
'MKTXPCollector': 0
|
'MKTXPCollector': 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def is_connected(self):
|
||||||
|
connected = True
|
||||||
|
if not self.api_connection.is_connected():
|
||||||
|
connected = False
|
||||||
|
# let's get connected now
|
||||||
|
self.api_connection.connect()
|
||||||
|
if self.dhcp_entry:
|
||||||
|
self.dhcp_entry.api_connection.connect()
|
||||||
|
|
||||||
|
return connected
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user