From c0c8dca78a782fc7ac327bcd9b0cd806cd9dba7a Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Mon, 15 Jul 2024 19:50:26 +0200
Subject: [PATCH] update project

---
 README.md                                     |   2 +-
 mkp/vsphere_topo-0.0.5-20240714.mkp           | Bin 0 -> 7453 bytes
 .../vsphere_topo/agent_based/packages.py      |  41 +++--------
 .../vsphere_topo/lib/utils.py                 |  64 ++++++++++++++----
 source/packages/vsphere_topo                  |   2 +-
 5 files changed, 61 insertions(+), 48 deletions(-)
 create mode 100644 mkp/vsphere_topo-0.0.5-20240714.mkp

diff --git a/README.md b/README.md
index 91b4b07..bddfd5f 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
GIT binary patch
literal 7453
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

literal 0
HcmV?d00001

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 63fc3de..dfb19c1 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 c377dca..606ffcd 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 b417aa7..203c698 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'}
-- 
GitLab