diff --git a/modules/__init__.py b/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/modules/device.py b/modules/device.py index e26c7fe..cbc03ec 100644 --- a/modules/device.py +++ b/modules/device.py @@ -25,7 +25,7 @@ except ModuleNotFoundError: sys.exit(0) 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. 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): """Set the hostgroup for this device""" # Create new Hostgroup instance - hg = Hostgroup("dev", self.nb, self.nb_api_version, - traverse_site_groups, traverse_regions, - nb_site_groups, nb_regions) + hg = Hostgroup("dev", self.nb, self.nb_api_version) + # Set Hostgroup nesting options + hg.set_nesting(traverse_site_groups, traverse_regions, nb_site_groups, nb_regions) # Generate hostgroup based on hostgroup format self.hostgroup = hg.generate(hg_format) @@ -301,9 +301,9 @@ class PhysicalDevice(): self.logger.info(e) self.create_journal_entry("warning", "Deleted host from Zabbix") except APIRequestError as e: - e = f"Zabbix returned the following error: {str(e)}." - self.logger.error(e) - raise SyncExternalError(e) from e + message = f"Zabbix returned the following error: {str(e)}." + self.logger.error(message) + raise SyncExternalError(message) from e def _zabbixHostnameExists(self): """ @@ -332,12 +332,12 @@ class PhysicalDevice(): if interface.interface["type"] == 2: interface.set_snmp() else: - interface.set_default() + interface.set_default_snmp() return [interface.interface] except InterfaceConfigError as e: - e = f"{self.name}: {e}" - self.logger.warning(e) - raise SyncInventoryError(e) from e + message = f"{self.name}: {e}" + self.logger.warning(message) + raise SyncInventoryError(message) from e def setProxy(self, proxy_list): """ @@ -459,9 +459,9 @@ class PhysicalDevice(): # Add group to final data final_data.append({'groupid': groupid["groupids"][0], 'name': zabbix_hg}) except APIRequestError as e: - e = f"Hostgroup '{zabbix_hg}': unable to create. Zabbix returned {str(e)}." - self.logger.error(e) - raise SyncExternalError(e) from 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): @@ -691,9 +691,9 @@ class PhysicalDevice(): self.logger.info(e) self.create_journal_entry("info", e) except APIRequestError as e: - e = f"Zabbix returned the following error: {str(e)}." - self.logger.error(e) - raise SyncExternalError(e) from e + msg = f"Zabbix returned the following error: {str(e)}." + self.logger.error(msg) + raise SyncExternalError(msg) from e else: # If no updates are found, Zabbix interface is in-sync e = f"Host {self.name}: interface in-sync." diff --git a/modules/hostgroups.py b/modules/hostgroups.py index 4c64f40..d2487b5 100644 --- a/modules/hostgroups.py +++ b/modules/hostgroups.py @@ -5,9 +5,7 @@ from modules.tools import build_path class Hostgroup(): """Hostgroup class for devices and VM's Takes type (vm or dev) and NB object""" - def __init__(self, obj_type, nb_obj, version, - nested_sitegroup_flag, nested_region_flag, - nb_groups, nb_regions): + def __init__(self, obj_type, nb_obj, version): if obj_type not in ("vm", "dev"): raise HostgroupError(f"Unable to create hostgroup with type {type}") self.type = str(obj_type) @@ -15,8 +13,7 @@ class Hostgroup(): self.name = self.nb.name self.nb_version = version # Used for nested data objects - self.nested_objects = {"site_group": {"flag": nested_sitegroup_flag, "data": nb_groups}, - "region": {"flag": nested_region_flag, "data": nb_regions}} + self.nested_objects = {} self._set_format_options() def __str__(self): @@ -68,13 +65,19 @@ class Hostgroup(): 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): """Generate hostgroup based on a provided format""" # Set format to default in case its not specified if not hg_format: hg_format = "site/manufacturer/role" if self.type == "dev" else "cluster/role" # Split all given names - hg_output = list() + hg_output = [] hg_items = hg_format.split("/") for hg_item in hg_items: # Check if requested data is available as option for this host diff --git a/modules/interface.py b/modules/interface.py index 54586db..384c35e 100644 --- a/modules/interface.py +++ b/modules/interface.py @@ -90,7 +90,7 @@ class ZabbixInterface(): e = "Interface type is not SNMP, unable to set SNMP details" raise InterfaceConfigError(e) - def set_default(self): + def set_default_snmp(self): """ Set default config to SNMPv2, port 161 and community macro. """ self.interface = self.skelet self.interface["type"] = "2" @@ -98,3 +98,8 @@ class ZabbixInterface(): self.interface["details"] = {"version": "2", "community": "{$SNMP_COMMUNITY}", "bulk": "1"} + + def set_default_agent(self): + """Sets interface to Zabbix agent defaults""" + self.interface["type"] = "1" + self.interface["port"] = "10050" diff --git a/modules/virtual_machine.py b/modules/virtual_machine.py index ba58311..87ba1f3 100644 --- a/modules/virtual_machine.py +++ b/modules/virtual_machine.py @@ -1,9 +1,12 @@ +#!/usr/bin/env python3 +# pylint: disable=duplicate-code """Module that hosts all functions for virtual machine processing""" from os import sys from modules.device import PhysicalDevice from modules.hostgroups import Hostgroup -from modules.exceptions import TemplateError +from modules.interface import ZabbixInterface +from modules.exceptions import TemplateError, InterfaceConfigError, SyncInventoryError try: from config import ( traverse_site_groups, @@ -16,12 +19,16 @@ except ModuleNotFoundError: class VirtualMachine(PhysicalDevice): """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): """Set the hostgroup for this device""" # Create new Hostgroup instance - hg = Hostgroup("vm", self.nb, self.nb_api_version, - traverse_site_groups, traverse_regions, - nb_site_groups, nb_regions) + hg = Hostgroup("vm", self.nb, self.nb_api_version) + hg.set_nesting(traverse_site_groups, traverse_regions, nb_site_groups, nb_regions) # Generate hostgroup based on hostgroup format self.hostgroup = hg.generate(hg_format) @@ -36,11 +43,24 @@ class VirtualMachine(PhysicalDevice): self.logger.warning(e) 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 it with the set_vm_template function. - This function (set_template) is used by several - other functions such as the consistency check in the parent class. + Overwrites device function to select an agent interface type by default + Agent type interfaces are more likely to be used with VMs then SNMP """ - 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 diff --git a/netbox_zabbix_sync.py b/netbox_zabbix_sync.py index 306f3f4..3be1793 100755 --- a/netbox_zabbix_sync.py +++ b/netbox_zabbix_sync.py @@ -109,7 +109,7 @@ def main(arguments): proxy_name = "name" # Get all Zabbix and Netbox data 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_regions = convert_recordset(netbox.dcim.regions.all()) 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_vm_template() vm.set_inventory(nb_vm) - print(f"Templates: {vm.zbx_template_names}") # Checks if device is in cleanup state if vm.status in zabbix_device_removal: