Collection of CheckMK checks (see https://checkmk.com/). All checks and plugins are provided as is. Absolutely no warranty. Send any comments to thl-cmk[at]outlook[dot]com

Skip to content
Snippets Groups Projects
Commit bef5cd37 authored by thl-cmk's avatar thl-cmk :flag_na:
Browse files

update project

parent 546c3199
No related branches found
No related tags found
No related merge requests found
[PACKAGE]: ../../raw/master/mkp/nvdct-0.8.8-20240508.mkp "nvdct-0.8.8-20240508.mkp"
[PACKAGE]: ../../raw/master/mkp/nvdct-0.8.9-20240518.mkp "nvdct-0.8.9-20240518.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 by Andreas Boesl and [schnetz](https://exchange.checkmk.com/u/schnetz).\
......
File added
......@@ -22,7 +22,7 @@ from time import time as now_time
from tomllib import loads as toml_loads, TOMLDecodeError
from typing import List, Dict, Any, TextIO
NVDCT_VERSION = '0.8.8-20240507'
NVDCT_VERSION = '0.8.9-20240518'
@unique
......
......@@ -86,7 +86,7 @@
# min inv_lldp_cache version: 0.9.3-20240320 -> host label nvdct/has_lldp_neighbours
# 2024-03-27: added option --api-port, defaults to 80
# 2024-03-28: changed restapi get_interface_data to use one call to fetch all data
# 2024-03-29: added L3V4_IGNORE_IP and L3V4_IRNORE_WILDCARD to toml file
# 2024-03-29: added L3V4_IGNORE_IP and L3V4_IGNORE_WILDCARD to toml file
# 2024-03-31: fixed: L3V3_REPLACE -> L3V4_REPLACE
# made input from toml more bullet proof
# 2024-04-03: change HostCacheMultiSite to be child of HostCacheLiveStatus
......@@ -102,6 +102,10 @@
# added tooltip for --skip-l3-if and --skip-l3-ip
# 2024-04-30: automatically create @default if it doesn't exist
# 2024-05-07: fixed handling of ignore wildcard in L3v4 topology
# 2024-05-17: added support for Extreme interfaces in LLDP without stack id (1 -> 1:1)
# 2024-05-18: added support for NXOS interfaces in LLDP in short from (Eth1/1 -> Ethernet1/1)
# added IP-Address/IP-Network as quickinfo
# 2024-05-18: fixed crash non empty neighbour port (ThX to andreas doehler)
# creating topology data json from inventory data
#
......@@ -142,8 +146,8 @@ __objects = {
# "link": {}, # object not in CMK core
'metadata': {
'images': {
'icon': 'icon_warning', # additional immage shown at the node
'emblem': 'ip-network_80', # image to show for a object
'icon': 'icon_warning', # additional image shown at the node
'emblem': 'ip-network_80', # image to show for an object
},
'tooltip': {
'html': "Test message<div style='color: blue'>Some color <b>test</b></div>",
......@@ -263,7 +267,8 @@ def add_host_object(host: str, emblem: bool = False) -> None:
'images': {
'emblem': EMBLEMS.host_node, # node image
# 'icon': 'icon_tick', # status image, top left from emblem
}
},
**({'tooltip': {'quickinfo': [{'name': 'Host node', 'value': host}]}} if not link else {})
}
NV_OBJECTS[host] = {
......@@ -342,7 +347,8 @@ def add_service_object(
'images': {
'emblem': EMBLEMS.service_node, # node image
# 'icon': 'icon_tick', # status image, top left from emblem
}
},
**({'tooltip': {'quickinfo': [{'name': 'Service node', 'value': item}]}} if not link else {})
})
if isinstance(native_speed, int):
metadata.update({'native_speed': native_speed})
......@@ -368,6 +374,11 @@ def add_ipv4_network_object(network: str, emblem: str | None = None) -> None:
'images': {
'emblem': emblem, # node image
# 'icon': 'icon_tick', # status image, top left from emblem
},
'tooltip': {
'quickinfo': [
{'name': 'IP-Network', 'value': network},
]
}
}
}
......@@ -387,6 +398,11 @@ def add_ipv4_address_object(host: str, interface: str | None, ipv4_address: str)
'images': {
'emblem': EMBLEMS.ip_address,
# 'icon': 'icon_tick',
},
'tooltip': {
'quickinfo': [
{'name': 'IP-Address', 'value': ipv4_address},
]
}
}
}
......@@ -600,26 +616,51 @@ def get_service_by_interface(host: str, interface: str) -> Tuple[str | None, str
Returns:
Tuple of interface item, native interface speed in bits per second
"""
_alternate_if_name = {
'ethernet': 'eth',
# 'fastethernet': 'Fa',
# 'gigabitethernet': 'Gi',
# 'tengigabitethernet': 'Te',
# 'fortygigabitethernet': 'Fo',
# 'hundredgigabitethernet': 'Hu',
# 'management': 'Ma',
}
def _get_short_if_name(interface: str) -> str:
"""
returns short interface name from long interface name
interface: is the long interface name
:type interface: str
"""
if not interface:
return interface
for interface_prefix in _alternate_if_name.keys():
if interface.lower().startswith(interface_prefix.lower()):
interface_short = _alternate_if_name[interface_prefix]
return interface.lower().replace(interface_prefix.lower(), interface_short, 1)
return interface
# try to find the item for an interface
def _match_entry_with_item(_entry: Dict[str, str], services: List[str]) -> str | None:
def _match_entry_with_item(_entry: Dict[str, str], services: List[str]) -> Tuple[str | None, str | None]:
values = [_entry.get('name'), _entry.get('description'), _entry.get('alias')]
for value in values:
if value in services:
return value
return value, _entry.get('speed')
index = str(_entry.get('index'))
# for index try with padding
for i in range(1, 6):
index_padded = f'{index:0>{i}}'
if index_padded in services:
return index_padded
return index_padded, _entry.get('speed')
# still not found try values + index
for value in values:
if f'{value} {index_padded}' in services:
return f'{value} {index_padded}'
return f'{value} {index_padded}', _entry.get('speed')
LOGGER.warning(f'no match found |{_entry}|{services}|')
return None
return None, None
# empty host/neighbour should never happen here
if not host:
......@@ -657,14 +698,12 @@ def get_service_by_interface(host: str, interface: str) -> Tuple[str | None, str
str(_entry.get('index')),
_entry.get('phys_address'),
]:
_interface = _match_entry_with_item(_entry, interface_items)
if _interface:
native_speed = _entry.get('speed')
LOGGER.debug(
msg=f'Device: {host}: speed for interface '
f'{interface} is {native_speed}'
)
return _interface, native_speed
return _match_entry_with_item(_entry, interface_items)
elif f'1:{interface}' == _entry.get('name'): # Extreme non stack:
return _match_entry_with_item(_entry, interface_items)
elif _entry.get('name') is not None and _get_short_if_name(
_entry.get('name')) == interface.lower(): # Cisco NXOS
return _match_entry_with_item(_entry, interface_items)
LOGGER.warning(msg=f'Device: {host}: service for interface {interface} not found')
return None, None
......@@ -679,8 +718,12 @@ def create_device_from_inv(
data: Dict = {'connections': {}, "interfaces": []}
for topo_neighbour in inv_data:
neighbour = topo_neighbour.get(inv_columns.neighbour)
if not neighbour:
# check if required data are not empty
if not (neighbour := topo_neighbour.get(inv_columns.neighbour)):
continue
if not (raw_local_port := topo_neighbour.get(inv_columns.local_port)):
continue
if not (raw_neighbour_port := topo_neighbour.get(inv_columns.neighbour_port)):
continue
# drop neighbour if inventory neighbour is invalid
......@@ -711,7 +754,6 @@ def create_device_from_inv(
neighbour = HOST_MAP[neighbour]
# getting/checking interfaces
raw_local_port = topo_neighbour.get(inv_columns.local_port, '')
local_port, _local_speed = get_service_by_interface(host, raw_local_port)
if not local_port:
local_port = raw_local_port
......@@ -722,7 +764,6 @@ def create_device_from_inv(
msg=f'host: {host}, raw_local_port: {raw_local_port} -> local_port: {local_port}'
)
raw_neighbour_port = topo_neighbour.get(inv_columns.neighbour_port, '')
neighbour_port, _neighbour_speed = get_service_by_interface(neighbour, raw_neighbour_port)
if not neighbour_port:
neighbour_port = raw_neighbour_port
......
......@@ -57,7 +57,7 @@
'htdocs/images/icons/location_80.png']},
'name': 'nvdct',
'title': 'Network Visualization Data Creation Tool (NVDCT)',
'version': '0.8.8-20240508',
'version': '0.8.9-20240518',
'version.min_required': '2.2.0b1',
'version.packaged': '2.2.0p24',
'version.usable_until': '2.4.0p1'}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment