mirror of
https://github.com/TheNetworkGuy/netbox-zabbix-sync.git
synced 2025-07-13 15:24:48 -06:00
Fixed several bugs, set default interface for VM to agent, fixed several linter errors.
This commit is contained in:
parent
bff34a8e38
commit
66f24e6891
0
modules/__init__.py
Normal file
0
modules/__init__.py
Normal 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."
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user