Fixed several bugs, set default interface for VM to agent, fixed several linter errors.

This commit is contained in:
TheNetworkGuy 2024-10-30 12:23:15 +01:00
parent bff34a8e38
commit 66f24e6891
6 changed files with 63 additions and 36 deletions

0
modules/__init__.py Normal file
View File

View File

@ -25,7 +25,7 @@ except ModuleNotFoundError:
sys.exit(0) sys.exit(0)
class PhysicalDevice(): class PhysicalDevice():
# pylint: disable=too-many-instance-attributes, too-many-arguments # pylint: disable=too-many-instance-attributes, too-many-arguments, too-many-positional-arguments
""" """
Represents Network device. Represents Network device.
INPUT: (Netbox device class, ZabbixAPI class, journal flag, NB journal class) INPUT: (Netbox device class, ZabbixAPI class, journal flag, NB journal class)
@ -98,9 +98,9 @@ class PhysicalDevice():
def set_hostgroup(self, hg_format, nb_site_groups, nb_regions): def set_hostgroup(self, hg_format, nb_site_groups, nb_regions):
"""Set the hostgroup for this device""" """Set the hostgroup for this device"""
# Create new Hostgroup instance # Create new Hostgroup instance
hg = Hostgroup("dev", self.nb, self.nb_api_version, hg = Hostgroup("dev", self.nb, self.nb_api_version)
traverse_site_groups, traverse_regions, # Set Hostgroup nesting options
nb_site_groups, nb_regions) hg.set_nesting(traverse_site_groups, traverse_regions, nb_site_groups, nb_regions)
# Generate hostgroup based on hostgroup format # Generate hostgroup based on hostgroup format
self.hostgroup = hg.generate(hg_format) self.hostgroup = hg.generate(hg_format)
@ -301,9 +301,9 @@ class PhysicalDevice():
self.logger.info(e) self.logger.info(e)
self.create_journal_entry("warning", "Deleted host from Zabbix") self.create_journal_entry("warning", "Deleted host from Zabbix")
except APIRequestError as e: except APIRequestError as e:
e = f"Zabbix returned the following error: {str(e)}." message = f"Zabbix returned the following error: {str(e)}."
self.logger.error(e) self.logger.error(message)
raise SyncExternalError(e) from e raise SyncExternalError(message) from e
def _zabbixHostnameExists(self): def _zabbixHostnameExists(self):
""" """
@ -332,12 +332,12 @@ class PhysicalDevice():
if interface.interface["type"] == 2: if interface.interface["type"] == 2:
interface.set_snmp() interface.set_snmp()
else: else:
interface.set_default() interface.set_default_snmp()
return [interface.interface] return [interface.interface]
except InterfaceConfigError as e: except InterfaceConfigError as e:
e = f"{self.name}: {e}" message = f"{self.name}: {e}"
self.logger.warning(e) self.logger.warning(message)
raise SyncInventoryError(e) from e raise SyncInventoryError(message) from e
def setProxy(self, proxy_list): def setProxy(self, proxy_list):
""" """
@ -459,9 +459,9 @@ class PhysicalDevice():
# Add group to final data # Add group to final data
final_data.append({'groupid': groupid["groupids"][0], 'name': zabbix_hg}) final_data.append({'groupid': groupid["groupids"][0], 'name': zabbix_hg})
except APIRequestError as e: except APIRequestError as e:
e = f"Hostgroup '{zabbix_hg}': unable to create. Zabbix returned {str(e)}." msg = f"Hostgroup '{zabbix_hg}': unable to create. Zabbix returned {str(e)}."
self.logger.error(e) self.logger.error(msg)
raise SyncExternalError(e) from e raise SyncExternalError(msg) from e
return final_data return final_data
def lookupZabbixHostgroup(self, group_list, lookup_group): def lookupZabbixHostgroup(self, group_list, lookup_group):
@ -691,9 +691,9 @@ class PhysicalDevice():
self.logger.info(e) self.logger.info(e)
self.create_journal_entry("info", e) self.create_journal_entry("info", e)
except APIRequestError as e: except APIRequestError as e:
e = f"Zabbix returned the following error: {str(e)}." msg = f"Zabbix returned the following error: {str(e)}."
self.logger.error(e) self.logger.error(msg)
raise SyncExternalError(e) from e raise SyncExternalError(msg) from e
else: else:
# If no updates are found, Zabbix interface is in-sync # If no updates are found, Zabbix interface is in-sync
e = f"Host {self.name}: interface in-sync." e = f"Host {self.name}: interface in-sync."

View File

@ -5,9 +5,7 @@ from modules.tools import build_path
class Hostgroup(): class Hostgroup():
"""Hostgroup class for devices and VM's """Hostgroup class for devices and VM's
Takes type (vm or dev) and NB object""" Takes type (vm or dev) and NB object"""
def __init__(self, obj_type, nb_obj, version, def __init__(self, obj_type, nb_obj, version):
nested_sitegroup_flag, nested_region_flag,
nb_groups, nb_regions):
if obj_type not in ("vm", "dev"): if obj_type not in ("vm", "dev"):
raise HostgroupError(f"Unable to create hostgroup with type {type}") raise HostgroupError(f"Unable to create hostgroup with type {type}")
self.type = str(obj_type) self.type = str(obj_type)
@ -15,8 +13,7 @@ class Hostgroup():
self.name = self.nb.name self.name = self.nb.name
self.nb_version = version self.nb_version = version
# Used for nested data objects # Used for nested data objects
self.nested_objects = {"site_group": {"flag": nested_sitegroup_flag, "data": nb_groups}, self.nested_objects = {}
"region": {"flag": nested_region_flag, "data": nb_regions}}
self._set_format_options() self._set_format_options()
def __str__(self): def __str__(self):
@ -68,13 +65,19 @@ class Hostgroup():
self.format_options = format_options self.format_options = format_options
def set_nesting(self, nested_sitegroup_flag, nested_region_flag,
nb_groups, nb_regions):
"""Set nesting options for this Hostgroup"""
self.nested_objects = {"site_group": {"flag": nested_sitegroup_flag, "data": nb_groups},
"region": {"flag": nested_region_flag, "data": nb_regions}}
def generate(self, hg_format=None): def generate(self, hg_format=None):
"""Generate hostgroup based on a provided format""" """Generate hostgroup based on a provided format"""
# Set format to default in case its not specified # Set format to default in case its not specified
if not hg_format: if not hg_format:
hg_format = "site/manufacturer/role" if self.type == "dev" else "cluster/role" hg_format = "site/manufacturer/role" if self.type == "dev" else "cluster/role"
# Split all given names # Split all given names
hg_output = list() hg_output = []
hg_items = hg_format.split("/") hg_items = hg_format.split("/")
for hg_item in hg_items: for hg_item in hg_items:
# Check if requested data is available as option for this host # Check if requested data is available as option for this host

View File

@ -90,7 +90,7 @@ class ZabbixInterface():
e = "Interface type is not SNMP, unable to set SNMP details" e = "Interface type is not SNMP, unable to set SNMP details"
raise InterfaceConfigError(e) raise InterfaceConfigError(e)
def set_default(self): def set_default_snmp(self):
""" Set default config to SNMPv2, port 161 and community macro. """ """ Set default config to SNMPv2, port 161 and community macro. """
self.interface = self.skelet self.interface = self.skelet
self.interface["type"] = "2" self.interface["type"] = "2"
@ -98,3 +98,8 @@ class ZabbixInterface():
self.interface["details"] = {"version": "2", self.interface["details"] = {"version": "2",
"community": "{$SNMP_COMMUNITY}", "community": "{$SNMP_COMMUNITY}",
"bulk": "1"} "bulk": "1"}
def set_default_agent(self):
"""Sets interface to Zabbix agent defaults"""
self.interface["type"] = "1"
self.interface["port"] = "10050"

View File

@ -1,9 +1,12 @@
#!/usr/bin/env python3
# pylint: disable=duplicate-code
"""Module that hosts all functions for virtual machine processing""" """Module that hosts all functions for virtual machine processing"""
from os import sys from os import sys
from modules.device import PhysicalDevice from modules.device import PhysicalDevice
from modules.hostgroups import Hostgroup from modules.hostgroups import Hostgroup
from modules.exceptions import TemplateError from modules.interface import ZabbixInterface
from modules.exceptions import TemplateError, InterfaceConfigError, SyncInventoryError
try: try:
from config import ( from config import (
traverse_site_groups, traverse_site_groups,
@ -16,12 +19,16 @@ except ModuleNotFoundError:
class VirtualMachine(PhysicalDevice): class VirtualMachine(PhysicalDevice):
"""Model for virtual machines""" """Model for virtual machines"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.hostgroup = None
self.zbx_template_names = None
def set_hostgroup(self, hg_format, nb_site_groups, nb_regions): def set_hostgroup(self, hg_format, nb_site_groups, nb_regions):
"""Set the hostgroup for this device""" """Set the hostgroup for this device"""
# Create new Hostgroup instance # Create new Hostgroup instance
hg = Hostgroup("vm", self.nb, self.nb_api_version, hg = Hostgroup("vm", self.nb, self.nb_api_version)
traverse_site_groups, traverse_regions, hg.set_nesting(traverse_site_groups, traverse_regions, nb_site_groups, nb_regions)
nb_site_groups, nb_regions)
# Generate hostgroup based on hostgroup format # Generate hostgroup based on hostgroup format
self.hostgroup = hg.generate(hg_format) self.hostgroup = hg.generate(hg_format)
@ -36,11 +43,24 @@ class VirtualMachine(PhysicalDevice):
self.logger.warning(e) self.logger.warning(e)
return True return True
def set_template(self, prefer_config_context=None, overrule_custom=None): def setInterfaceDetails(self): # pylint: disable=invalid-name
""" """
This wrapper takes the original function and Overwrites device function to select an agent interface type by default
overwrites it with the set_vm_template function. Agent type interfaces are more likely to be used with VMs then SNMP
This function (set_template) is used by several
other functions such as the consistency check in the parent class.
""" """
self.set_vm_template() try:
# Initiate interface class
interface = ZabbixInterface(self.nb.config_context, self.ip)
# Check if Netbox has device context.
# If not fall back to old config.
if interface.get_context():
# If device is SNMP type, add aditional information.
if interface.interface["type"] == 2:
interface.set_snmp()
else:
interface.set_default_agent()
return [interface.interface]
except InterfaceConfigError as e:
message = f"{self.name}: {e}"
self.logger.warning(message)
raise SyncInventoryError(message) from e

View File

@ -109,7 +109,7 @@ def main(arguments):
proxy_name = "name" proxy_name = "name"
# Get all Zabbix and Netbox data # Get all Zabbix and Netbox data
netbox_devices = netbox.dcim.devices.filter(**nb_device_filter) netbox_devices = netbox.dcim.devices.filter(**nb_device_filter)
netbox_vms = netbox.virtualization.virtual_machines.all() if sync_vms else list() netbox_vms = netbox.virtualization.virtual_machines.all() if sync_vms else []
netbox_site_groups = convert_recordset((netbox.dcim.site_groups.all())) netbox_site_groups = convert_recordset((netbox.dcim.site_groups.all()))
netbox_regions = convert_recordset(netbox.dcim.regions.all()) netbox_regions = convert_recordset(netbox.dcim.regions.all())
netbox_journals = netbox.extras.journal_entries netbox_journals = netbox.extras.journal_entries
@ -138,7 +138,6 @@ def main(arguments):
vm.set_hostgroup(vm_hostgroup_format,netbox_site_groups,netbox_regions) vm.set_hostgroup(vm_hostgroup_format,netbox_site_groups,netbox_regions)
vm.set_vm_template() vm.set_vm_template()
vm.set_inventory(nb_vm) vm.set_inventory(nb_vm)
print(f"Templates: {vm.zbx_template_names}")
# Checks if device is in cleanup state # Checks if device is in cleanup state
if vm.status in zabbix_device_removal: if vm.status in zabbix_device_removal: