diff --git a/README.md b/README.md index 91b4b07c559c505f275463e532add06859d30c76..bddfd5f0342b45a6017a831e750a13f9fc76b11f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[PACKAGE]: ../../raw/master/mkp/vsphere_topo-0.0.4-20240712.mkp "vsphere_topo-0.0.4-20240712.mkp" +[PACKAGE]: ../../raw/master/mkp/vsphere_topo-0.0.5-20240714.mkp "vsphere_topo-0.0.5-20240714.mkp" # vSphere Topology Visualization This plugin uses the data from the _VMware ESX via vSphere_ special agent to create a topology of the vSphere environment.\ diff --git a/mkp/vsphere_topo-0.0.5-20240714.mkp b/mkp/vsphere_topo-0.0.5-20240714.mkp new file mode 100644 index 0000000000000000000000000000000000000000..3aca732bac6cadc4d49fbe4b351dc8705e6b1143 Binary files /dev/null and b/mkp/vsphere_topo-0.0.5-20240714.mkp differ diff --git a/source/cmk_addons_plugins/vsphere_topo/agent_based/packages.py b/source/cmk_addons_plugins/vsphere_topo/agent_based/packages.py index 63fc3dedc90fde82ce7588832ec4e5aeef2a95d6..dfb19c1f8fca6665e41ad0b283e80ffd2c577b94 100644 --- a/source/cmk_addons_plugins/vsphere_topo/agent_based/packages.py +++ b/source/cmk_addons_plugins/vsphere_topo/agent_based/packages.py @@ -15,9 +15,9 @@ # added vCenter twice (once as vCenter once as vM) with different object IDs # -> obsoletes 'Don\'t add vCenter as VM' # 2024-07-12: added support for Queried host is a host system +# 2024-07-13: refactoring save topology/make default and add dummy's logic from collections.abc import Mapping, Sequence -from pathlib import Path from time import time_ns from typing import Any @@ -33,12 +33,12 @@ from cmk.agent_based.v2 import ( ) from cmk.base.check_api import host_name from cmk_addons.plugins.vsphere_topo.lib.utils import ( + BASE_TOPO_PATH, EMBLEM_CLUSTER, EMBLEM_DATA_CENTER, EMBLEM_DATA_STORE, ICON_VCENTER, LiveStatusConnection, - OMD_ROOT, PARAM_CLUSTER, PARAM_DATA_CENTER, PARAM_DATA_STORE, @@ -48,10 +48,11 @@ from cmk_addons.plugins.vsphere_topo.lib.utils import ( PARAM_VCENTER, PARAM_VM_NAMES, RULE_SET_NAME_VSPHERE_TOPO, + add_dummy_topologies, adjust_name, get_emblem, - get_topologies, - save_data_to_file, + make_topo_default, + save_topology, ) Section = Mapping[str, object] @@ -276,39 +277,15 @@ def check_vsphere_topo( 'connections': connections, } - data_sets = [] - + save_topology(data=data_set_vsphere, sub_directory=raw_vsphere_host) # workaround for backend is only picking up topologies from default folder - path: str = f'{OMD_ROOT}/var/check_mk/topology/data/default' - if Path(path).exists() and not Path(f'{path}/data_vsphere.json').exists(): # don't overwrite existing topology - dummy_topology = {'version': 1, 'name': 'vSphere', 'objects': {}, 'connections': []} - save_data_to_file( - data=dummy_topology, - file='data_vsphere.json', - make_default=params.get(PARAM_MAKE_DEFAULT, False), - path=path, - ) - - for topology in get_topologies(): - data_sets.append({'version': 1, 'name': topology, 'objects': {}, 'connections': []}) + add_dummy_topologies(sub_directory=raw_vsphere_host) # end workaround - - data_sets.append(data_set_vsphere) - - path: str = f'{OMD_ROOT}/var/check_mk/topology/data/{raw_vsphere_host}' - - for data_set in data_sets: - file: str = f'data_{data_set["name"].lower()}.json' - save_data_to_file( - data=data_set, - file=file, - make_default=params.get(PARAM_MAKE_DEFAULT, False), - path=path, - ) + make_topo_default(sub_directory=raw_vsphere_host, make_default=params.get(PARAM_MAKE_DEFAULT, False)) yield Result(state=State.OK, summary=f'Objects: {len(objects)}') yield Result(state=State.OK, summary=f'Connections: {len(connections)}') - yield Result(state=State.OK, notice=f'Written to: {path}/{file}') + yield Result(state=State.OK, notice=f'Written to: {BASE_TOPO_PATH}/{raw_vsphere_host}/data_vsphere.json') yield from check_levels( value=(time_ns() - start_time) / 1e9, label='Time taken', diff --git a/source/cmk_addons_plugins/vsphere_topo/lib/utils.py b/source/cmk_addons_plugins/vsphere_topo/lib/utils.py index c377dca75e34d02892afa60274c3391a45423ea8..606ffcd0873a45d94549fdfaccb935ad7c88a7bb 100644 --- a/source/cmk_addons_plugins/vsphere_topo/lib/utils.py +++ b/source/cmk_addons_plugins/vsphere_topo/lib/utils.py @@ -48,6 +48,7 @@ PICTURE_TYPE_ICON: Final[str] = 'icon' RULE_SET_NAME_VSPHERE_TOPO: Final[str] = 'vsphere_topo' OMD_ROOT = environ["OMD_ROOT"] +BASE_TOPO_PATH: Final[str] = f'{OMD_ROOT}/var/check_mk/topology/data' def adjust_name(name: str, params: Mapping[str, Any]) -> str: @@ -90,44 +91,79 @@ def get_emblem(emblem: str, params: Tuple[str, bool | str] | None = None) -> str return params[1].strip() -def save_data_to_file(data: Mapping, path: str, file: str, make_default: bool) -> None: +def save_topology(data: Mapping, sub_directory: str) -> None: """ - Save the data as json file. + Save the topology as json file under $OMD_ROOT/var/check_mk/topology/data/{sub_directory}.data_{data['name']}.json + the filename will be changed to lower case. Args: data: the topology data - path: the path were to save the data - file: the file name to save the data in - make_default: if True, create the symlink "default" with path as target + sub_directory: the subdirectory were to save the data under ~/var/check_mk/topology/data/ Returns: None """ - - path_file = f'{path}/{file}' - save_file = Path(f'{path_file}') + file_name = f'data_{data["name"]}.json'.lower() + save_file = Path(f'{BASE_TOPO_PATH}/{sub_directory}/{file_name}') save_file.parent.mkdir(exist_ok=True, parents=True) save_file.write_text(json_dunps(data)) - parent_path = Path(f'{path}').parent - if not Path(f'{parent_path}/default').exists(): + +def make_topo_default(sub_directory: str, make_default: bool) -> None: + """ + Create the symlink "default" to $OMD_ROOT/var/check_mk/topology/data/{sub_directory} in + $OMD_ROOT/var/check_mk/topology/data/ if it don't exist or mage_default is True + Args: + sub_directory: the subdirectory under ~/var/check_mk/topology/data/ thaht become default + make_default: if True, create the symlink "default" with path as target + + Returns: + None + """ + + target_path = f'{BASE_TOPO_PATH}/{sub_directory}' + + if not Path(f'{BASE_TOPO_PATH}/default').exists(): make_default = True if make_default: - Path(f'{parent_path}/default').unlink(missing_ok=True) - Path(f'{parent_path}/default').symlink_to(target=Path(path), target_is_directory=True) + Path(f'{BASE_TOPO_PATH}/default').unlink(missing_ok=True) + Path(f'{BASE_TOPO_PATH}/default').symlink_to(target=Path(target_path), target_is_directory=True) def get_topologies() -> Sequence[str | None]: - path: str = f'{OMD_ROOT}/var/check_mk/topology/data/default' + """ + Returns a list of topology names form the default typology directory. + + Returns: + List of str ie: ['CDP', 'LLDP'] + """ + path: str = f'{BASE_TOPO_PATH}/default' if not Path(path).exists(): return [] files = [f for f in Path(path).glob('*.json') if f.is_file()] return [ - json_loads(Path(file).read_text()).get('name') for file in files if + json_loads(Path(file).read_text())['name'] for file in files if json_loads(Path(file).read_text()).get('name') is not None ] +def add_dummy_topologies(sub_directory: str): + path: str = f'{BASE_TOPO_PATH}/default' + if Path(path).exists() and not Path(f'{path}/data_vsphere.json').exists(): # don't overwrite existing topology + dummy_topology = {'version': 1, 'name': 'vSphere', 'objects': {}, 'connections': []} + save_topology( + data=dummy_topology, + sub_directory='default', + ) + + for topology in get_topologies(): + if not Path(f'{BASE_TOPO_PATH}/{sub_directory}/data_{topology.lower()}.json').exists(): + save_topology( + data={'version': 1, 'name': topology, 'objects': {}, 'connections': []}, + sub_directory=sub_directory + ) + + # # live status # diff --git a/source/packages/vsphere_topo b/source/packages/vsphere_topo index b417aa7d1be3b17463b9956bb4dbae566cd995ac..203c6983fae0bea438a9caaffbee88281d6270dd 100644 --- a/source/packages/vsphere_topo +++ b/source/packages/vsphere_topo @@ -12,7 +12,7 @@ 'vsphere_topo/graphing/packages.py']}, 'name': 'vsphere_topo', 'title': 'vSphere Topologie', - 'version': '0.0.4-20240712', + 'version': '0.0.5-20240714', 'version.min_required': '2.3.0b1', 'version.packaged': 'cmk-mkp-tool 0.2.0', 'version.usable_until': '2.4.0b1'}