first supoport of multiple hostgroups

This commit is contained in:
Raymond Kuiper
2025-06-04 14:23:01 +02:00
parent 6bdaf4e5b7
commit bc53737e02
5 changed files with 68 additions and 44 deletions

BIN
modules/.device.py.swp Normal file

Binary file not shown.

View File

@@ -6,6 +6,7 @@ from copy import deepcopy
from logging import getLogger
from os import sys
from re import search
from operator import itemgetter
from zabbix_utils import APIRequestError
@@ -64,11 +65,11 @@ class PhysicalDevice:
self.status = nb.status.label
self.zabbix = zabbix
self.zabbix_id = None
self.group_id = None
self.group_ids = []
self.nb_api_version = nb_version
self.zbx_template_names = []
self.zbx_templates = []
self.hostgroup = None
self.hostgroups = []
self.tenant = nb.tenant
self.config_context = nb.config_context
self.zbxproxy = None
@@ -152,7 +153,10 @@ class PhysicalDevice:
nb_regions=nb_regions,
)
# Generate hostgroup based on hostgroup format
self.hostgroup = hg.generate(hg_format)
if isinstance(hg_format, list):
self.hostgroups = [hg.generate(f) for f in hg_format]
else:
self.hostgroups.append(hg.generate(hg_format))
def set_template(self, prefer_config_context, overrule_custom):
"""Set Template"""
@@ -333,12 +337,16 @@ class PhysicalDevice:
OUTPUT: True / False
"""
# Go through all groups
for group in groups:
if group["name"] == self.hostgroup:
self.group_id = group["groupid"]
e = f"Host {self.name}: matched group {group['name']}"
self.logger.debug(e)
return True
self.logger.debug(self.hostgroups)
for hg in self.hostgroups:
for group in groups:
if group["name"] == hg:
self.group_ids.append({"groupid": group["groupid"]})
e = f"Host {self.name}: matched group {group['name']}"
self.logger.debug(e)
if self.group_ids:
return True
return False
def cleanup(self):
@@ -514,7 +522,8 @@ class PhysicalDevice:
templateids.append({"templateid": template["templateid"]})
# Set interface, group and template configuration
interfaces = self.setInterfaceDetails()
groups = [{"groupid": self.group_id}]
groups = self.group_ids
# Set Zabbix proxy if defined
self.setProxy(proxies)
# Set basic data for host creation
@@ -567,25 +576,26 @@ class PhysicalDevice:
"""
final_data = []
# Check if the hostgroup is in a nested format and check each parent
for pos in range(len(self.hostgroup.split("/"))):
zabbix_hg = self.hostgroup.rsplit("/", pos)[0]
if self.lookupZabbixHostgroup(hostgroups, zabbix_hg):
# Hostgroup already exists
continue
# Create new group
try:
# API call to Zabbix
groupid = self.zabbix.hostgroup.create(name=zabbix_hg)
e = f"Hostgroup '{zabbix_hg}': created in Zabbix."
self.logger.info(e)
# Add group to final data
final_data.append(
{"groupid": groupid["groupids"][0], "name": zabbix_hg}
)
except APIRequestError as e:
msg = f"Hostgroup '{zabbix_hg}': unable to create. Zabbix returned {str(e)}."
self.logger.error(msg)
raise SyncExternalError(msg) from e
for hostgroup in self.hostgroups:
for pos in range(len(hostgroup.split("/"))):
zabbix_hg = hostgroup.rsplit("/", pos)[0]
if self.lookupZabbixHostgroup(hostgroups, zabbix_hg):
# Hostgroup already exists
continue
# Create new group
try:
# API call to Zabbix
groupid = self.zabbix.hostgroup.create(name=zabbix_hg)
e = f"Hostgroup '{zabbix_hg}': created in Zabbix."
self.logger.info(e)
# Add group to final data
final_data.append(
{"groupid": groupid["groupids"][0], "name": zabbix_hg}
)
except APIRequestError as e:
msg = f"Hostgroup '{zabbix_hg}': unable to create. Zabbix returned {str(e)}."
self.logger.error(msg)
raise SyncExternalError(msg) from e
return final_data
def lookupZabbixHostgroup(self, group_list, lookup_group):
@@ -625,7 +635,7 @@ class PhysicalDevice:
Checks if Zabbix object is still valid with NetBox parameters.
"""
# If group is found or if the hostgroup is nested
if not self.setZabbixGroupID(groups) or len(self.hostgroup.split("/")) > 1:
if not self.setZabbixGroupID(groups): # or len(self.hostgroups.split("/")) > 1:
if create_hostgroups:
# Script is allowed to create a new hostgroup
new_groups = self.createZabbixHostgroup(groups)
@@ -633,7 +643,7 @@ class PhysicalDevice:
# Add all new groups to the list of groups
groups.append(group)
# check if the initial group was not already found (and this is a nested folder check)
if not self.group_id:
if not self.group_ids:
# Function returns true / false but also sets GroupID
if not self.setZabbixGroupID(groups) and not create_hostgroups:
e = (
@@ -642,6 +652,9 @@ class PhysicalDevice:
)
self.logger.warning(e)
raise SyncInventoryError(e)
#if self.group_ids:
# self.group_ids.append(self.pri_group_id)
# Prepare templates and proxy config
self.zbxTemplatePrepper(templates)
self.setProxy(proxies)
@@ -680,6 +693,7 @@ class PhysicalDevice:
f"Received value: {host['host']}"
)
self.updateZabbixHost(host=self.name)
# Execute check depending on wether the name is special or not
if self.use_visible_name:
if host["name"] == self.visible_name:
@@ -709,18 +723,20 @@ class PhysicalDevice:
group_dictname = "hostgroups"
if str(self.zabbix.version).startswith(("6", "5")):
group_dictname = "groups"
for group in host[group_dictname]:
if group["groupid"] == self.group_id:
self.logger.debug(f"Host {self.name}: hostgroup in-sync.")
break
self.logger.warning(f"Host {self.name}: hostgroup OUT of sync.")
self.updateZabbixHost(groups={"groupid": self.group_id})
# Check if hostgroups match
if (sorted(host[group_dictname], key=itemgetter('groupid')) ==
sorted(self.group_ids, key=itemgetter('groupid'))):
self.logger.debug(f"Host {self.name}: hostgroups in-sync.")
else:
self.logger.warning(f"Host {self.name}: hostgroups OUT of sync.")
self.updateZabbixHost(groups=self.group_ids)
if int(host["status"]) == self.zabbix_state:
self.logger.debug(f"Host {self.name}: status in-sync.")
else:
self.logger.warning(f"Host {self.name}: status OUT of sync.")
self.updateZabbixHost(status=str(self.zabbix_state))
# Check if a proxy has been defined
if self.zbxproxy:
# Check if proxy or proxy group is defined
@@ -882,7 +898,7 @@ class PhysicalDevice:
e = (
f"Host {self.name} has unsupported interface configuration."
f" Host has total of {len(host['interfaces'])} interfaces. "
"Manual interfention required."
"Manual intervention required."
)
self.logger.error(e)
raise SyncInventoryError(e)

View File

@@ -91,7 +91,6 @@ class Hostgroup:
if self.nb.cluster:
format_options["cluster"] = self.nb.cluster.name
format_options["cluster_type"] = self.nb.cluster.type.name
self.format_options = format_options
def set_nesting(

View File

@@ -58,7 +58,10 @@ class VirtualMachine(PhysicalDevice):
nb_regions=nb_regions,
)
# Generate hostgroup based on hostgroup format
self.hostgroup = hg.generate(hg_format)
if isinstance(hg_format, list):
self.hostgroups = [hg.generate(f) for f in hg_format]
else:
self.hostgroups.append(hg.generate(hg_format))
def set_vm_template(self):
"""Set Template for VMs. Overwrites default class