diff --git a/README.md b/README.md index 0e0a0cd16e82639c875bde320b281b0756ca9aa7..567c5c330c9df39d40d5c38b9ceef4a44bb8351b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[PACKAGE]: ../../raw/master/mkp/nvdct-0.9.1-20241110.mkp "nvdct-0.9.1-20241110.mkp" +[PACKAGE]: ../../raw/master/mkp/nvdct-0.9.2-20241116.mkp "nvdct-0.9.2-20241116.mkp" # Network Visualization Data Creation Tool (NVDCT) This script creates the topology data file needed for the [Checkmk Exchange Network visualization](https://exchange.checkmk.com/p/network-visualization) plugin.\ diff --git a/mkp/nvdct-0.9.2-20241116.mkp b/mkp/nvdct-0.9.2-20241116.mkp new file mode 100644 index 0000000000000000000000000000000000000000..ba44fa941c1816075850cd9cd46d7d144127ccf4 Binary files /dev/null and b/mkp/nvdct-0.9.2-20241116.mkp differ diff --git a/source/bin/nvdct/conf/nvdct.toml b/source/bin/nvdct/conf/nvdct.toml index 48d787bc9502e2280b76208eab3e784f90a20f8e..b5632b5aa521ef87764297fb97eafa9676ec3e06 100755 --- a/source/bin/nvdct/conf/nvdct.toml +++ b/source/bin/nvdct/conf/nvdct.toml @@ -13,23 +13,18 @@ # # list of (additional to -s/--seed-devices) seed devices -SEED_DEVICES = [ +L2_SEED_DEVICES = [ # "CORE01", # "LOCATION01", # "LOCATION02", ] # drop neighbours with invalid names (only L2 Topologies (i.e. CDP, LLDP, CUSTOM) -DROP_HOSTS = [ +L2_DROP_HOSTS = [ # "not advertised", # "a nother invalid name", ] -# drop neighbours with invalid names by regex (only L2 Topologies (i.e. CDP, LLDP, CUSTOM) -DROP_HOSTS_REGEX = [ - # "^(([0-9a-fA-F]){2}[:.-]?){5}([0-9a-fA-F]){2}$", -] - # hosts will be ignored in L3v4 topology L3V4_IGNORE_HOSTS = [ # "host1", @@ -69,7 +64,7 @@ PROTECTED_TOPOLOGIES = [ ] # user defined static connections -# connections will be added from host to neighbour and in reverese +# these connections will be added from host to neighbour and in reverese # hosts/neighbours in this section will be added to SEED_DEVICES STATIC_CONNECTIONS = [ # ["cmk_host1", "local-port1", "neighbour-port1", "neighbour1", "label"], @@ -84,38 +79,39 @@ CUSTOM_LAYERS = [ # { path = "networking,cdp_cache,neighbours", columns = "neighbour_name,local_port,neighbour_port", label = "custom_CDP", host_label = "nvdct/has_cdp_neighbours" }, ] -# list site so include/excluse, use option --filter-sites INCLUDE/EXCLUDE -SITES = [ - # "site1", - # "site2", - # "site3", -] - -# list customers so include/excluse, use option --filter-costumers INCLUDE/EXCLUDE +# list customers so include/excluse, use option --filter-costumers INCLUDE/EXCLUDE CUSTOMERS = [ # "customer1", # "customer2", # "customer3", ] -[MAP_SPEED_TO_THICKNESS] -# must be sorted from slower to faster speed -# use only one entry to have all conections with the same thickness -# bits per second = thickness -# 2000000 = 1 # 2 mbit -# 5000000 = 2 # 5 mbit -# 1e7 = 3 # 10 mbit -# 51e7 = 4 # 51 mbit -1e8 = 1 # 100 mbit -1e9 = 3 # 1 gbit -1e10 = 5 # 10 gbit +# list site so include/excluse, use option --filter-sites INCLUDE/EXCLUDE +SITES = [ + # "site1", + # "site2", + # "site3", +] # map inventory neighbour name to Checkmk host name -[HOST_MAP] +[L2_HOST_MAP] # inventory_neighbour1 = "cmk_host1" # inventory_neighbour2 = "cmk_host2" # inventory_neighbour3 = "cmk_host3" +[L2_NEIGHBOUR_REPLACE_REGEX] +# "regex string to replace" = "string to replace with" +# "^(([0-9a-fA-F]){2}[:.-]?){5}([0-9a-fA-F]){2}$" = "" +# "\\([0-9a-zA-Z]+\\)$" = "" +# "^Meraki.*\\s-\\s" = "" + +# replace network objects (takes place after summarize) +[L3V4_REPLACE] +# "10.193.172.0/24" = "MPLS" +# "10.194.8.0/23" = "MPLS" +# "10.194.12.0/24" = "MPLS" +# "10.194.115.0/24" = "MPLS" + [EMBLEMS] # can use misc icons from CMK or upload your own in the misc category # for built-in icons use "icon_" as prefix to the name from CMK @@ -127,12 +123,17 @@ CUSTOMERS = [ # "l3v4_summarize" = "icon_aggr" # "service_node" = "icon_missing" -# replace network objects (takes place after summarize) -[L3V4_REPLACE] -# "10.193.172.0/24" = "MPLS" -# "10.194.8.0/23" = "MPLS" -# "10.194.12.0/24" = "MPLS" -# "10.194.115.0/24" = "MPLS" +[MAP_SPEED_TO_THICKNESS] +# must be sorted from slower to faster speed +# use only one entry to have all conections with the same thickness +# bits per second = thickness +# 2000000 = 1 # 2 mbit +# 5000000 = 2 # 5 mbit +# 1e7 = 3 # 10 mbit +# 51e7 = 4 # 51 mbit +1e8 = 1 # 100 mbit +1e9 = 3 # 1 gbit +1e10 = 5 # 10 gbit [SETTINGS] # api_port = 80 @@ -143,7 +144,6 @@ CUSTOMERS = [ # filter_customers = "INCLUDE" |"EXCLUDE" # filter_sites = "INCLUDE" | "EXCLUDE" # keep = 0 -# keep_domain = false # layers = ["LLDP", "CDP", "STATIC", "CUSTOM", "L3v4"] # log_file = "~/var/log/nvdct.log" # log_level = "WARNING" @@ -153,6 +153,7 @@ CUSTOMERS = [ # pre_fetch = false # prefix = "" # quiet = true +# remove_domain = false # skip_l3_if = false # skip_l3_ip = false # time_format = "%Y-%m-%dT%H:%M:%S.%m" diff --git a/source/bin/nvdct/lib/args.py b/source/bin/nvdct/lib/args.py index 080a0758e7f9aacfb4e3f50112f6cb852d996660..abd5472d8a45408a84eab7de829f74ab689338f2 100755 --- a/source/bin/nvdct/lib/args.py +++ b/source/bin/nvdct/lib/args.py @@ -14,7 +14,7 @@ # -l --layer # -o --output-directory # -p --prefix -# -s --seed-devices +# # -s --seed-devices # -u --user-data-file # -v --version # --api-port (deprecated ?) @@ -24,13 +24,13 @@ # --filter-customers # --filter-sites # --keep -# --keep-domain # --log-file # --log-level # --log-to-stdout # --min-age # --pre-fetch # --quiet +# --remove-domain # --skip-l3-if # --skip-l3-ip # --time-format @@ -50,7 +50,7 @@ from lib.utils import ( MIN_LLDP_VERSION, MIN_IPV4_ADDRESSES, NVDCT_VERSION, - SAMPLE_SEEDS, + # SAMPLE_SEEDS, SCRIPT, TIME_FORMAT_ARGPARSER, USER_DATA_FILE, @@ -83,7 +83,7 @@ def parse_arguments() -> arg_Namespace: f' {ExitCodes.BACKEND_NOT_IMPLEMENTED.value} - Backend not implemented\n' f' {ExitCodes.AUTOMATION_SECRET_NOT_FOUND.value} - Automation secret not found\n' '\nUsage:\n' - f'{SCRIPT} -s {SAMPLE_SEEDS} -d\n\n' + f'{SCRIPT} -u ~/local/bin/nvdct/conf/{USER_DATA_FILE} \n\n' ) parser.add_argument( @@ -107,11 +107,11 @@ def parse_arguments() -> arg_Namespace: 'in "--time-format" format.\n' 'NOTE: the directory is a sub directory under "~/var/check_mk/topology/data/"\n', ) - parser.add_argument( - '-s', '--seed-devices', type=str, nargs='+', - help=f'List of devices to start the topology discovery from.\n' - f'I.e. {SAMPLE_SEEDS}', - ) + # parser.add_argument( + # '-s', '--seed-devices', type=str, nargs='+', + # help=f'List of devices to start the topology discovery from.\n' + # f'I.e. {SAMPLE_SEEDS}', + # ) parser.add_argument( '-p', '--prefix', type=str, help='Prepends each host with the prefix. (Needs testing)\n' @@ -131,7 +131,7 @@ def parse_arguments() -> arg_Namespace: parser.add_argument( '-u', '--user-data-file', type=str, help='Set the name uf the user provided data file\n' - f'Default is ~/local/bin/nvdct/conf/conf/{USER_DATA_FILE}\n', + f'Default is ~/local/bin/nvdct/conf/{USER_DATA_FILE}\n', ) parser.add_argument( '-v', '--version', action='version', @@ -191,8 +191,8 @@ def parse_arguments() -> arg_Namespace: 'Note: MULTISITE backend only.', ) parser.add_argument( - '--keep-domain', action='store_const', const=True, # default=False, - help='Do not remove the domain name from the neighbor name', + '--remove-domain', action='store_const', const=True, # default=False, + help='Remove the domain name from the neighbor name', ) parser.add_argument( '--keep', type=int, diff --git a/source/bin/nvdct/lib/settings.py b/source/bin/nvdct/lib/settings.py index 8a55f5553528b266fbe2e180d82da55d50905afe..f8f4bc87e379266536e477fc4116b147c8addba8 100755 --- a/source/bin/nvdct/lib/settings.py +++ b/source/bin/nvdct/lib/settings.py @@ -16,7 +16,7 @@ from logging import CRITICAL, FATAL, ERROR, WARNING, INFO, DEBUG from os import environ from sys import exit as sys_exit from time import strftime -from typing import Dict, List, NamedTuple +from typing import Dict, List, NamedTuple, Tuple from lib.utils import ( ExitCodes, @@ -81,7 +81,7 @@ class Settings: 'filter_customers': None, 'filter_sites': None, 'keep': False, - 'keep_domain': False, + 'remove_domain': False, 'layers': ['CDP'], 'log_file': f'{self.omd_root}/var/log/nvdct.log', 'log_level': 'WARNING', @@ -91,12 +91,11 @@ class Settings: 'prefix': None, 'quiet': False, 'pre_fetch': False, - 'seed_devices': [], + # 'seed_devices': [], 'skip_l3_if': False, 'skip_l3_ip': False, 'time_format': TIME_FORMAT, 'user_data_file': f'{self.omd_root}/local/bin/nvdct/conf/{USER_DATA_FILE}', - # 'version': False, } # args in the form {'s, __seed_devices': 'CORE01', 'p, __path_in_inventory': None, ... }} # we will remove 's, __' @@ -129,10 +128,14 @@ class Settings: self.__api_port: int | None = None # init user data with defaults + # self.__drop_host_regex: List[str] | None = None self.__custom_layers: List[StaticConnection] | None = None - self.__drop_host: List[str] | None = None - self.__drop_host_regex: List[str] | None = None - self.__host_map: Dict[str, str] | None = None + self.__customers: List[str] | None = None + self.__emblems: Emblems | None = None + self.__l2_drop_host: List[str] | None = None + self.__l2_host_map: Dict[str, str] | None = None + self.__l2_neighbour_replace_regex: List[Tuple[str, str]] | None = None + self.__l2_seed_devices: List[str] | None = None self.__l3v4_ignore_hosts: List[str] | None = None self.__l3v4_ignore_ip: List[IPv4Network] | None = None self.__l3v4_ignore_wildcard: List[Wildcard] | None = None @@ -140,11 +143,8 @@ class Settings: self.__l3v4_summarize: List[IPv4Network] | None = None self.__map_speed_to_thickness: List[Thickness] | None = None self.__protected_topologies: List[str] | None = None - self.__seed_devices: List[str] | None = None - self.__static_connections: List[StaticConnection] | None = None - self.__emblems: Emblems | None = None self.__sites: List[str] | None = None - self.__customers: List[str] | None = None + self.__static_connections: List[StaticConnection] | None = None # # CLI settings @@ -167,13 +167,13 @@ class Settings: return str(self.__settings['backend']) else: # fallback to defaukt -> exit ?? LOGGER.warning( - f'Unknown backend: {self.__settings['backend']}. Accepted backends are: ' + f'Unknown backend: {self.__settings["backend"]}. Accepted backends are: ' 'LIVESTATUS, MULTISITE, RESTAPI. Fall back zo MULTISITE.' ) return 'MULTISITE' @property # --case - def case(self) -> str| None: + def case(self) -> str | None: if self.__settings['case'] in ['LOWER', 'UPPER']: return self.__settings['case'] elif self.__settings['case'] is not None: @@ -224,8 +224,8 @@ class Settings: return None @property # --keep-domain - def keep_domain(self) -> bool: - return bool(self.__settings['keep_domain']) + def remove_domain(self) -> bool: + return bool(self.__settings['remove_domain']) @property # --layers def layers(self) -> List[str]: @@ -287,14 +287,6 @@ class Settings: def quiet(self) -> bool: return bool(self.__settings['quiet']) - @property # --seed-devices - def seed_devices(self) -> List[str]: - if self.__seed_devices is None: - self.__seed_devices = list(set(str(host) for host in ( - self.__user_data.get('SEED_DEVICES', []) + self.__settings.get('seed_devices', []) - ))) - return self.__seed_devices - @property # --skip-l3-if def skip_l3_if(self) -> bool: return bool(self.__settings['skip_l3_if']) @@ -311,13 +303,18 @@ class Settings: def user_data_file(self) -> str: return str(self.__settings['user_data_file']) - # @property # --version - # def version(self) -> bool: - # return bool(self.__settings['version']) - # # user data setting # + @property + def customers(self) -> List[str]: + if self.__customers is None: + self.__customers = [ + str(customer) for customer in set(self.__user_data.get('CUSTOMERS', [])) + ] + LOGGER.info(f'Found {len(self.__customers)} to filter on') + return self.__customers + @property def custom_layers(self) -> List[Layer]: if self.__custom_layers is None: @@ -341,20 +338,6 @@ class Settings: ) return self.__custom_layers - @property - def drop_hosts(self) -> List[str]: - if self.__drop_host is None: - self.__drop_host = [str(host) for host in set(self.__user_data.get('DROP_HOSTS', []))] - return self.__drop_host - - @property - def drop_hosts_regex(self) -> List[str]: - if self.__drop_host_regex is None: - self.__drop_host_regex = [str(host) for host in self.__user_data.get( - 'DROP_HOSTS_REGEX', [] - )] - return self.__drop_host_regex - @property def emblems(self) -> Emblems: if self.__emblems is None: @@ -370,14 +353,39 @@ class Settings: return self.__emblems @property - def host_map(self) -> Dict[str, str]: - if self.__host_map is None: - self.__host_map = { + def l2_drop_hosts(self) -> List[str]: + if self.__l2_drop_host is None: + self.__l2_drop_host = [str(host) for host in set(self.__user_data.get('L2_DROP_HOSTS', []))] + return self.__l2_drop_host + + @property + def l2_seed_devices(self) -> List[str]: + if self.__l2_seed_devices is None: + self.__l2_seed_devices = list(set(str(host) for host in ( + # self.__user_data.get('L2_SEED_DEVICES', []) + self.__settings.get('seed_devices', []) + self.__user_data.get('L2_SEED_DEVICES', []) + ))) + return self.__l2_seed_devices + + @property + def l2_host_map(self) -> Dict[str, str]: + if self.__l2_host_map is None: + self.__l2_host_map = { str(host): str(replace_host) for host, replace_host in self.__user_data.get( - 'HOST_MAP', {} + 'L2_HOST_MAP', {} ).items() } - return self.__host_map + return self.__l2_host_map + + @property + def l2_neighbour_replace_regex(self) -> List[Tuple[str, str]] | None: + if self.__l2_neighbour_replace_regex is None: + self.__l2_neighbour_replace_regex = [ + ( + str(regex), str(replace) + ) for regex, replace in self.__user_data.get('L2_NEIGHBOUR_REPLACE_REGEX', {}).items() + ] + return self.__l2_neighbour_replace_regex @property def l3v4_ignore_hosts(self) -> List[str]: @@ -544,15 +552,6 @@ class Settings: LOGGER.info(f'fFound {len(self.__sites)} to filter on') return self.__sites - @property - def customers(self) -> List[str]: - if self.__customers is None: - self.__customers = [ - str(customer) for customer in set(self.__user_data.get('CUSTOMERS', [])) - ] - LOGGER.info(f'fFound {len(self.__customers)} to filter on') - return self.__customers - # # all other settings # diff --git a/source/bin/nvdct/lib/utils.py b/source/bin/nvdct/lib/utils.py index 5b74464d0805f62db3c53f1a87a6d639b0fbee9b..27af6e0a0bb84fb7048c629effbc2375ad917656 100755 --- a/source/bin/nvdct/lib/utils.py +++ b/source/bin/nvdct/lib/utils.py @@ -23,7 +23,7 @@ from time import time as now_time from tomllib import loads as toml_loads, TOMLDecodeError from typing import List, Dict, TextIO -NVDCT_VERSION = '0.9.1-20241110' +NVDCT_VERSION = '0.9.2-20241117' @unique diff --git a/source/bin/nvdct/nvdct.py b/source/bin/nvdct/nvdct.py index 12eda3b07cf50d6727c1da7c1d2445a471e63a4f..81ae95783b5da7675a657b78b878e2386b827978 100755 --- a/source/bin/nvdct/nvdct.py +++ b/source/bin/nvdct/nvdct.py @@ -113,12 +113,24 @@ # moved (default) config file(s) to ./conf/ # 2024-06-14: added debug code for bad IPv4 address data # 2024-06-17: fixed bad IPv4 address data (just drop it) -# 2024-09-23: replaced options --lowercase/--uppercase with --case LOWER|UPPER +# 2024-09-23: incompatible replaced options --lowercase/--uppercase with --case LOWER|UPPER # changed version output from settings to argparse action -# removed backend FILESYSTEM -> will fallback to MULTISITE +# incompatible removed backend FILESYSTEM -> will fallback to MULTISITE +# incompatible # removed support for CMK2.2.x file format (removed option --new-format) -# 2024-09-24: added site filter for multisite deployments (MULTISITE only), option --filter-sites and SITES section in toml file -# added customer filter for MSP deployments (MULTISITE only), option --filter-customers and section CUSTOMERS in toml file +# 2024-09-24: added site filter for multisite deployments (MULTISITE only), option --filter-sites +# and SITES section in toml file +# added customer filter for MSP deployments (MULTISITE only), option --filter-customers +# and section CUSTOMERS in toml file +# 2024-11-16: added better logging for missing L2 data +# 2024-11-17: added L2_NEIGHBOUR_REPLACE_REGEX (ThX to Frankb@checkmk forum for the base idea) +# incompatible removed DROP_HOST_REGEX -> use L2_NEIGHBOUR_REPLACE_REGEX instead +# incompatible changed section names in TOML file to better distinguish between L2 and L3v4 +# HOST_MAP -> L2_HOST_MAP +# DROP_HOSTS -> L2_DROP_HOSTS +# SEED_DEVICES -> L2_SEED_DEVICES +# incompatible removed option -s, --seed-devices from CLI -> use TOML section L2_SEED_DEVICES instead +# incompatible changed the option keep-domain to remove-domain -> don't mess with neighbor names by default # creating topology data json from inventory data # @@ -217,9 +229,9 @@ import sys from collections.abc import Mapping, Sequence from ipaddress import IPv4Network from logging import DEBUG -from re import compile as re_compile +from re import sub as re_sub from time import strftime, time_ns -from typing import Dict, List +from typing import Dict, List, Tuple from lib.args import parse_arguments from lib.backends import ( @@ -265,11 +277,11 @@ from lib.settings import ( ) -DROP_HOSTS_REGEX: List[str] = [] -DROP_HOSTS: List[str] = [] EMBLEMS: Emblems HOST_CACHE: HostCache -HOST_MAP: Dict[str, str] = {} +L2_DROP_HOSTS: List[str] = [] +L2_HOST_MAP: Dict[str, str] = {} +L2_NEIGHBOUR_REPLACE_REGEX: List[Tuple[str, str]] | None = None MAP_SPEED_TO_THICKNESS: List[Thickness] = [] NV_CONNECTIONS = NvConnections() NV_OBJECTS = NvObjects() @@ -280,37 +292,42 @@ def create_l2_device_from_inv( host: str, inv_data: Sequence[Mapping[str, str]], inv_columns: InventoryColumns, - label: str, + # label: str, ) -> None: for topo_neighbour in inv_data: # check if required data are not empty if not (neighbour := topo_neighbour.get(inv_columns.neighbour)): + LOGGER.warning(f'incomplete data, neighbour missing {topo_neighbour}') continue if not (raw_local_port := topo_neighbour.get(inv_columns.local_port)): + LOGGER.warning(f'incomplete data, local port missing {topo_neighbour}') continue if not (raw_neighbour_port := topo_neighbour.get(inv_columns.neighbour_port)): + LOGGER.warning(f'incomplete data, neighbour port missing {topo_neighbour}') continue # drop neighbour before domain split - if neighbour in DROP_HOSTS: + if neighbour in L2_DROP_HOSTS: LOGGER.info(msg=f'drop neighbour: {neighbour}') continue - drop_regex = False - for re_str in DROP_HOSTS_REGEX: - re_host = re_compile(re_str) - if re_host.match(neighbour): - LOGGER.info(msg=f'regex drop neighbour: {neighbour}, regex str: {re_str}') - drop_regex = True - break - if drop_regex: - continue + if L2_NEIGHBOUR_REPLACE_REGEX: + for re_str, replace_str in L2_NEIGHBOUR_REPLACE_REGEX: + re_neighbour = re_sub(re_str, replace_str, neighbour) + if re_neighbour != neighbour: + LOGGER.info(f'regex changed Neighbor |{neighbour}| to |{re_neighbour}|') + neighbour = re_neighbour + if not neighbour: + LOGGER.info(f'Neighbour removed by regex (|{neighbour}|, |{re_str}|, |{replace_str}|)') + break + if not neighbour: + continue - if not SETTINGS.keep_domain: + if SETTINGS.remove_domain: neighbour = neighbour.split('.')[0] # drop neighbour after domain split - if neighbour in DROP_HOSTS: + if neighbour in L2_DROP_HOSTS: LOGGER.info(msg=f'drop neighbour: {neighbour}') continue @@ -324,8 +341,8 @@ def create_l2_device_from_inv( if SETTINGS.prefix: neighbour = f'{SETTINGS.prefix}{neighbour}' # rewrite neighbour if inventory neighbour and checkmk host don't match - if neighbour in HOST_MAP.keys(): - neighbour = HOST_MAP[neighbour] + if neighbour in L2_HOST_MAP.keys(): + neighbour = L2_HOST_MAP[neighbour] # getting/checking interfaces local_port = get_service_by_interface(host, raw_local_port, HOST_CACHE) @@ -439,12 +456,12 @@ def create_l2_topology( while devices_to_go: device = devices_to_go[0] - if device in HOST_MAP.keys(): + if device in L2_HOST_MAP.keys(): try: devices_to_go.remove(device) except ValueError: pass - device = HOST_MAP[device] + device = L2_HOST_MAP[device] if device in devices_done: continue @@ -456,7 +473,7 @@ def create_l2_topology( host=device, inv_data=topo_data, inv_columns=inv_columns, - label=label, + # label=label, ) for _entry in NV_OBJECTS.host_list: @@ -627,7 +644,7 @@ if __name__ == '__main__': HOST_CACHE = HostCacheMultiSite( pre_fetch=SETTINGS.pre_fetch, filter_sites=SETTINGS.filter_sites, - sites = SETTINGS.sites, + sites=SETTINGS.sites, ) case 'LIVESTATUS': HOST_CACHE = HostCacheLiveStatus( @@ -637,11 +654,11 @@ if __name__ == '__main__': LOGGER.error(msg=f'Backend {SETTINGS.backend} not (yet) implemented') sys.exit(ExitCodes.BACKEND_NOT_IMPLEMENTED.value) - HOST_MAP = SETTINGS.host_map - DROP_HOSTS = SETTINGS.drop_hosts - DROP_HOSTS_REGEX = SETTINGS.drop_hosts_regex - MAP_SPEED_TO_THICKNESS = SETTINGS.map_speed_to_thickness EMBLEMS = SETTINGS.emblems + L2_DROP_HOSTS = SETTINGS.l2_drop_hosts + L2_HOST_MAP = SETTINGS.l2_host_map + L2_NEIGHBOUR_REPLACE_REGEX = SETTINGS.l2_neighbour_replace_regex + MAP_SPEED_TO_THICKNESS = SETTINGS.map_speed_to_thickness jobs: List[Layer] = [] final_topology: Dict = {} @@ -701,7 +718,7 @@ if __name__ == '__main__': label = job.label.lower() columns = job.columns.split(',') create_l2_topology( - seed_devices=SETTINGS.seed_devices, + seed_devices=SETTINGS.l2_seed_devices, path_in_inventory=job.path, inv_columns=InventoryColumns( neighbour=columns[0], diff --git a/source/packages/nvdct b/source/packages/nvdct index 0302612a09b111180ac434963731ccb95dbd45f9..0b021af51d27b544826f163431b74f8f43a5267e 100644 --- a/source/packages/nvdct +++ b/source/packages/nvdct @@ -54,7 +54,7 @@ 'htdocs/images/icons/location_80.png']}, 'name': 'nvdct', 'title': 'Network Visualization Data Creation Tool (NVDCT)', - 'version': '0.9.1-20241110', + 'version': '0.9.2-20241116', 'version.min_required': '2.3.0b1', 'version.packaged': 'cmk-mkp-tool 0.2.0', 'version.usable_until': '2.4.0p1'}