From d6aaf9f53fe0b1ac518070eba54d9c007bd12384 Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Thu, 1 Aug 2024 20:24:23 +0200
Subject: [PATCH] update project

---
 README.md                                     |   2 +-
 mkp/vsphere_topo-0.0.7-20240801.mkp           | Bin 0 -> 8716 bytes
 .../vsphere_topo/agent_based/vsphere_topo.py  |  17 +++++--
 .../vsphere_topo/constants.py                 |   3 ++
 .../vsphere_topo/lib/utils.py                 |  14 ++++++
 .../vsphere_topo/rulesets/vsphere_topo.py     |  42 +++++++++++++++---
 source/packages/vsphere_topo                  |   2 +-
 7 files changed, 69 insertions(+), 11 deletions(-)
 create mode 100644 mkp/vsphere_topo-0.0.7-20240801.mkp

diff --git a/README.md b/README.md
index b5a342b..dfc7b17 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[PACKAGE]: ../../raw/master/mkp/vsphere_topo-0.0.6-20240729.mkp "vsphere_topo-0.0.6-20240729.mkp"
+[PACKAGE]: ../../raw/master/mkp/vsphere_topo-0.0.7-20240801.mkp "vsphere_topo-0.0.7-20240801.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.7-20240801.mkp b/mkp/vsphere_topo-0.0.7-20240801.mkp
new file mode 100644
index 0000000000000000000000000000000000000000..89ccc3529641c39ea5ee6509ec00d18b4779f8f9
GIT binary patch
literal 8716
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

literal 0
HcmV?d00001

diff --git a/source/cmk_addons_plugins/vsphere_topo/agent_based/vsphere_topo.py b/source/cmk_addons_plugins/vsphere_topo/agent_based/vsphere_topo.py
index 791db5f..ea6baf7 100644
--- a/source/cmk_addons_plugins/vsphere_topo/agent_based/vsphere_topo.py
+++ b/source/cmk_addons_plugins/vsphere_topo/agent_based/vsphere_topo.py
@@ -21,6 +21,7 @@
 # 2024-07-25: fixed crash if VM has no data store
 # 2024-07-29: added option to ignore powered off VMs
 #             added option to ignore VMs by name (regex)
+# 2024-07-31: added option to map vSphere names to CMK/topology names for data center, cluster, hosts and VMs
 
 from collections.abc import Mapping, Sequence
 from re import compile as re_compile
@@ -51,6 +52,7 @@ from cmk_addons.plugins.vsphere_topo.constants import (
     PARAM_IGNORE_POWERED_OFF_VMS,
     PARAM_IGNORE_VM_NAME_REGEX,
     PARAM_MAKE_DEFAULT,
+    PARAM_MAP_NAMES,
     PARAM_VCENTER,
     PARAM_VM_NAMES,
     RULE_SET_NAME_VSPHERE_TOPO,
@@ -64,6 +66,7 @@ from cmk_addons.plugins.vsphere_topo.lib.utils import (
     add_dummy_topologies,
     adjust_name,
     get_emblem,
+    get_name_map,
     make_topo_default,
     save_topology,
 )
@@ -90,6 +93,9 @@ def check_vsphere_topo(
     connections: TopoConnections = TopoConnections()
     ignored_powered_off_vms: int = 0
     ignored_by_name_vms: int = 0
+
+    name_map = get_name_map(params.get(PARAM_MAP_NAMES, []))
+
     if ignore_by_name_str := ')|('.join(params.get(PARAM_IGNORE_VM_NAME_REGEX, [])):
         re_ignore_vms = re_compile(f'({ignore_by_name_str})')
     else:
@@ -112,8 +118,9 @@ def check_vsphere_topo(
         )
         vsphere_host = f'vc{raw_vsphere_host}'
 
-        for cluster in section_esx_vsphere_clusters:
-            data_center: str = section_esx_vsphere_clusters[cluster]['datacenter'].strip()
+        for raw_cluster in section_esx_vsphere_clusters:
+            data_center: str = section_esx_vsphere_clusters[raw_cluster]['datacenter'].strip()
+            data_center = name_map.get(data_center, data_center)
             if objects.topo_objects.get(data_center) is None:
                 objects.add_host(
                     host=data_center,
@@ -121,6 +128,7 @@ def check_vsphere_topo(
                     link2core=False,
                 )
                 connections.add_connection(data_center, vsphere_host)
+            cluster = name_map.get(raw_cluster, raw_cluster)
             objects.add_host(
                 host=cluster,
                 emblem=get_emblem(EMBLEM_CLUSTER, params.get(PARAM_CLUSTER)),
@@ -128,9 +136,10 @@ def check_vsphere_topo(
             )
             connections.add_connection(cluster, data_center)
 
-            host_systems: Sequence[str] = section_esx_vsphere_clusters[cluster].get('hostsystems', '').split(',')
+            host_systems: Sequence[str] = section_esx_vsphere_clusters[raw_cluster].get('hostsystems', '').split(',')
             for host_system in host_systems:
                 esx_name: str = adjust_name(host_system, params.get(PARAM_HOST_SYSTEMS, {}))
+                esx_name = name_map.get(esx_name, esx_name)
                 objects.add_host(host=esx_name)
                 connections.add_connection(cluster, esx_name)
         yield Result(
@@ -177,7 +186,9 @@ def check_vsphere_topo(
             if params.get(PARAM_IGNORE_POWERED_OFF_VMS) is not True or vm.get('powerstate') != 'poweredOff':
                 vm_name: str = adjust_name(vm['vm_name'], params.get(PARAM_VM_NAMES, {}))
                 if re_ignore_vms is None or re_ignore_vms.match(vm_name) is None:
+                    vm_name = name_map.get(vm_name, vm_name)
                     host_system: str = adjust_name(vm['hostsystem'], params.get(PARAM_HOST_SYSTEMS, {}))
+                    host_system = name_map.get(host_system, host_system)
                     objects.add_host(host=vm_name)
                     connections.add_connection(vm_name, host_system)
                 else:
diff --git a/source/cmk_addons_plugins/vsphere_topo/constants.py b/source/cmk_addons_plugins/vsphere_topo/constants.py
index 2036aea..e7b40d6 100644
--- a/source/cmk_addons_plugins/vsphere_topo/constants.py
+++ b/source/cmk_addons_plugins/vsphere_topo/constants.py
@@ -31,6 +31,9 @@ PARAM_IGNORE_VM_NAME_REGEX: Final[str] = 'ignore_vms_by_name'
 PARAM_KEEP_DOMAIN: Final[str] = 'keep_domain'
 PARAM_LOWER: Final[str] = 'lower'
 PARAM_MAKE_DEFAULT: Final[str] = 'make_default'
+PARAM_MAP_NAMES: Final[str] = 'map_names'
+PARAM_MAP_NAME_CMK: Final[str] = 'name_cmk'
+PARAM_MAP_NAME_VSPHERE: Final[str] = 'name_vsphere'
 PARAM_NO_CHANGE: Final[str] = 'no_change'
 PARAM_NO_EMBLEM: Final[str] = 'no_emblem'
 PARAM_PREFIX: Final[str] = 'prefix'
diff --git a/source/cmk_addons_plugins/vsphere_topo/lib/utils.py b/source/cmk_addons_plugins/vsphere_topo/lib/utils.py
index e969d59..9f4b36a 100644
--- a/source/cmk_addons_plugins/vsphere_topo/lib/utils.py
+++ b/source/cmk_addons_plugins/vsphere_topo/lib/utils.py
@@ -12,6 +12,7 @@ from collections.abc import Mapping, MutableMapping, MutableSequence, Sequence
 from json import dumps as json_dunps, loads as json_loads
 from os import environ
 from pathlib import Path
+from re import compile as re_compile
 from typing import Final, Tuple
 
 from livestatus import MultiSiteConnection, SiteConfigurations, SiteId
@@ -21,6 +22,8 @@ from cmk_addons.plugins.vsphere_topo.constants import (
     PARAM_DEFAULT_EMBLEM,
     PARAM_KEEP_DOMAIN,
     PARAM_LOWER,
+    PARAM_MAP_NAME_CMK,
+    PARAM_MAP_NAME_VSPHERE,
     PARAM_NO_CHANGE,
     PARAM_NO_EMBLEM,
     PARAM_PREFIX,
@@ -31,6 +34,17 @@ OMD_ROOT = environ['OMD_ROOT']
 BASE_TOPO_PATH: Final[str] = f'{OMD_ROOT}/var/check_mk/topology/data'
 
 
+def get_name_map(mappings: Sequence):
+    re_hostname = re_compile(r'^[0-9a-zA-Z\.\-\_]+$')
+    name_map = {}
+
+    for mapping in mappings:
+        if re_hostname.match(mapping[PARAM_MAP_NAME_CMK]) is not None:
+            name_map[mapping[PARAM_MAP_NAME_VSPHERE]] = mapping[PARAM_MAP_NAME_CMK]
+
+    return name_map
+
+
 def adjust_name(name: str, params: Mapping[str, object]) -> str:
     class Case:
         upper: str = PARAM_UPPER
diff --git a/source/cmk_addons_plugins/vsphere_topo/rulesets/vsphere_topo.py b/source/cmk_addons_plugins/vsphere_topo/rulesets/vsphere_topo.py
index 4ce3367..f24b582 100644
--- a/source/cmk_addons_plugins/vsphere_topo/rulesets/vsphere_topo.py
+++ b/source/cmk_addons_plugins/vsphere_topo/rulesets/vsphere_topo.py
@@ -11,8 +11,9 @@
 # removed PARAM_ADD_DUMMY_TOPOLOGIES and PARAM_DONT_ADD_VC_AS_VM
 
 from collections.abc import Mapping, Sequence
+from re import compile as re_compile
 
-from cmk.rulesets.v1 import Help, Label, Title
+from cmk.rulesets.v1 import Help, Label, Title, Message
 from cmk.rulesets.v1.form_specs import (
     CascadingSingleChoice,
     CascadingSingleChoiceElement,
@@ -20,12 +21,12 @@ from cmk.rulesets.v1.form_specs import (
     DictElement,
     Dictionary,
     FixedValue,
+    List,
     SingleChoice,
     SingleChoiceElement,
     String,
-    List,
 )
-from cmk.rulesets.v1.form_specs.validators import LengthInRange
+from cmk.rulesets.v1.form_specs.validators import LengthInRange, MatchRegex
 from cmk.rulesets.v1.rule_specs import CheckParameters, HostCondition, Topic
 from cmk_addons.plugins.vsphere_topo.constants import (
     # PARAM_ADD_DUMMY_TOPOLOGIES,
@@ -47,6 +48,9 @@ from cmk_addons.plugins.vsphere_topo.constants import (
     PARAM_KEEP_DOMAIN,
     PARAM_LOWER,
     PARAM_MAKE_DEFAULT,
+    PARAM_MAP_NAMES,
+    PARAM_MAP_NAME_CMK,
+    PARAM_MAP_NAME_VSPHERE,
     PARAM_NO_CHANGE,
     PARAM_NO_EMBLEM,
     PARAM_PREFIX,
@@ -194,14 +198,40 @@ def _parameter_form() -> Dictionary:
             PARAM_IGNORE_VM_NAME_REGEX: DictElement(
                 parameter_form=List(
                     title=Title('Ignore VMs by name (regex)'),
-                    element_template=String(
-                        title=Title('add regex string')
-                    ),
+                    element_template=String(),
                     help_text=Help(
                         'The regex strings will be applied after the upper/lower case and prefix '
                         'change to the VM names. If there more than one regex string the will be "OR" connected.'
                     ),
                 )),
+            PARAM_MAP_NAMES: DictElement(
+                parameter_form=List(
+                    title=Title('Map vSphere names to CMK names'),
+                    element_template=Dictionary(
+                        elements={
+                            PARAM_MAP_NAME_VSPHERE: DictElement(
+                                parameter_form=String(
+                                    title=Title('vSphere name'),
+                                ),
+                                required=True,
+                            ),
+                            PARAM_MAP_NAME_CMK: DictElement(
+                                parameter_form=String(
+                                    title=Title('Checkmk name'),
+                                    custom_validate=(MatchRegex(
+                                        regex=r'^[0-9a-zA-Z\.\-\_]+$',
+                                        error_msg=Message(
+                                            'Your input does not match the required format. '
+                                            'Only "0-9a-zA-Z_-." are allowed.'
+                                        )
+                                    ),)
+                                ),
+                                required=True,
+                            )
+                        }
+                    ),
+                    help_text=Help(''),
+                )),
             # PARAM_DONT_ADD_VC_AS_VM: DictElement(
             #     render_only=True,
             #     parameter_form=FixedValue(
diff --git a/source/packages/vsphere_topo b/source/packages/vsphere_topo
index 8ec8c4e..f5b7d53 100644
--- a/source/packages/vsphere_topo
+++ b/source/packages/vsphere_topo
@@ -13,7 +13,7 @@
                                   'vsphere_topo/rulesets/vsphere_topo.py']},
  'name': 'vsphere_topo',
  'title': 'vSphere Topologie',
- 'version': '0.0.6-20240729',
+ 'version': '0.0.7-20240801',
  'version.min_required': '2.3.0b1',
  'version.packaged': 'cmk-mkp-tool 0.2.0',
  'version.usable_until': '2.4.0b1'}
-- 
GitLab