Skip to content

Commit c865c75

Browse files
committed
Consistent Interface Name Formatting, #176 #54
1 parent 9d1563b commit c865c75

14 files changed

Lines changed: 162 additions & 46 deletions

File tree

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,10 @@ The default configuration file comes with a sample configuration, making it easy
138138
remote_dhcp_entry = None # An MKTXP entry to provide for remote DHCP info / resolution
139139
remote_capsman_entry = None # An MKTXP entry to provide for remote capsman info
140140
141-
use_comments_over_names = True # when available, forces using comments over the interfaces names
141+
interface_name_format = name # Format to use for interface / resource names, allowed values: 'name', 'comment', or 'combined'
142+
# 'name': use interface name only (e.g. 'ether1')
143+
# 'comment': use comment if available, fallback to name if not
144+
# 'combined': use both (e.g. 'ether1 (Office Switch)')
142145
check_for_updates = False # check for available ROS updates
143146
```
144147

deploy/kubernetes/secret.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ stringData:
136136
remote_dhcp_entry = None # An MKTXP entry to provide for remote DHCP info / resolution
137137
remote_capsman_entry = None # An MKTXP entry to provide for remote capsman info
138138
139-
use_comments_over_names = True # when available, forces using comments over the interfaces names
139+
interface_name_format = name # Format to use for interface / resource names, allowed values: 'name', 'comment', or 'combined'
140+
# 'name': use interface name only (e.g. 'ether1')
141+
# 'comment': use comment if available, fallback to name if not
142+
# 'combined': use both (e.g. 'ether1 (Office Switch)')
140143
check_for_updates = False # check for available ROS updates
141144

mktxp/cli/config/config.py

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ class MKTXPConfigKeys:
160160
# UnRegistered entries placeholder
161161
NO_ENTRIES_REGISTERED = 'NoEntriesRegistered'
162162

163-
MKTXP_USE_COMMENTS_OVER_NAMES = 'use_comments_over_names'
163+
MKTXP_USE_COMMENTS_OVER_NAMES = 'use_comments_over_names' # Legacy option, deprecated
164+
FE_INTERFACE_NAME_FORMAT = 'interface_name_format'
164165

165166
# Base router id labels
166167
ROUTERBOARD_NAME = 'routerboard_name'
@@ -184,6 +185,7 @@ class MKTXPConfigKeys:
184185
DEFAULT_FE_ADDRESS_LIST_KEY = 'None'
185186
DEFAULT_FE_IPV6_ADDRESS_LIST_KEY = 'None'
186187
DEFAULT_FE_CUSTOM_LABELS_KEY = 'None'
188+
DEFAULT_FE_INTERFACE_NAME_FORMAT = 'name'
187189

188190
DEFAULT_MKTXP_PORT = 49090
189191
DEFAULT_MKTXP_SOCKET_TIMEOUT = 2
@@ -204,14 +206,14 @@ class MKTXPConfigKeys:
204206

205207
# Feature keys enabled by default
206208
BOOLEAN_KEYS_YES = {PLAINTEXT_LOGIN_KEY, FE_DHCP_KEY, FE_HEALTH_KEY, FE_PACKAGE_KEY, FE_DHCP_LEASE_KEY, FE_IP_CONNECTIONS_KEY, FE_INTERFACE_KEY,
207-
FE_ROUTE_KEY, FE_DHCP_POOL_KEY, FE_FIREWALL_KEY, FE_NEIGHBOR_KEY, FE_MONITOR_KEY, SSL_CHECK_HOSTNAME, MKTXP_USE_COMMENTS_OVER_NAMES,
209+
FE_ROUTE_KEY, FE_DHCP_POOL_KEY, FE_FIREWALL_KEY, FE_NEIGHBOR_KEY, FE_MONITOR_KEY, SSL_CHECK_HOSTNAME,
208210
FE_WIRELESS_KEY, FE_WIRELESS_CLIENTS_KEY, FE_CAPSMAN_KEY, FE_CAPSMAN_CLIENTS_KEY, FE_POE_KEY,
209211
FE_NETWATCH_KEY, FE_PUBLIC_IP_KEY, FE_USER_KEY, FE_QUEUE_KEY}
210212

211213
SYSTEM_BOOLEAN_KEYS_YES = {MKTXP_PERSISTENT_ROUTER_CONNECTION_POOL, MKTXP_PERSISTENT_DHCP_CACHE}
212214
SYSTEM_BOOLEAN_KEYS_NO = {MKTXP_BANDWIDTH_KEY, MKTXP_VERBOSE_MODE, MKTXP_FETCH_IN_PARALLEL, MKTXP_COMPACT_CONFIG, MKTXP_PROMETHEUS_HEADERS_DEDUPLICATION}
213215

214-
STR_KEYS = (HOST_KEY, USER_KEY, PASSWD_KEY, CREDENTIALS_FILE_KEY, SSL_CA_FILE, FE_REMOTE_DHCP_ENTRY, FE_REMOTE_CAPSMAN_ENTRY, FE_ADDRESS_LIST_KEY, FE_IPV6_ADDRESS_LIST_KEY, FE_CUSTOM_LABELS_KEY)
216+
STR_KEYS = (HOST_KEY, USER_KEY, PASSWD_KEY, CREDENTIALS_FILE_KEY, SSL_CA_FILE, FE_REMOTE_DHCP_ENTRY, FE_REMOTE_CAPSMAN_ENTRY, FE_ADDRESS_LIST_KEY, FE_IPV6_ADDRESS_LIST_KEY, FE_CUSTOM_LABELS_KEY, FE_INTERFACE_NAME_FORMAT)
215217
MKTXP_STR_KEYS = (MKTXP_BANDWIDTH_TEST_DNS_SERVER,)
216218
INT_KEYS = ()
217219
MKTXP_INT_KEYS = (PORT_KEY, MKTXP_SOCKET_TIMEOUT, MKTXP_INITIAL_DELAY, MKTXP_MAX_DELAY,
@@ -232,7 +234,7 @@ class ConfigEntry:
232234
MKTXPConfigKeys.FE_DHCP_KEY, MKTXPConfigKeys.FE_HEALTH_KEY, MKTXPConfigKeys.FE_PACKAGE_KEY, MKTXPConfigKeys.FE_DHCP_LEASE_KEY, MKTXPConfigKeys.FE_INTERFACE_KEY,
233235
MKTXPConfigKeys.FE_MONITOR_KEY, MKTXPConfigKeys.FE_W60G_KEY, MKTXPConfigKeys.FE_WIRELESS_KEY, MKTXPConfigKeys.FE_WIRELESS_CLIENTS_KEY,
234236
MKTXPConfigKeys.FE_IP_CONNECTIONS_KEY, MKTXPConfigKeys.FE_CONNECTION_STATS_KEY, MKTXPConfigKeys.FE_CAPSMAN_KEY, MKTXPConfigKeys.FE_CAPSMAN_CLIENTS_KEY, MKTXPConfigKeys.FE_POE_KEY,
235-
MKTXPConfigKeys.FE_NETWATCH_KEY, MKTXPConfigKeys.MKTXP_USE_COMMENTS_OVER_NAMES, MKTXPConfigKeys.FE_PUBLIC_IP_KEY,
237+
MKTXPConfigKeys.FE_NETWATCH_KEY, MKTXPConfigKeys.FE_INTERFACE_NAME_FORMAT, MKTXPConfigKeys.FE_PUBLIC_IP_KEY,
236238
MKTXPConfigKeys.FE_ROUTE_KEY, MKTXPConfigKeys.FE_DHCP_POOL_KEY, MKTXPConfigKeys.FE_FIREWALL_KEY, MKTXPConfigKeys.FE_ADDRESS_LIST_KEY, MKTXPConfigKeys.FE_NEIGHBOR_KEY, MKTXPConfigKeys.FE_DNS_KEY,
237239
MKTXPConfigKeys.FE_IPV6_ROUTE_KEY, MKTXPConfigKeys.FE_IPV6_DHCP_POOL_KEY, MKTXPConfigKeys.FE_IPV6_FIREWALL_KEY, MKTXPConfigKeys.FE_IPV6_ADDRESS_LIST_KEY, MKTXPConfigKeys.FE_IPV6_NEIGHBOR_KEY,
238240
MKTXPConfigKeys.FE_USER_KEY, MKTXPConfigKeys.FE_QUEUE_KEY, MKTXPConfigKeys.FE_REMOTE_DHCP_ENTRY, MKTXPConfigKeys.FE_REMOTE_CAPSMAN_ENTRY, MKTXPConfigKeys.FE_CHECK_FOR_UPDATES, MKTXPConfigKeys.FE_BFD_KEY, MKTXPConfigKeys.FE_BGP_KEY,
@@ -531,11 +533,43 @@ def _config_entry_reader(self, entry_name):
531533
def _default_config_entry_reader(self):
532534
default_config_entry_reader = {}
533535
new_keys, new_keys_values = [], {}
536+
537+
# Track if the section was created in this run
538+
created_latest_section = False
534539

535540
if not self.config.get(MKTXPConfigKeys.DEFAULT_ENTRY_KEY):
536541
self.config[MKTXPConfigKeys.DEFAULT_ENTRY_KEY] = {}
537542
if not self.config.get(MKTXPConfigKeys.MKTXP_LATEST_DEFAULT_ENTRY_KEY):
538543
self.config[MKTXPConfigKeys.MKTXP_LATEST_DEFAULT_ENTRY_KEY] = {}
544+
created_latest_section = True
545+
546+
# Migrate legacy use_comments_over_names to interface_name_format FIRST
547+
# This ensures the migrated value is available for the normal config processing below
548+
migrated_entries = []
549+
for entry_name in list(self.config.keys()):
550+
if entry_name == MKTXPConfigKeys.MKTXP_LATEST_DEFAULT_ENTRY_KEY:
551+
continue
552+
if self.config[entry_name].get(MKTXPConfigKeys.MKTXP_USE_COMMENTS_OVER_NAMES) is not None:
553+
# Migrate the legacy option
554+
legacy_value = self.config[entry_name].as_bool(MKTXPConfigKeys.MKTXP_USE_COMMENTS_OVER_NAMES)
555+
new_value = 'comment' if legacy_value else 'name'
556+
self.config[entry_name][MKTXPConfigKeys.FE_INTERFACE_NAME_FORMAT] = new_value
557+
# Remove the legacy key
558+
self.config[entry_name].pop(MKTXPConfigKeys.MKTXP_USE_COMMENTS_OVER_NAMES, None)
559+
migrated_entries.append(entry_name)
560+
561+
if migrated_entries:
562+
# Remove empty new_default_parameters section if it exists
563+
if self.config.get(MKTXPConfigKeys.MKTXP_LATEST_DEFAULT_ENTRY_KEY) and \
564+
len(self.config[MKTXPConfigKeys.MKTXP_LATEST_DEFAULT_ENTRY_KEY]) == 0:
565+
del self.config[MKTXPConfigKeys.MKTXP_LATEST_DEFAULT_ENTRY_KEY]
566+
567+
try:
568+
self.config.write()
569+
print(f'Migrated use_comments_over_names to interface_name_format for entries: {", ".join(migrated_entries)}')
570+
except Exception as exc:
571+
print(f'Error migrating use_comments_over_names to interface_name_format: {exc}')
572+
print('Please update mktxp.conf manually')
539573

540574
for key in MKTXPConfigKeys.BOOLEAN_KEYS_NO.union(MKTXPConfigKeys.BOOLEAN_KEYS_YES):
541575
if self.config[MKTXPConfigKeys.DEFAULT_ENTRY_KEY].get(key) is not None:
@@ -590,6 +624,12 @@ def _default_config_entry_reader(self):
590624
except Exception as exc:
591625
print(f'Error updating default router entry with new feature keys {new_keys}: {exc}')
592626
print('Please update mktxp.conf to its latest version manually')
627+
else:
628+
# Only clean up if the section was created and is now empty after migration
629+
if created_latest_section and \
630+
self.config.get(MKTXPConfigKeys.MKTXP_LATEST_DEFAULT_ENTRY_KEY) is not None and \
631+
len(self.config[MKTXPConfigKeys.MKTXP_LATEST_DEFAULT_ENTRY_KEY]) == 0:
632+
del self.config[MKTXPConfigKeys.MKTXP_LATEST_DEFAULT_ENTRY_KEY]
593633

594634
return default_config_entry_reader
595635

@@ -607,6 +647,7 @@ def _default_value_for_key(self, key, value=None):
607647
MKTXPConfigKeys.FE_REMOTE_CAPSMAN_ENTRY: lambda _: MKTXPConfigKeys.DEFAULT_FE_REMOTE_CAPSMAN_ENTRY,
608648
MKTXPConfigKeys.FE_ADDRESS_LIST_KEY: lambda _: MKTXPConfigKeys.DEFAULT_FE_ADDRESS_LIST_KEY,
609649
MKTXPConfigKeys.FE_IPV6_ADDRESS_LIST_KEY: lambda _: MKTXPConfigKeys.DEFAULT_FE_IPV6_ADDRESS_LIST_KEY,
650+
MKTXPConfigKeys.FE_INTERFACE_NAME_FORMAT: lambda _: MKTXPConfigKeys.DEFAULT_FE_INTERFACE_NAME_FORMAT,
610651
MKTXPConfigKeys.MKTXP_SOCKET_TIMEOUT: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_SOCKET_TIMEOUT,
611652
MKTXPConfigKeys.MKTXP_INITIAL_DELAY: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_INITIAL_DELAY,
612653
MKTXPConfigKeys.MKTXP_MAX_DELAY: lambda _: MKTXPConfigKeys.DEFAULT_MKTXP_MAX_DELAY,

mktxp/cli/config/mktxp.conf

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,8 @@
9191
remote_dhcp_entry = None # An MKTXP entry to provide for remote DHCP info / resolution
9292
remote_capsman_entry = None # An MKTXP entry to provide for remote capsman info
9393

94-
use_comments_over_names = True # when available, forces using comments over the interfaces names
94+
interface_name_format = name # Format to use for interface / resource names, allowed values: 'name', 'comment', or 'combined'
95+
# 'name': use interface name only (e.g. 'ether1')
96+
# 'comment': use comment if available, fallback to name if not
97+
# 'combined': use both (e.g. 'ether1 (Office Switch)')
9598
check_for_updates = False # check for available ROS updates

mktxp/collector/monitor_collector.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ def collect(router_entry):
6262
monitor_records = InterfaceMonitorMetricsDataSource.metric_records(
6363
router_entry,
6464
metric_labels=monitor_labels,
65-
translation_table=translation_table,
66-
include_comments=True
65+
translation_table=translation_table
6766
)
6867

6968
if not monitor_records:

mktxp/collector/poe_collector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def collect(router_entry):
2525
return
2626

2727
poe_labels = ['name', 'poe_out', 'poe_priority', 'poe_voltage', 'poe_out_status', 'poe_out_voltage', 'poe_out_current', 'poe_out_power']
28-
poe_records = POEMetricsDataSource.metric_records(router_entry, include_comments = True, metric_labels = poe_labels)
28+
poe_records = POEMetricsDataSource.metric_records(router_entry, metric_labels = poe_labels)
2929

3030
if poe_records:
3131
poe_info_labels = ['name', 'poe_out', 'poe_priority', 'poe_voltage', 'poe_out_status']

mktxp/collector/w60g_collector.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ def collect(router_entry):
5353
metric_labels=monitor_labels,
5454
translation_table=translation_table,
5555
kind='w60g',
56-
include_comments=True,
5756
running_only=False
5857
)
5958

mktxp/datasource/container_ds.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414

1515
from mktxp.datasource.base_ds import BaseDSProcessor
16+
from mktxp.flow.processor.output import BaseOutputProcessor
1617

1718

1819
class ContainerDataSource:
@@ -26,7 +27,12 @@ def metric_records(router_entry, metric_labels):
2627
router_records = router_entry.api_connection.router_api().get_resource(f'/container').get()
2728
for record in router_records:
2829
if 'comment' in record:
29-
record['name'] = record['comment']
30+
# Format name with comment using centralized function
31+
record['name'] = BaseOutputProcessor.format_interface_name(
32+
record['name'],
33+
record['comment'],
34+
router_entry.config_entry.interface_name_format
35+
)
3036
return BaseDSProcessor.trimmed_records(router_entry, router_records=router_records, metric_labels=metric_labels)
3137
except Exception as exc:
3238
print(f'Error getting Neighbors info from router {router_entry.router_name}@{router_entry.config_entry.hostname}: {exc}')

mktxp/datasource/interface_ds.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@
1515
from mktxp.datasource.base_ds import BaseDSProcessor
1616
from mktxp.datasource.system_resource_ds import SystemResourceMetricsDataSource
1717
from mktxp.utils.utils import routerOS7_version
18+
from mktxp.flow.processor.output import BaseOutputProcessor
1819

1920
class BaseInterfaceDataSource:
2021
@staticmethod
2122
def rewrite_interface_names(router_entry, metric_records):
2223
for metric_record in metric_records:
2324
if metric_record.get('comment'):
24-
if router_entry.config_entry.use_comments_over_names:
25-
metric_record['name'] = metric_record['comment']
26-
else:
27-
metric_record['name'] = f"{metric_record['name']} ({metric_record['comment']})"
25+
metric_record['name'] = BaseOutputProcessor.format_interface_name(
26+
metric_record['name'],
27+
metric_record['comment'],
28+
router_entry.config_entry.interface_name_format
29+
)
2830

2931
return metric_records
3032

@@ -94,7 +96,7 @@ class InterfaceMonitorMetricsDataSource:
9496
""" Interface Monitor Metrics data provider
9597
"""
9698
@staticmethod
97-
def metric_records(router_entry, *, metric_labels = None, translation_table = None, kind = 'ethernet', include_comments = False, running_only = True):
99+
def metric_records(router_entry, *, metric_labels = None, translation_table = None, kind = 'ethernet', running_only = True):
98100
if metric_labels is None:
99101
metric_labels = []
100102

@@ -115,10 +117,14 @@ def metric_records(router_entry, *, metric_labels = None, translation_table = No
115117
# unless explicitly requested, no need to do a monitor call for not running interfaces
116118
interface_monitor_record = {'name': interface['name'], 'status': 'no-link'}
117119

118-
if include_comments and interface.get('comment'):
119-
# combines names with comments
120-
interface_monitor_record['name'] = interface['comment'] if router_entry.config_entry.use_comments_over_names else \
121-
f"{interface['name']} ({interface['comment']})"
120+
# Apply interface name formatting based on config
121+
if interface.get('comment'):
122+
# Format name with comment using centralized function
123+
interface_monitor_record['name'] = BaseOutputProcessor.format_interface_name(
124+
interface['name'],
125+
interface['comment'],
126+
router_entry.config_entry.interface_name_format
127+
)
122128
interface_monitor_record.setdefault('name', interface['name'])
123129
interface_monitor_records.append(interface_monitor_record)
124130

mktxp/datasource/ipsec_ds.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414

1515
from mktxp.datasource.base_ds import BaseDSProcessor
16+
from mktxp.flow.processor.output import BaseOutputProcessor
1617

1718

1819
class IPSecMetricsDataSource:
@@ -25,9 +26,13 @@ def metric_records(router_entry, *, metric_labels=None, translation_table=None):
2526
try:
2627
ipsec_records = router_entry.api_connection.router_api().get_resource('/ip/ipsec/active-peers').call('print', {'stats': ''})
2728
for record in ipsec_records:
28-
# The comment for active peers is the name from the peer
29+
# Format name with comment using centralized function
2930
if 'comment' in record:
30-
record['name'] = record['comment']
31+
record['name'] = BaseOutputProcessor.format_interface_name(
32+
record['name'],
33+
record['comment'],
34+
router_entry.config_entry.interface_name_format
35+
)
3136

3237
return BaseDSProcessor.trimmed_records(router_entry, router_records=ipsec_records,
3338
metric_labels=metric_labels, translation_table=translation_table)

0 commit comments

Comments
 (0)