Added logic for proxy groups. Only thing left is consistency check

This commit is contained in:
TheNetworkGuy 2024-06-11 16:13:45 +02:00
parent 2e7890784b
commit 6f044cb228
3 changed files with 95 additions and 46 deletions

View File

@ -3,7 +3,6 @@
""" """
Device specific handeling for Netbox to Zabbix Device specific handeling for Netbox to Zabbix
""" """
from os import sys from os import sys
from logging import getLogger from logging import getLogger
from pyzabbix import ZabbixAPIException from pyzabbix import ZabbixAPIException
@ -48,7 +47,7 @@ class NetworkDevice():
self.hostgroup = None self.hostgroup = None
self.tenant = nb.tenant self.tenant = nb.tenant
self.config_context = nb.config_context self.config_context = nb.config_context
self.zbxproxy = "0" self.zbxproxy = None
self.zabbix_state = 0 self.zabbix_state = 0
self.journal = journal self.journal = journal
self.nb_journals = nb_journal_class self.nb_journals = nb_journal_class
@ -372,23 +371,50 @@ class NetworkDevice():
self.logger.warning(e) self.logger.warning(e)
raise SyncInventoryError(e) from e raise SyncInventoryError(e) from e
def setProxy(self, proxy_list): # def setProxy(self, proxy_list):
""" check if Zabbix Proxy has been defined in config context """ # """ check if Zabbix Proxy has been defined in config context """
if "zabbix" in self.nb.config_context: # if "zabbix" in self.nb.config_context:
if "proxy" in self.nb.config_context["zabbix"]: # if "proxy" in self.nb.config_context["zabbix"]:
proxy = self.nb.config_context["zabbix"]["proxy"] # proxy = self.nb.config_context["zabbix"]["proxy"]
# Try matching proxy # # Try matching proxy
for px in proxy_list: # for px in proxy_list:
if px["name"] == proxy: # if px["name"] == proxy:
self.zbxproxy = px["proxyid"] # self.zbxproxy = px["proxyid"]
self.logger.debug(f"Found proxy {proxy}" # self.logger.debug(f"Found proxy {proxy}"
f" for {self.name}.") # f" for {self.name}.")
return True # return True
e = f"{self.name}: Defined proxy {proxy} not found." # e = f"{self.name}: Defined proxy {proxy} not found."
self.logger.warning(e) # self.logger.warning(e)
return False # return False
return True return True
def setProxy(self, proxy_list):
"""
Sets proxy or proxy group if this
value has been defined in config context
input: List of all proxies and proxy gorups in standardized format
"""
# check if the key Zabbix is defined in the config context
if not "zabbix" in self.nb.config_context:
return False
# Proxy group takes priority over a proxy due
# to it being HA and therefore being more reliable
for proxy_type in ('proxy_group', 'proxy'):
# Check if the key exists in Netbox CC
if proxy_type in self.nb.config_context["zabbix"]:
proxy_name = self.nb.config_context["zabbix"][proxy_type]
# go through all proxies
for proxy in proxy_list:
# If the proxy does not match the type, ignore and continue
if not proxy["type"] == proxy_type:
continue
# If the proxy name matches
if proxy["name"] == proxy_name:
self.zbxproxy = proxy
return True
return False
def createInZabbix(self, groups, templates, proxies, def createInZabbix(self, groups, templates, proxies,
description="Host added by Netbox sync script."): description="Host added by Netbox sync script."):
""" """
@ -408,30 +434,30 @@ class NetworkDevice():
groups = [{"groupid": self.group_id}] groups = [{"groupid": self.group_id}]
# Set Zabbix proxy if defined # Set Zabbix proxy if defined
self.setProxy(proxies) self.setProxy(proxies)
# Set basic data for host creation
create_data = {"host": self.name,
"name": self.visible_name,
"status": self.zabbix_state,
"interfaces": interfaces,
"groups": groups,
"templates": templateids,
"description": description,
"inventory_mode": self.inventory_mode,
"inventory": self.inventory
}
# If a Zabbix proxy or Zabbix Proxy group has been defined
if self.zbxproxy:
# If a lower version than 7 is used, we can assume that
# the proxy is a normal proxy and not a proxy group
if version.parse(self.zabbix.version) < version.parse("7.0.0"):
create_data["proxy_hostid"] = self.zbxproxy["id"]
else:
# Configure either a proxy or proxy group
create_data[self.zbxproxy["idtype"]] = self.zbxproxy["id"]
create_data["monitored_by"] = self.zbxproxy["monitored_by"]
# Add host to Zabbix # Add host to Zabbix
try: try:
if version.parse(self.zabbix.api_version()) < version.parse("7.0.0"): host = self.zabbix.host.create(**create_data)
host = self.zabbix.host.create(host=self.name,
name=self.visible_name,
status=self.zabbix_state,
interfaces=interfaces,
groups=groups,
templates=templateids,
proxy_hostid=self.zbxproxy,
description=description,
inventory_mode=self.inventory_mode,
inventory=self.inventory)
else:
host = self.zabbix.host.create(host=self.name,
name=self.visible_name,
status=self.zabbix_state,
interfaces=interfaces,
groups=groups,
templates=templateids,
proxyid=self.zbxproxy,
description=description,
inventory_mode=self.inventory_mode,
inventory=self.inventory)
self.zabbix_id = host["hostids"][0] self.zabbix_id = host["hostids"][0]
except ZabbixAPIException as e: except ZabbixAPIException as e:
e = f"Couldn't add {self.name}, Zabbix returned {str(e)}." e = f"Couldn't add {self.name}, Zabbix returned {str(e)}."
@ -540,9 +566,9 @@ class NetworkDevice():
else: else:
self.logger.warning(f"Device {self.name}: status OUT of sync.") self.logger.warning(f"Device {self.name}: status OUT of sync.")
self.updateZabbixHost(status=str(self.zabbix_state)) self.updateZabbixHost(status=str(self.zabbix_state))
### CHANGE THIS
# Check if a proxy has been defined # Check if a proxy has been defined
if self.zbxproxy != "0": if self.zbxproxy:
# Check if expected proxyID matches with configured proxy # Check if expected proxyID matches with configured proxy
if (("proxy_hostid" in host and host["proxy_hostid"] == self.zbxproxy) or if (("proxy_hostid" in host and host["proxy_hostid"] == self.zbxproxy) or
("proxyid" in host and host["proxyid"] == self.zbxproxy)): ("proxyid" in host and host["proxyid"] == self.zbxproxy)):

View File

@ -22,3 +22,23 @@ def build_path(endpoint, list_of_dicts):
item_path.append(item['name']) item_path.append(item['name'])
item_path.reverse() item_path.reverse()
return item_path return item_path
def proxy_prepper(proxy_list, proxy_group_list):
"""
Function that takes 2 lists and converts them using a
standardized format for further processing.
"""
output = []
for proxy in proxy_list:
proxy["type"] = "proxy"
proxy["id"] = proxy["proxyid"]
proxy["idtype"] = "proxyid"
proxy["monitored_by"] = 1
output.append(proxy)
for group in proxy_group_list:
group["type"] = "proxy_group"
group["id"] = group["proxy_groupid"]
group["idtype"] = "proxy_groupid"
group["monitored_by"] = 2
output.append(group)
return output

View File

@ -10,7 +10,7 @@ from pynetbox import api
#from pyzabbix import ZabbixAPI, ZabbixAPIException #from pyzabbix import ZabbixAPI, ZabbixAPIException
from zabbix_utils import ZabbixAPI, APIRequestError, ProcessingError from zabbix_utils import ZabbixAPI, APIRequestError, ProcessingError
from modules.device import NetworkDevice from modules.device import NetworkDevice
from modules.tools import convert_recordset from modules.tools import convert_recordset, proxy_prepper
from modules.exceptions import EnvironmentVarError, HostgroupError, SyncError from modules.exceptions import EnvironmentVarError, HostgroupError, SyncError
try: try:
from config import ( from config import (
@ -117,12 +117,15 @@ def main(arguments):
zabbix_templates = zabbix.template.get(output=['templateid', 'name']) zabbix_templates = zabbix.template.get(output=['templateid', 'name'])
zabbix_proxies = zabbix.proxy.get(output=['proxyid', proxy_name]) zabbix_proxies = zabbix.proxy.get(output=['proxyid', proxy_name])
zabbix_proxygroups = zabbix.proxygroup.get(output=["proxy_groupid", "name"]) zabbix_proxygroups = zabbix.proxygroup.get(output=["proxy_groupid", "name"])
# Get Netbox API version
nb_version = netbox.version
# Sanitize proxy data # Sanitize proxy data
if proxy_name == "host": if proxy_name == "host":
for proxy in zabbix_proxies: for proxy in zabbix_proxies:
proxy['name'] = proxy.pop('host') proxy['name'] = proxy.pop('host')
# Prepare list of all proxy and proxy_groups
zabbix_proxy_list = proxy_prepper(zabbix_proxies, zabbix_proxygroups)
# Get Netbox API version
nb_version = netbox.version
# Go through all Netbox devices # Go through all Netbox devices
for nb_device in netbox_devices: for nb_device in netbox_devices:
@ -167,7 +170,7 @@ def main(arguments):
# Check if device is already in Zabbix # Check if device is already in Zabbix
if device.zabbix_id: if device.zabbix_id:
device.ConsistencyCheck(zabbix_groups, zabbix_templates, device.ConsistencyCheck(zabbix_groups, zabbix_templates,
zabbix_proxies, full_proxy_sync) zabbix_proxy_list, full_proxy_sync)
continue continue
# Add hostgroup is config is set # Add hostgroup is config is set
# and Hostgroup is not present in Zabbix # and Hostgroup is not present in Zabbix
@ -182,7 +185,7 @@ def main(arguments):
zabbix_groups.append(hostgroup) zabbix_groups.append(hostgroup)
# Add device to Zabbix # Add device to Zabbix
device.createInZabbix(zabbix_groups, zabbix_templates, device.createInZabbix(zabbix_groups, zabbix_templates,
zabbix_proxies) zabbix_proxy_list)
except SyncError: except SyncError:
pass pass