mirror of
https://github.com/KevinMidboe/mktxp-no-cli.git
synced 2025-10-29 17:50:23 +00:00
Shared default config (->#119)
This commit is contained in:
23
README.md
23
README.md
@@ -50,11 +50,20 @@ To get started with MKTXP, you need to edit its main configuration file. This es
|
|||||||
|
|
||||||
The default configuration file comes with a sample configuration, making it easy to copy / edit parameters for your RouterOS devices as needed:
|
The default configuration file comes with a sample configuration, making it easy to copy / edit parameters for your RouterOS devices as needed:
|
||||||
```
|
```
|
||||||
[Sample-Router]
|
[Sample-Router-1]
|
||||||
enabled = False # turns metrics collection for this RouterOS device on / off
|
# for specific configuration on the router level, overload the defaults here
|
||||||
|
hostname = 192.168.88.1
|
||||||
|
|
||||||
|
[Sample-Router-2]
|
||||||
|
# for specific configuration on the router level, overload the defaults here
|
||||||
|
hostname = 192.168.88.2
|
||||||
|
|
||||||
|
[default]
|
||||||
|
# this affects configuration of all routers, unless overloaded on their specific levels
|
||||||
|
enabled = True # turns metrics collection for this RouterOS device on / off
|
||||||
|
|
||||||
hostname = localhost # RouterOS IP address
|
hostname = localhost # RouterOS IP address
|
||||||
port = 8728 # RouterOS API / API-SSL service port
|
port = 8728 # RouterOS IP Port
|
||||||
|
|
||||||
username = username # RouterOS user, needs to have 'read' and 'api' permissions
|
username = username # RouterOS user, needs to have 'read' and 'api' permissions
|
||||||
password = password
|
password = password
|
||||||
@@ -87,7 +96,7 @@ The default configuration file comes with a sample configuration, making it easy
|
|||||||
capsman = True # CAPsMAN general metrics
|
capsman = True # CAPsMAN general metrics
|
||||||
capsman_clients = True # CAPsMAN clients metrics
|
capsman_clients = True # CAPsMAN clients metrics
|
||||||
|
|
||||||
kid_control_devices = False # Kid Control metrics
|
kid_control_devices = False # Kid Control metrics
|
||||||
|
|
||||||
user = True # Active Users metrics
|
user = True # Active Users metrics
|
||||||
queue = True # Queues metrics
|
queue = True # Queues metrics
|
||||||
@@ -102,7 +111,7 @@ The default configuration file comes with a sample configuration, making it easy
|
|||||||
```
|
```
|
||||||
|
|
||||||
Most options are easy to understand at first glance, and some are described in more details [later](https://github.com/akpw/mktxp#advanced-features).
|
Most options are easy to understand at first glance, and some are described in more details [later](https://github.com/akpw/mktxp#advanced-features).
|
||||||
|
<sup>💡</sup> To automatically optimise older format of the `mktxp.conf` for existing installs, set `compact_default_conf_values = True` in the system config `_mktxp.conf`
|
||||||
|
|
||||||
#### Local install
|
#### Local install
|
||||||
If you have a local MKTXP installation, you can edit the configuration file with your default system editor directly from mktxp:
|
If you have a local MKTXP installation, you can edit the configuration file with your default system editor directly from mktxp:
|
||||||
@@ -230,6 +239,8 @@ mktxp edit -i
|
|||||||
max_worker_threads = 5 # Max number of worker threads that can fetch routers (parallel fetch only)
|
max_worker_threads = 5 # Max number of worker threads that can fetch routers (parallel fetch only)
|
||||||
max_scrape_duration = 10 # Max duration of individual routers' metrics collection (parallel fetch only)
|
max_scrape_duration = 10 # Max duration of individual routers' metrics collection (parallel fetch only)
|
||||||
total_max_scrape_duration = 30 # Max overall duration of all metrics collection (parallel fetch only)
|
total_max_scrape_duration = 30 # Max overall duration of all metrics collection (parallel fetch only)
|
||||||
|
|
||||||
|
compact_default_conf_values = True # Compact mktxp.conf, so only specific values are kept on the individual routers' level
|
||||||
```
|
```
|
||||||
<sup>💡</sup> *When changing the default mktxp port for [docker image installs](https://github.com/akpw/mktxp#docker-image-install), you'll need to adjust the `docker run ... -p 49090:49090 ...` command to reflect the new port*
|
<sup>💡</sup> *When changing the default mktxp port for [docker image installs](https://github.com/akpw/mktxp#docker-image-install), you'll need to adjust the `docker run ... -p 49090:49090 ...` command to reflect the new port*
|
||||||
|
|
||||||
|
|||||||
@@ -28,4 +28,6 @@
|
|||||||
fetch_routers_in_parallel = False # Set to True if you want to fetch multiple routers parallel
|
fetch_routers_in_parallel = False # Set to True if you want to fetch multiple routers parallel
|
||||||
max_worker_threads = 5 # Max number of worker threads that can fetch routers (parallel fetch only)
|
max_worker_threads = 5 # Max number of worker threads that can fetch routers (parallel fetch only)
|
||||||
max_scrape_duration = 10 # Max duration of individual routers' metrics collection (parallel fetch only)
|
max_scrape_duration = 10 # Max duration of individual routers' metrics collection (parallel fetch only)
|
||||||
total_max_scrape_duration = 30 # Max overall duration of all metrics collection (parallel fetch only)
|
total_max_scrape_duration = 30 # Max overall duration of all metrics collection (parallel fetch only)
|
||||||
|
|
||||||
|
compact_default_conf_values = True # Compact mktxp.conf, so only specific values are kept on the individual routers' level
|
||||||
@@ -109,6 +109,7 @@ class MKTXPConfigKeys:
|
|||||||
MKTXP_MAX_WORKER_THREADS = 'max_worker_threads'
|
MKTXP_MAX_WORKER_THREADS = 'max_worker_threads'
|
||||||
MKTXP_MAX_SCRAPE_DURATION = 'max_scrape_duration'
|
MKTXP_MAX_SCRAPE_DURATION = 'max_scrape_duration'
|
||||||
MKTXP_TOTAL_MAX_SCRAPE_DURATION = 'total_max_scrape_duration'
|
MKTXP_TOTAL_MAX_SCRAPE_DURATION = 'total_max_scrape_duration'
|
||||||
|
MKTXP_COMPACT_CONFIG = 'compact_default_conf_values'
|
||||||
|
|
||||||
# UnRegistered entries placeholder
|
# UnRegistered entries placeholder
|
||||||
NO_ENTRIES_REGISTERED = 'NoEntriesRegistered'
|
NO_ENTRIES_REGISTERED = 'NoEntriesRegistered'
|
||||||
@@ -119,7 +120,11 @@ class MKTXPConfigKeys:
|
|||||||
ROUTERBOARD_NAME = 'routerboard_name'
|
ROUTERBOARD_NAME = 'routerboard_name'
|
||||||
ROUTERBOARD_ADDRESS = 'routerboard_address'
|
ROUTERBOARD_ADDRESS = 'routerboard_address'
|
||||||
|
|
||||||
# Default values
|
# Default values
|
||||||
|
DEFAULT_HOST_KEY = 'localhost'
|
||||||
|
DEFAULT_USER_KEY = 'user'
|
||||||
|
DEFAULT_PASSWORD_KEY = 'password'
|
||||||
|
|
||||||
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_FE_REMOTE_DHCP_ENTRY = 'None'
|
||||||
@@ -130,7 +135,6 @@ class MKTXPConfigKeys:
|
|||||||
DEFAULT_MKTXP_INC_DIV = 5
|
DEFAULT_MKTXP_INC_DIV = 5
|
||||||
DEFAULT_MKTXP_BANDWIDTH_TEST_INTERVAL = 420
|
DEFAULT_MKTXP_BANDWIDTH_TEST_INTERVAL = 420
|
||||||
DEFAULT_MKTXP_MIN_COLLECT_INTERVAL = 5
|
DEFAULT_MKTXP_MIN_COLLECT_INTERVAL = 5
|
||||||
DEFAULT_MKTXP_FETCH_IN_PARALLEL = False
|
|
||||||
DEFAULT_MKTXP_MAX_WORKER_THREADS = 5
|
DEFAULT_MKTXP_MAX_WORKER_THREADS = 5
|
||||||
DEFAULT_MKTXP_MAX_SCRAPE_DURATION = 10
|
DEFAULT_MKTXP_MAX_SCRAPE_DURATION = 10
|
||||||
DEFAULT_MKTXP_TOTAL_MAX_SCRAPE_DURATION = 30
|
DEFAULT_MKTXP_TOTAL_MAX_SCRAPE_DURATION = 30
|
||||||
@@ -146,7 +150,7 @@ class MKTXPConfigKeys:
|
|||||||
FE_NETWATCH_KEY, FE_PUBLIC_IP_KEY, FE_USER_KEY, FE_QUEUE_KEY}
|
FE_NETWATCH_KEY, FE_PUBLIC_IP_KEY, FE_USER_KEY, FE_QUEUE_KEY}
|
||||||
|
|
||||||
SYSTEM_BOOLEAN_KEYS_YES = set()
|
SYSTEM_BOOLEAN_KEYS_YES = set()
|
||||||
SYSTEM_BOOLEAN_KEYS_NO = {MKTXP_BANDWIDTH_KEY, MKTXP_VERBOSE_MODE, MKTXP_FETCH_IN_PARALLEL}
|
SYSTEM_BOOLEAN_KEYS_NO = {MKTXP_BANDWIDTH_KEY, MKTXP_VERBOSE_MODE, MKTXP_FETCH_IN_PARALLEL, MKTXP_COMPACT_CONFIG}
|
||||||
|
|
||||||
STR_KEYS = (HOST_KEY, USER_KEY, PASSWD_KEY, FE_REMOTE_DHCP_ENTRY)
|
STR_KEYS = (HOST_KEY, USER_KEY, PASSWD_KEY, FE_REMOTE_DHCP_ENTRY)
|
||||||
INT_KEYS = ()
|
INT_KEYS = ()
|
||||||
@@ -154,7 +158,8 @@ class MKTXPConfigKeys:
|
|||||||
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)
|
||||||
|
|
||||||
# MKTXP config entry name
|
# MKTXP configs entry names
|
||||||
|
DEFAULT_ENTRY_KEY = 'default'
|
||||||
MKTXP_CONFIG_ENTRY_NAME = 'MKTXP'
|
MKTXP_CONFIG_ENTRY_NAME = 'MKTXP'
|
||||||
|
|
||||||
|
|
||||||
@@ -174,7 +179,7 @@ class ConfigEntry:
|
|||||||
MKTXPConfigKeys.MKTXP_VERBOSE_MODE, MKTXPConfigKeys.MKTXP_BANDWIDTH_TEST_INTERVAL,
|
MKTXPConfigKeys.MKTXP_VERBOSE_MODE, MKTXPConfigKeys.MKTXP_BANDWIDTH_TEST_INTERVAL,
|
||||||
MKTXPConfigKeys.MKTXP_MIN_COLLECT_INTERVAL, MKTXPConfigKeys.MKTXP_FETCH_IN_PARALLEL,
|
MKTXPConfigKeys.MKTXP_MIN_COLLECT_INTERVAL, MKTXPConfigKeys.MKTXP_FETCH_IN_PARALLEL,
|
||||||
MKTXPConfigKeys.MKTXP_MAX_WORKER_THREADS, MKTXPConfigKeys.MKTXP_MAX_SCRAPE_DURATION,
|
MKTXPConfigKeys.MKTXP_MAX_WORKER_THREADS, MKTXPConfigKeys.MKTXP_MAX_SCRAPE_DURATION,
|
||||||
MKTXPConfigKeys.MKTXP_TOTAL_MAX_SCRAPE_DURATION])
|
MKTXPConfigKeys.MKTXP_TOTAL_MAX_SCRAPE_DURATION, MKTXPConfigKeys.MKTXP_COMPACT_CONFIG])
|
||||||
|
|
||||||
|
|
||||||
class OSConfig(metaclass=ABCMeta):
|
class OSConfig(metaclass=ABCMeta):
|
||||||
@@ -265,11 +270,14 @@ class MKTXPConfigHandler:
|
|||||||
|
|
||||||
self._read_from_disk()
|
self._read_from_disk()
|
||||||
|
|
||||||
|
self.default_config_entry_reader = self._default_config_entry_reader()
|
||||||
|
self.system_entry = self._system_entry()
|
||||||
|
|
||||||
# MKTXP entries
|
# MKTXP entries
|
||||||
def registered_entries(self):
|
def registered_entries(self):
|
||||||
''' All MKTXP registered entries
|
''' All MKTXP registered entries
|
||||||
'''
|
'''
|
||||||
return (entry_name for entry_name in self.config.keys())
|
return (entry_name for entry_name in self.config.keys() if entry_name != MKTXPConfigKeys.DEFAULT_ENTRY_KEY )
|
||||||
|
|
||||||
def registered_entry(self, entry_name):
|
def registered_entry(self, entry_name):
|
||||||
''' A specific MKTXP registered entry by name
|
''' A specific MKTXP registered entry by name
|
||||||
@@ -282,13 +290,13 @@ class MKTXPConfigHandler:
|
|||||||
entry_reader = self._config_entry_reader(entry_name)
|
entry_reader = self._config_entry_reader(entry_name)
|
||||||
return ConfigEntry.MKTXPConfigEntry(**entry_reader) if entry_reader else None
|
return ConfigEntry.MKTXPConfigEntry(**entry_reader) if entry_reader else None
|
||||||
|
|
||||||
def system_entry(self):
|
# Helpers
|
||||||
|
def _system_entry(self):
|
||||||
''' MKTXP internal config entry
|
''' MKTXP internal config entry
|
||||||
'''
|
'''
|
||||||
_entry_reader = self._system_entry_reader()
|
_entry_reader = self._system_entry_reader()
|
||||||
return ConfigEntry.MKTXPSystemEntry(**_entry_reader)
|
return ConfigEntry.MKTXPSystemEntry(**_entry_reader)
|
||||||
|
|
||||||
# Helpers
|
|
||||||
def _read_from_disk(self):
|
def _read_from_disk(self):
|
||||||
''' (Force-)Read conf data from disk
|
''' (Force-)Read conf data from disk
|
||||||
'''
|
'''
|
||||||
@@ -305,55 +313,6 @@ class MKTXPConfigHandler:
|
|||||||
Requirement.parse("mktxp"), resource_path)
|
Requirement.parse("mktxp"), resource_path)
|
||||||
shutil.copy(lookup_path, os_path)
|
shutil.copy(lookup_path, os_path)
|
||||||
|
|
||||||
def _config_entry_reader(self, entry_name):
|
|
||||||
config_entry_reader = {}
|
|
||||||
new_keys = []
|
|
||||||
|
|
||||||
for key in MKTXPConfigKeys.BOOLEAN_KEYS_NO.union(MKTXPConfigKeys.BOOLEAN_KEYS_YES):
|
|
||||||
if self.config[entry_name].get(key) is not None:
|
|
||||||
config_entry_reader[key] = self.config[entry_name].as_bool(key)
|
|
||||||
else:
|
|
||||||
config_entry_reader[key] = True if key in MKTXPConfigKeys.BOOLEAN_KEYS_YES else False
|
|
||||||
new_keys.append(key) # read from disk next time
|
|
||||||
|
|
||||||
for key in MKTXPConfigKeys.STR_KEYS:
|
|
||||||
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:
|
|
||||||
config_entry_reader[key] = ','.join(config_entry_reader[key])
|
|
||||||
|
|
||||||
for key in MKTXPConfigKeys.INT_KEYS:
|
|
||||||
if self.config[entry_name].get(key):
|
|
||||||
config_entry_reader[key] = self.config[entry_name].as_int(key)
|
|
||||||
else:
|
|
||||||
config_entry_reader[key] = self._default_value_for_key(key)
|
|
||||||
new_keys.append(key) # read from disk next time
|
|
||||||
|
|
||||||
# port
|
|
||||||
if self.config[entry_name].get(MKTXPConfigKeys.PORT_KEY):
|
|
||||||
config_entry_reader[MKTXPConfigKeys.PORT_KEY] = self.config[entry_name].as_int(
|
|
||||||
MKTXPConfigKeys.PORT_KEY)
|
|
||||||
else:
|
|
||||||
config_entry_reader[MKTXPConfigKeys.PORT_KEY] = self._default_value_for_key(
|
|
||||||
MKTXPConfigKeys.SSL_KEY, config_entry_reader[MKTXPConfigKeys.SSL_KEY])
|
|
||||||
new_keys.append(MKTXPConfigKeys.PORT_KEY) # read from disk next time
|
|
||||||
|
|
||||||
if new_keys:
|
|
||||||
self.config[entry_name] = config_entry_reader
|
|
||||||
try:
|
|
||||||
self.config.write()
|
|
||||||
if self._config[MKTXPConfigKeys.MKTXP_CONFIG_ENTRY_NAME].as_bool(MKTXPConfigKeys.MKTXP_VERBOSE_MODE):
|
|
||||||
print(f'Updated router entry {entry_name} with new feature keys {new_keys}')
|
|
||||||
except Exception as exc:
|
|
||||||
print(f'Error updating router entry {entry_name} with new feature keys {new_keys}: {exc}')
|
|
||||||
print('Please update mktxp.conf to its latest version manually')
|
|
||||||
|
|
||||||
return config_entry_reader
|
|
||||||
|
|
||||||
def _system_entry_reader(self):
|
def _system_entry_reader(self):
|
||||||
system_entry_reader = {}
|
system_entry_reader = {}
|
||||||
entry_name = MKTXPConfigKeys.MKTXP_CONFIG_ENTRY_NAME
|
entry_name = MKTXPConfigKeys.MKTXP_CONFIG_ENTRY_NAME
|
||||||
@@ -394,9 +353,115 @@ class MKTXPConfigHandler:
|
|||||||
|
|
||||||
return system_entry_reader
|
return system_entry_reader
|
||||||
|
|
||||||
|
def _config_entry_reader(self, entry_name):
|
||||||
|
config_entry_reader = {}
|
||||||
|
compact_config = self._config[MKTXPConfigKeys.MKTXP_CONFIG_ENTRY_NAME].as_bool(MKTXPConfigKeys.MKTXP_COMPACT_CONFIG)
|
||||||
|
drop_keys = []
|
||||||
|
|
||||||
|
for key in MKTXPConfigKeys.BOOLEAN_KEYS_NO.union(MKTXPConfigKeys.BOOLEAN_KEYS_YES):
|
||||||
|
if self.config[entry_name].get(key) is not None:
|
||||||
|
config_entry_reader[key] = self.config[entry_name].as_bool(key)
|
||||||
|
if compact_config and config_entry_reader[key] == self.default_config_entry_reader[key]:
|
||||||
|
drop_keys.append(key)
|
||||||
|
else:
|
||||||
|
config_entry_reader[key] = self.default_config_entry_reader[key]
|
||||||
|
|
||||||
|
for key in MKTXPConfigKeys.STR_KEYS:
|
||||||
|
if self.config[entry_name].get(key):
|
||||||
|
config_entry_reader[key] = self.config[entry_name].get(key)
|
||||||
|
if key is MKTXPConfigKeys.PASSWD_KEY and type(config_entry_reader[key]) is list:
|
||||||
|
config_entry_reader[key] = ','.join(config_entry_reader[key])
|
||||||
|
|
||||||
|
if compact_config and config_entry_reader[key] == self.default_config_entry_reader[key]:
|
||||||
|
drop_keys.append(key)
|
||||||
|
else:
|
||||||
|
config_entry_reader[key] = self.default_config_entry_reader[key]
|
||||||
|
|
||||||
|
for key in MKTXPConfigKeys.INT_KEYS:
|
||||||
|
if self.config[entry_name].get(key):
|
||||||
|
config_entry_reader[key] = self.config[entry_name].as_int(key)
|
||||||
|
if compact_config and config_entry_reader[key] == self.default_config_entry_reader[key]:
|
||||||
|
drop_keys.append(key)
|
||||||
|
else:
|
||||||
|
config_entry_reader[key] = self.default_config_entry_reader[key]
|
||||||
|
|
||||||
|
# port
|
||||||
|
if self.config[entry_name].get(MKTXPConfigKeys.PORT_KEY):
|
||||||
|
config_entry_reader[MKTXPConfigKeys.PORT_KEY] = self.config[entry_name].as_int(MKTXPConfigKeys.PORT_KEY)
|
||||||
|
if compact_config and config_entry_reader[MKTXPConfigKeys.PORT_KEY] == self.default_config_entry_reader[MKTXPConfigKeys.PORT_KEY]:
|
||||||
|
drop_keys.append(MKTXPConfigKeys.PORT_KEY)
|
||||||
|
else:
|
||||||
|
config_entry_reader[MKTXPConfigKeys.PORT_KEY] = self.default_config_entry_reader[key]
|
||||||
|
|
||||||
|
# If allowed, compact mktxp.conf entry
|
||||||
|
if drop_keys and compact_config:
|
||||||
|
for key in drop_keys:
|
||||||
|
self.config[entry_name].pop(key, None)
|
||||||
|
try:
|
||||||
|
self.config.write()
|
||||||
|
if self._config[MKTXPConfigKeys.MKTXP_CONFIG_ENTRY_NAME].as_bool(MKTXPConfigKeys.MKTXP_VERBOSE_MODE):
|
||||||
|
print(f'compacted router entry {entry_name} for default values of the feature keys {drop_keys}')
|
||||||
|
except Exception as exc:
|
||||||
|
print(f'Error compacting router entry {entry_name} for default values of feature keys {drop_keys}: {exc}')
|
||||||
|
print(f'Error compacting router entry {entry_name} for default values of feature keys {drop_keys}: {exc}')
|
||||||
|
print('Please compact mktxp.conf manually')
|
||||||
|
|
||||||
|
return config_entry_reader
|
||||||
|
|
||||||
|
def _default_config_entry_reader(self):
|
||||||
|
default_config_entry_reader = {}
|
||||||
|
new_keys = []
|
||||||
|
|
||||||
|
if not self.config.get(MKTXPConfigKeys.DEFAULT_ENTRY_KEY):
|
||||||
|
self.config[MKTXPConfigKeys.DEFAULT_ENTRY_KEY] = {}
|
||||||
|
|
||||||
|
for key in MKTXPConfigKeys.BOOLEAN_KEYS_NO.union(MKTXPConfigKeys.BOOLEAN_KEYS_YES):
|
||||||
|
if self.config[MKTXPConfigKeys.DEFAULT_ENTRY_KEY].get(key) is not None:
|
||||||
|
default_config_entry_reader[key] = self.config[MKTXPConfigKeys.DEFAULT_ENTRY_KEY].as_bool(key)
|
||||||
|
else:
|
||||||
|
default_config_entry_reader[key] = True if key in MKTXPConfigKeys.BOOLEAN_KEYS_YES else False
|
||||||
|
new_keys.append(key) # read from disk next time
|
||||||
|
|
||||||
|
for key in MKTXPConfigKeys.STR_KEYS:
|
||||||
|
if self.config[MKTXPConfigKeys.DEFAULT_ENTRY_KEY].get(key):
|
||||||
|
default_config_entry_reader[key] = self.config[MKTXPConfigKeys.DEFAULT_ENTRY_KEY].get(key)
|
||||||
|
else:
|
||||||
|
default_config_entry_reader[key] = self._default_value_for_key(key)
|
||||||
|
new_keys.append(key) # read from disk next time
|
||||||
|
|
||||||
|
for key in MKTXPConfigKeys.INT_KEYS:
|
||||||
|
if self.config[MKTXPConfigKeys.DEFAULT_ENTRY_KEY].get(key):
|
||||||
|
default_config_entry_reader[key] = self.config[MKTXPConfigKeys.DEFAULT_ENTRY_KEY].as_int(key)
|
||||||
|
else:
|
||||||
|
default_config_entry_reader[key] = self._default_value_for_key(key)
|
||||||
|
new_keys.append(key) # read from disk next time
|
||||||
|
|
||||||
|
# port
|
||||||
|
if self.config[MKTXPConfigKeys.DEFAULT_ENTRY_KEY].get(MKTXPConfigKeys.PORT_KEY):
|
||||||
|
default_config_entry_reader[MKTXPConfigKeys.PORT_KEY] = self.config[MKTXPConfigKeys.DEFAULT_ENTRY_KEY].as_int(MKTXPConfigKeys.PORT_KEY)
|
||||||
|
else:
|
||||||
|
default_config_entry_reader[MKTXPConfigKeys.PORT_KEY] = self._default_value_for_key(
|
||||||
|
MKTXPConfigKeys.SSL_KEY, default_config_entry_reader[MKTXPConfigKeys.SSL_KEY])
|
||||||
|
new_keys.append(MKTXPConfigKeys.PORT_KEY) # read from disk next time
|
||||||
|
|
||||||
|
if new_keys:
|
||||||
|
self.config[MKTXPConfigKeys.DEFAULT_ENTRY_KEY] = default_config_entry_reader
|
||||||
|
try:
|
||||||
|
self.config.write()
|
||||||
|
if self._config[MKTXPConfigKeys.MKTXP_CONFIG_ENTRY_NAME].as_bool(MKTXPConfigKeys.MKTXP_VERBOSE_MODE):
|
||||||
|
print(f'Updated default router entry with new feature keys {new_keys}')
|
||||||
|
except Exception as exc:
|
||||||
|
print(f'Error updating default router entry with new feature keys {new_keys}: {exc}')
|
||||||
|
print('Please update mktxp.conf to its latest version manually')
|
||||||
|
|
||||||
|
return default_config_entry_reader
|
||||||
|
|
||||||
def _default_value_for_key(self, key, value=None):
|
def _default_value_for_key(self, key, value=None):
|
||||||
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.HOST_KEY: lambda _: MKTXPConfigKeys.DEFAULT_HOST_KEY,
|
||||||
|
MKTXPConfigKeys.USER_KEY: lambda _: MKTXPConfigKeys.DEFAULT_USER_KEY,
|
||||||
|
MKTXPConfigKeys.PASSWD_KEY: lambda _: MKTXPConfigKeys.DEFAULT_PASSWORD_KEY,
|
||||||
MKTXPConfigKeys.PORT_KEY: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_PORT,
|
MKTXPConfigKeys.PORT_KEY: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_PORT,
|
||||||
MKTXPConfigKeys.FE_REMOTE_DHCP_ENTRY: lambda _: MKTXPConfigKeys.DEFAULT_FE_REMOTE_DHCP_ENTRY,
|
MKTXPConfigKeys.FE_REMOTE_DHCP_ENTRY: lambda _: MKTXPConfigKeys.DEFAULT_FE_REMOTE_DHCP_ENTRY,
|
||||||
MKTXPConfigKeys.MKTXP_SOCKET_TIMEOUT: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_SOCKET_TIMEOUT,
|
MKTXPConfigKeys.MKTXP_SOCKET_TIMEOUT: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_SOCKET_TIMEOUT,
|
||||||
@@ -405,7 +470,6 @@ class MKTXPConfigHandler:
|
|||||||
MKTXPConfigKeys.MKTXP_INC_DIV: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_INC_DIV,
|
MKTXPConfigKeys.MKTXP_INC_DIV: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_INC_DIV,
|
||||||
MKTXPConfigKeys.MKTXP_BANDWIDTH_TEST_INTERVAL: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_BANDWIDTH_TEST_INTERVAL,
|
MKTXPConfigKeys.MKTXP_BANDWIDTH_TEST_INTERVAL: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_BANDWIDTH_TEST_INTERVAL,
|
||||||
MKTXPConfigKeys.MKTXP_MIN_COLLECT_INTERVAL: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_MIN_COLLECT_INTERVAL,
|
MKTXPConfigKeys.MKTXP_MIN_COLLECT_INTERVAL: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_MIN_COLLECT_INTERVAL,
|
||||||
MKTXPConfigKeys.MKTXP_FETCH_IN_PARALLEL: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_FETCH_IN_PARALLEL,
|
|
||||||
MKTXPConfigKeys.MKTXP_MAX_WORKER_THREADS: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_MAX_WORKER_THREADS,
|
MKTXPConfigKeys.MKTXP_MAX_WORKER_THREADS: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_MAX_WORKER_THREADS,
|
||||||
MKTXPConfigKeys.MKTXP_MAX_SCRAPE_DURATION: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_MAX_SCRAPE_DURATION,
|
MKTXPConfigKeys.MKTXP_MAX_SCRAPE_DURATION: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_MAX_SCRAPE_DURATION,
|
||||||
MKTXPConfigKeys.MKTXP_TOTAL_MAX_SCRAPE_DURATION: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_TOTAL_MAX_SCRAPE_DURATION,
|
MKTXPConfigKeys.MKTXP_TOTAL_MAX_SCRAPE_DURATION: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_TOTAL_MAX_SCRAPE_DURATION,
|
||||||
|
|||||||
@@ -12,8 +12,13 @@
|
|||||||
|
|
||||||
|
|
||||||
[Sample-Router]
|
[Sample-Router]
|
||||||
enabled = False # turns metrics collection for this RouterOS device on / off
|
# for specific configuration on the router level, change here the defaults values from below
|
||||||
|
hostname = 192.168.88.1
|
||||||
|
|
||||||
|
[default]
|
||||||
|
# this affects configuration of all routers, unless overloaded on their specific levels
|
||||||
|
|
||||||
|
enabled = True # turns metrics collection for this RouterOS device on / off
|
||||||
hostname = localhost # RouterOS IP address
|
hostname = localhost # RouterOS IP address
|
||||||
port = 8728 # RouterOS IP Port
|
port = 8728 # RouterOS IP Port
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,10 @@
|
|||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pkg_resources
|
|
||||||
from argparse import ArgumentParser, HelpFormatter
|
from argparse import ArgumentParser, HelpFormatter
|
||||||
from mktxp.cli.config.config import config_handler, MKTXPConfigKeys, CustomConfig
|
from mktxp.cli.config.config import config_handler, MKTXPConfigKeys, CustomConfig
|
||||||
from mktxp.utils.utils import FSHelper, UniquePartialMatchList, run_cmd
|
from mktxp.utils.utils import FSHelper, UniquePartialMatchList, run_cmd
|
||||||
|
from importlib.metadata import version as Version
|
||||||
|
|
||||||
class MKTXPCommands:
|
class MKTXPCommands:
|
||||||
INFO = 'info'
|
INFO = 'info'
|
||||||
@@ -41,7 +40,7 @@ class MKTXPOptionsParser:
|
|||||||
'''
|
'''
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._script_name = f'MKTXP'
|
self._script_name = f'MKTXP'
|
||||||
version = pkg_resources.require("mktxp")[0].version
|
version = Version('mktxp')
|
||||||
self._description = \
|
self._description = \
|
||||||
f'''
|
f'''
|
||||||
Prometheus Exporter for Mikrotik RouterOS, version {version}
|
Prometheus Exporter for Mikrotik RouterOS, version {version}
|
||||||
@@ -232,7 +231,7 @@ Selected metrics info can be printed on the command line. For more information,
|
|||||||
return editor
|
return editor
|
||||||
|
|
||||||
commands = ['which nano', 'which vi', 'which vim']
|
commands = ['which nano', 'which vi', 'which vim']
|
||||||
quiet = not config_handler.system_entry().verbose_mode
|
quiet = not config_handler.system_entry.verbose_mode
|
||||||
for command in commands:
|
for command in commands:
|
||||||
editor = run_cmd(command, quiet = quiet).rstrip()
|
editor = run_cmd(command, quiet = quiet).rstrip()
|
||||||
if editor:
|
if editor:
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class BandwidthCollector(BaseCollector):
|
|||||||
self.last_call_timestamp = 0
|
self.last_call_timestamp = 0
|
||||||
|
|
||||||
def collect(self):
|
def collect(self):
|
||||||
if not config_handler.system_entry().bandwidth:
|
if not config_handler.system_entry.bandwidth:
|
||||||
return
|
return
|
||||||
|
|
||||||
if result_list:
|
if result_list:
|
||||||
@@ -49,7 +49,7 @@ class BandwidthCollector(BaseCollector):
|
|||||||
yield latency_metrics
|
yield latency_metrics
|
||||||
|
|
||||||
ts = datetime.now().timestamp()
|
ts = datetime.now().timestamp()
|
||||||
if (ts - self.last_call_timestamp) > config_handler.system_entry().bandwidth_test_interval:
|
if (ts - self.last_call_timestamp) > config_handler.system_entry.bandwidth_test_interval:
|
||||||
self.pool.apply_async(BandwidthCollector.bandwidth_worker, callback=get_result)
|
self.pool.apply_async(BandwidthCollector.bandwidth_worker, callback=get_result)
|
||||||
self.last_call_timestamp = ts
|
self.last_call_timestamp = ts
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class CollectorHandler:
|
|||||||
|
|
||||||
# overall scrape duration
|
# overall scrape duration
|
||||||
total_scrape_timeout_event = Event()
|
total_scrape_timeout_event = Event()
|
||||||
total_scrape_timer = Timer(config_handler.system_entry().total_max_scrape_duration, timeout, args=(total_scrape_timeout_event,))
|
total_scrape_timer = Timer(config_handler.system_entry.total_max_scrape_duration, timeout, args=(total_scrape_timeout_event,))
|
||||||
total_scrape_timer.start()
|
total_scrape_timer.start()
|
||||||
|
|
||||||
with ThreadPoolExecutor(max_workers=max_worker_threads) as executor:
|
with ThreadPoolExecutor(max_workers=max_worker_threads) as executor:
|
||||||
@@ -94,7 +94,7 @@ class CollectorHandler:
|
|||||||
|
|
||||||
# Duration of individual scrapes
|
# Duration of individual scrapes
|
||||||
scrape_timeout_event = Event()
|
scrape_timeout_event = Event()
|
||||||
scrape_timer = Timer(config_handler.system_entry().max_scrape_duration, timeout, args=(scrape_timeout_event,))
|
scrape_timer = Timer(config_handler.system_entry.max_scrape_duration, timeout, args=(scrape_timeout_event,))
|
||||||
scrape_timer.start()
|
scrape_timer.start()
|
||||||
|
|
||||||
futures[executor.submit(self.collect_router_entry_async, router_entry, scrape_timeout_event, total_scrape_timeout_event)] = scrape_timer
|
futures[executor.submit(self.collect_router_entry_async, router_entry, scrape_timeout_event, total_scrape_timeout_event)] = scrape_timer
|
||||||
@@ -117,8 +117,8 @@ class CollectorHandler:
|
|||||||
|
|
||||||
# all other collectors
|
# all other collectors
|
||||||
# Check whether to run in parallel by looking at the mktxp system configuration
|
# Check whether to run in parallel by looking at the mktxp system configuration
|
||||||
parallel = config_handler.system_entry().fetch_routers_in_parallel
|
parallel = config_handler.system_entry.fetch_routers_in_parallel
|
||||||
max_worker_threads = config_handler.system_entry().max_worker_threads
|
max_worker_threads = config_handler.system_entry.max_worker_threads
|
||||||
if parallel:
|
if parallel:
|
||||||
yield from self.collect_async(max_worker_threads=max_worker_threads)
|
yield from self.collect_async(max_worker_threads=max_worker_threads)
|
||||||
else:
|
else:
|
||||||
@@ -128,9 +128,9 @@ class CollectorHandler:
|
|||||||
def _valid_collect_interval(self):
|
def _valid_collect_interval(self):
|
||||||
now = datetime.now().timestamp()
|
now = datetime.now().timestamp()
|
||||||
diff = now - self.last_collect_timestamp
|
diff = now - self.last_collect_timestamp
|
||||||
if diff < config_handler.system_entry().minimal_collect_interval:
|
if diff < config_handler.system_entry.minimal_collect_interval:
|
||||||
if config_handler.system_entry().verbose_mode:
|
if config_handler.system_entry.verbose_mode:
|
||||||
print(f'An attemp to collect metrics within minimal metrics collection interval: {diff} < {config_handler.system_entry().minimal_collect_interval}')
|
print(f'An attemp to collect metrics within minimal metrics collection interval: {diff} < {config_handler.system_entry.minimal_collect_interval}')
|
||||||
print('deferring..')
|
print('deferring..')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ class ExportProcessor:
|
|||||||
def start():
|
def start():
|
||||||
REGISTRY.register(CollectorHandler(RouterEntriesHandler(), CollectorRegistry()))
|
REGISTRY.register(CollectorHandler(RouterEntriesHandler(), CollectorRegistry()))
|
||||||
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
print(f'{current_time} Running HTTP metrics server on: {config_handler.system_entry().listen}')
|
print(f'{current_time} Running HTTP metrics server on: {config_handler.system_entry.listen}')
|
||||||
serve(make_wsgi_app(), listen = config_handler.system_entry().listen)
|
serve(make_wsgi_app(), listen = config_handler.system_entry.listen)
|
||||||
|
|
||||||
class OutputProcessor:
|
class OutputProcessor:
|
||||||
''' Base CLI Processing
|
''' Base CLI Processing
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class RouterAPIConnection:
|
|||||||
ssl_verify = self.config_entry.ssl_certificate_verify,
|
ssl_verify = self.config_entry.ssl_certificate_verify,
|
||||||
ssl_context = ctx)
|
ssl_context = ctx)
|
||||||
|
|
||||||
self.connection.socket_timeout = config_handler.system_entry().socket_timeout
|
self.connection.socket_timeout = config_handler.system_entry.socket_timeout
|
||||||
self.api = None
|
self.api = None
|
||||||
|
|
||||||
def is_connected(self):
|
def is_connected(self):
|
||||||
@@ -92,11 +92,11 @@ class RouterAPIConnection:
|
|||||||
def _in_connect_timeout(self, connect_timestamp):
|
def _in_connect_timeout(self, connect_timestamp):
|
||||||
connect_delay = self._connect_delay()
|
connect_delay = self._connect_delay()
|
||||||
if (connect_timestamp - self.last_failure_timestamp) < connect_delay:
|
if (connect_timestamp - self.last_failure_timestamp) < connect_delay:
|
||||||
if config_handler.system_entry().verbose_mode:
|
if config_handler.system_entry.verbose_mode:
|
||||||
print(f'{self.router_name}@{self.config_entry.hostname}: in connect timeout, {int(connect_delay - (connect_timestamp - self.last_failure_timestamp))}secs remaining')
|
print(f'{self.router_name}@{self.config_entry.hostname}: in connect timeout, {int(connect_delay - (connect_timestamp - self.last_failure_timestamp))}secs remaining')
|
||||||
print(f'Successive failure count: {self.successive_failure_count}')
|
print(f'Successive failure count: {self.successive_failure_count}')
|
||||||
return True
|
return True
|
||||||
if config_handler.system_entry().verbose_mode:
|
if config_handler.system_entry.verbose_mode:
|
||||||
print(f'{self.router_name}@{self.config_entry.hostname}: OK to connect')
|
print(f'{self.router_name}@{self.config_entry.hostname}: OK to connect')
|
||||||
if self.last_failure_timestamp > 0:
|
if self.last_failure_timestamp > 0:
|
||||||
print(f'Seconds since last failure: {connect_timestamp - self.last_failure_timestamp}')
|
print(f'Seconds since last failure: {connect_timestamp - self.last_failure_timestamp}')
|
||||||
@@ -104,7 +104,7 @@ class RouterAPIConnection:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def _connect_delay(self):
|
def _connect_delay(self):
|
||||||
mktxp_entry = config_handler.system_entry()
|
mktxp_entry = config_handler.system_entry
|
||||||
connect_delay = (1 + self.successive_failure_count / mktxp_entry.delay_inc_div) * mktxp_entry.initial_delay_on_failure
|
connect_delay = (1 + self.successive_failure_count / mktxp_entry.delay_inc_div) * mktxp_entry.initial_delay_on_failure
|
||||||
return connect_delay if connect_delay < mktxp_entry.max_delay_on_failure else mktxp_entry.max_delay_on_failure
|
return connect_delay if connect_delay < mktxp_entry.max_delay_on_failure else mktxp_entry.max_delay_on_failure
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user