🏷️ Changed all occurences of "Netbox" to "NetBox" as per the [NetBox Style Guide](https://netboxlabs.com/docs/netbox/en/stable/development/style-guide/).

This commit is contained in:
Raymond Kuiper 2024-12-06 13:51:05 +01:00
parent 434722df53
commit d0941ff909
7 changed files with 75 additions and 75 deletions

View File

@ -1,6 +1,6 @@
# Netbox to Zabbix synchronization # NetBox to Zabbix synchronization
A script to create, update and delete Zabbix hosts using Netbox device objects. A script to create, update and delete Zabbix hosts using NetBox device objects.
## Installation via Docker ## Installation via Docker
@ -81,16 +81,16 @@ password. In that case `ZABBIX_USER` and `ZABBIX_PASS` will be ignored.
ZABBIX_TOKEN=othersecrettoken ZABBIX_TOKEN=othersecrettoken
``` ```
If you are using custom SSL certificates for Netbox and/or Zabbix, you can set If you are using custom SSL certificates for NetBox and/or Zabbix, you can set
the following environment variable to the path of your CA bundle file: the following environment variable to the path of your CA bundle file:
```bash ```bash
REQUEST_CA_BUNDLE=/path/to/your/ca-bundle.crt REQUEST_CA_BUNDLE=/path/to/your/ca-bundle.crt
``` ```
### Netbox custom fields ### NetBox custom fields
Use the following custom fields in Netbox (if you are using config context for Use the following custom fields in NetBox (if you are using config context for
the template information then the zabbix_template field is not required): the template information then the zabbix_template field is not required):
``` ```
@ -118,7 +118,7 @@ manually change the ID. For example to re-run a sync.
## Virtual Machine (VM) Syncing ## Virtual Machine (VM) Syncing
In order to use VM syncing, make sure that the `zabbix_id` custom field is also In order to use VM syncing, make sure that the `zabbix_id` custom field is also
present on Virtual machine objects in Netbox. present on Virtual machine objects in NetBox.
Use the `config.py` file and set the `sync_vms` variable to `True`. Use the `config.py` file and set the `sync_vms` variable to `True`.
@ -128,7 +128,7 @@ hostgroups. The default is `cluster_type/cluster/role`.
To enable filtering for VM's, check the `nb_vm_filter` variable out. It works To enable filtering for VM's, check the `nb_vm_filter` variable out. It works
the same as with the device filter (see documentation under "Hostgroup layout"). the same as with the device filter (see documentation under "Hostgroup layout").
Note that not all filtering capabilities and properties of devices are Note that not all filtering capabilities and properties of devices are
applicable to VM's and vice-versa. Check the Netbox API documentation to see applicable to VM's and vice-versa. Check the NetBox API documentation to see
which filtering options are available for each object type. which filtering options are available for each object type.
## Config file ## Config file
@ -260,15 +260,15 @@ in an error:
``` ```
hostgroup_format = "mycustomfieldname" hostgroup_format = "mycustomfieldname"
Netbox-Zabbix-sync - ERROR - ESXI1 has no reliable hostgroup. This is most likely due to the use of custom fields that are empty. NetBox-Zabbix-sync - ERROR - ESXI1 has no reliable hostgroup. This is most likely due to the use of custom fields that are empty.
``` ```
### Device status ### Device status
By setting a status on a Netbox device you determine how the host is added (or By setting a status on a NetBox device you determine how the host is added (or
updated) in Zabbix. There are, by default, 3 options: updated) in Zabbix. There are, by default, 3 options:
- Delete the host from Zabbix (triggered by Netbox status "Decommissioning" and - Delete the host from Zabbix (triggered by NetBox status "Decommissioning" and
"Inventory") "Inventory")
- Create the host in Zabbix but with a disabled status (Trigger by "Offline", - Create the host in Zabbix but with a disabled status (Trigger by "Offline",
"Planned", "Staged" and "Failed") "Planned", "Staged" and "Failed")
@ -284,8 +284,8 @@ script:
### Zabbix Inventory ### Zabbix Inventory
This script allows you to enable the inventory on managed Zabbix hosts and sync This script allows you to enable the inventory on managed Zabbix hosts and sync
NetBox device properties to the specified inventory fields. To map Netbox NetBox device properties to the specified inventory fields. To map NetBox
information to Netbox inventory fields, set `inventory_sync` to `True`. information to NetBox inventory fields, set `inventory_sync` to `True`.
You can set the inventory mode to "disabled", "manual" or "automatic" with the You can set the inventory mode to "disabled", "manual" or "automatic" with the
`inventory_mode` variable. See `inventory_mode` variable. See
@ -310,7 +310,7 @@ fields.
### Template source ### Template source
You can either use a Netbox device type custom field or Netbox config context You can either use a NetBox device type custom field or NetBox config context
for the Zabbix template information. for the Zabbix template information.
Using a custom field allows for only one template. You can assign multiple Using a custom field allows for only one template. You can assign multiple
@ -342,7 +342,7 @@ in the config context in this format:
``` ```
You can also opt for the default device type custom field behaviour but with the You can also opt for the default device type custom field behaviour but with the
added benefit of overwriting the template should a device in Netbox have a added benefit of overwriting the template should a device in NetBox have a
device specific context defined. In this case the device specific context device specific context defined. In this case the device specific context
template(s) will take priority over the device type custom field template. template(s) will take priority over the device type custom field template.
@ -352,9 +352,9 @@ templates_config_context_overrule = True
## Permissions ## Permissions
### Netbox ### NetBox
Make sure that the Netbox user has proper permissions for device read and modify Make sure that the NetBox user has proper permissions for device read and modify
(modify to set the Zabbix HostID custom field) operations. The user should also (modify to set the Zabbix HostID custom field) operations. The user should also
have read-only access to the device types. have read-only access to the device types.
@ -435,13 +435,13 @@ In the example above the host will use the group on Zabbix 7. On Zabbix 6 and
below the host will use the proxy. Zabbix 7 will use the proxy value when below the host will use the proxy. Zabbix 7 will use the proxy value when
ommiting the proxy_group value. ommiting the proxy_group value.
Because of the possible amount of destruction when setting up Netbox but Because of the possible amount of destruction when setting up NetBox but
forgetting the proxy command, the sync works a bit different. By default forgetting the proxy command, the sync works a bit different. By default
everything is synced except in a situation where the Zabbix host has a proxy everything is synced except in a situation where the Zabbix host has a proxy
configured but nothing is configured in Netbox. To force deletion and a full configured but nothing is configured in NetBox. To force deletion and a full
sync, set the `full_proxy_sync` variable in the config file. sync, set the `full_proxy_sync` variable in the config file.
### Set interface parameters within Netbox ### Set interface parameters within NetBox
When adding a new device, you can set the interface type with custom context. By When adding a new device, you can set the interface type with custom context. By
default, the following configuration is applied when no config context is default, the following configuration is applied when no config context is
@ -453,14 +453,14 @@ provided:
- SNMP community: {$SNMP_COMMUNITY} - SNMP community: {$SNMP_COMMUNITY}
Due to Zabbix limitations of changing interface type with a linked template, Due to Zabbix limitations of changing interface type with a linked template,
changing the interface type from within Netbox is not supported and the script changing the interface type from within NetBox is not supported and the script
will generate an error. will generate an error.
For example when changing a SNMP interface to an Agent interface: For example when changing a SNMP interface to an Agent interface:
``` ```
Netbox-Zabbix-sync - WARNING - Device: Interface OUT of sync. NetBox-Zabbix-sync - WARNING - Device: Interface OUT of sync.
Netbox-Zabbix-sync - ERROR - Device: changing interface type to 1 is not supported. NetBox-Zabbix-sync - ERROR - Device: changing interface type to 1 is not supported.
``` ```
To configure the interface parameters you'll need to use custom context. Custom To configure the interface parameters you'll need to use custom context. Custom
@ -519,7 +519,7 @@ environment. For example, you could:
``` ```
I would recommend using macros for sensitive data such as community strings I would recommend using macros for sensitive data such as community strings
since the data in Netbox is plain-text. since the data in NetBox is plain-text.
> **_NOTE:_** Not all SNMP data is required for a working configuration. > **_NOTE:_** Not all SNMP data is required for a working configuration.
> [The following parameters are allowed](https://www.zabbix.com/documentation/current/manual/api/reference/hostinterface/object#details_tag "The following parameters are allowed")but > [The following parameters are allowed](https://www.zabbix.com/documentation/current/manual/api/reference/hostinterface/object#details_tag "The following parameters are allowed")but

View File

@ -7,7 +7,7 @@ templates_config_context = False
# higher priority then custom field templates # higher priority then custom field templates
templates_config_context_overrule = False templates_config_context_overrule = False
# Set template and device Netbox "custom field" names # Set template and device NetBox "custom field" names
# Template_cf is not used when templates_config_context is enabled # Template_cf is not used when templates_config_context is enabled
template_cf = "zabbix_template" template_cf = "zabbix_template"
device_cf = "zabbix_hostid" device_cf = "zabbix_hostid"
@ -35,7 +35,7 @@ vm_hostgroup_format = "cluster_type/cluster/role"
# With this option disabled proxy's will only be added and modified for Zabbix hosts. # With this option disabled proxy's will only be added and modified for Zabbix hosts.
full_proxy_sync = False full_proxy_sync = False
## Netbox to Zabbix device state convertion ## NetBox to Zabbix device state convertion
zabbix_device_removal = ["Decommissioning", "Inventory"] zabbix_device_removal = ["Decommissioning", "Inventory"]
zabbix_device_disable = ["Offline", "Planned", "Staged", "Failed"] zabbix_device_disable = ["Offline", "Planned", "Staged", "Failed"]
@ -62,7 +62,7 @@ traverse_site_groups = False
# nb_device_filter = {"site": ["HQ-AMS", "HQ-FRA"]} #Device must be in either one of these sites # nb_device_filter = {"site": ["HQ-AMS", "HQ-FRA"]} #Device must be in either one of these sites
# nb_device_filter = {"site": "HQ-AMS", "tag": "zabbix", "role__n": ["PDU", "console-server"]} #Device must be in site HQ-AMS, have the tag zabbix and must not be part of the PDU or console-server role # nb_device_filter = {"site": "HQ-AMS", "tag": "zabbix", "role__n": ["PDU", "console-server"]} #Device must be in site HQ-AMS, have the tag zabbix and must not be part of the PDU or console-server role
# Default device filter, only get devices which have a name in Netbox: # Default device filter, only get devices which have a name in NetBox:
nb_device_filter = {"name__n": "null"} nb_device_filter = {"name__n": "null"}
# Default filter for VMs # Default filter for VMs
nb_vm_filter = {"name__n": "null"} nb_vm_filter = {"name__n": "null"}

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# pylint: disable=invalid-name, logging-not-lazy, too-many-locals, logging-fstring-interpolation, too-many-lines # pylint: disable=invalid-name, logging-not-lazy, too-many-locals, logging-fstring-interpolation, too-many-lines
""" """
Device specific handeling for Netbox to Zabbix Device specific handeling for NetBox to Zabbix
""" """
from os import sys from os import sys
from re import search from re import search
@ -29,7 +29,7 @@ class PhysicalDevice():
# pylint: disable=too-many-instance-attributes, too-many-arguments, too-many-positional-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)
""" """
def __init__(self, nb, zabbix, nb_journal_class, nb_version, journal=None, logger=None): def __init__(self, nb, zabbix, nb_journal_class, nb_version, journal=None, logger=None):
@ -92,7 +92,7 @@ class PhysicalDevice():
self.visible_name = self.nb.name self.visible_name = self.nb.name
self.use_visible_name = True self.use_visible_name = True
self.logger.info(f"Host {self.visible_name} contains special characters. " self.logger.info(f"Host {self.visible_name} contains special characters. "
f"Using {self.name} as name for the Netbox object " f"Using {self.name} as name for the NetBox object "
f"and using {self.visible_name} as visible name in Zabbix.") f"and using {self.visible_name} as visible name in Zabbix.")
else: else:
pass pass
@ -164,7 +164,7 @@ class PhysicalDevice():
# Set inventory mode. Default is disabled (see class init function). # Set inventory mode. Default is disabled (see class init function).
if inventory_mode == "disabled": if inventory_mode == "disabled":
if inventory_sync: if inventory_sync:
self.logger.error(f"Host {self.name}: Unable to map Netbox inventory to Zabbix. " self.logger.error(f"Host {self.name}: Unable to map NetBox inventory to Zabbix. "
"Inventory sync is enabled in config but inventory mode is disabled.") "Inventory sync is enabled in config but inventory mode is disabled.")
return True return True
if inventory_mode == "manual": if inventory_mode == "manual":
@ -194,7 +194,7 @@ class PhysicalDevice():
self.inventory[zbx_inv_field] = str(value) self.inventory[zbx_inv_field] = str(value)
elif not value: elif not value:
# empty value should just be an empty string for API compatibility # empty value should just be an empty string for API compatibility
self.logger.debug(f"Host {self.name}: Netbox inventory lookup for " self.logger.debug(f"Host {self.name}: NetBox inventory lookup for "
f"'{nb_inv_field}' returned an empty value") f"'{nb_inv_field}' returned an empty value")
self.inventory[zbx_inv_field] = "" self.inventory[zbx_inv_field] = ""
else: else:
@ -221,7 +221,7 @@ class PhysicalDevice():
self.logger.warning(e) self.logger.warning(e)
raise SyncInventoryError(e) raise SyncInventoryError(e)
if not self.nb.virtual_chassis.master: if not self.nb.virtual_chassis.master:
e = (f"{self.name} is part of a Netbox virtual chassis which does " e = (f"{self.name} is part of a NetBox virtual chassis which does "
"not have a master configured. Skipping for this reason.") "not have a master configured. Skipping for this reason.")
self.logger.error(e) self.logger.error(e)
raise SyncInventoryError(e) raise SyncInventoryError(e)
@ -256,7 +256,7 @@ class PhysicalDevice():
raise SyncInventoryError() raise SyncInventoryError()
# Set variable to empty list # Set variable to empty list
self.zbx_templates = [] self.zbx_templates = []
# Go through all templates definded in Netbox # Go through all templates definded in NetBox
for nb_template in self.zbx_template_names: for nb_template in self.zbx_template_names:
template_match = False template_match = False
# Go through all templates found in Zabbix # Go through all templates found in Zabbix
@ -295,7 +295,7 @@ class PhysicalDevice():
def cleanup(self): def cleanup(self):
""" """
Removes device from external resources. Removes device from external resources.
Resets custom fields in Netbox. Resets custom fields in NetBox.
""" """
if self.zabbix_id: if self.zabbix_id:
try: try:
@ -303,7 +303,7 @@ class PhysicalDevice():
zbx_host = bool(self.zabbix.host.get(filter={'hostid': self.zabbix_id}, zbx_host = bool(self.zabbix.host.get(filter={'hostid': self.zabbix_id},
output=[])) output=[]))
e = (f"Host {self.name}: was already deleted from Zabbix." e = (f"Host {self.name}: was already deleted from Zabbix."
" Removed link in Netbox.") " Removed link in NetBox.")
if zbx_host: if zbx_host:
# Delete host should it exists # Delete host should it exists
self.zabbix.host.delete(self.zabbix_id) self.zabbix.host.delete(self.zabbix_id)
@ -317,7 +317,7 @@ class PhysicalDevice():
raise SyncExternalError(message) from e raise SyncExternalError(message) from e
def _zeroize_cf(self): def _zeroize_cf(self):
"""Sets the hostID custom field in Netbox to zero, """Sets the hostID custom field in NetBox to zero,
effectively destroying the link""" effectively destroying the link"""
self.nb.custom_fields[device_cf] = None self.nb.custom_fields[device_cf] = None
self.nb.save() self.nb.save()
@ -336,13 +336,13 @@ class PhysicalDevice():
def setInterfaceDetails(self): def setInterfaceDetails(self):
""" """
Checks interface parameters from Netbox and Checks interface parameters from NetBox and
creates a model for the interface to be used in Zabbix. creates a model for the interface to be used in Zabbix.
""" """
try: try:
# Initiate interface class # Initiate interface class
interface = ZabbixInterface(self.nb.config_context, self.ip) interface = ZabbixInterface(self.nb.config_context, self.ip)
# Check if Netbox has device context. # Check if NetBox has device context.
# If not fall back to old config. # If not fall back to old config.
if interface.get_context(): if interface.get_context():
# If device is SNMP type, add aditional information. # If device is SNMP type, add aditional information.
@ -377,7 +377,7 @@ class PhysicalDevice():
# Only insert groups in front of list for Zabbix7 # Only insert groups in front of list for Zabbix7
proxy_types.insert(0, "proxy_group") proxy_types.insert(0, "proxy_group")
for proxy_type in proxy_types: for proxy_type in proxy_types:
# Check if the key exists in Netbox CC # Check if the key exists in NetBox CC
if proxy_type in self.nb.config_context["zabbix"]: if proxy_type in self.nb.config_context["zabbix"]:
proxy_name = self.nb.config_context["zabbix"][proxy_type] proxy_name = self.nb.config_context["zabbix"][proxy_type]
# go through all proxies # go through all proxies
@ -395,9 +395,9 @@ class PhysicalDevice():
return False 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."):
""" """
Creates Zabbix host object with parameters from Netbox object. Creates Zabbix host object with parameters from NetBox object.
""" """
# Check if hostname is already present in Zabbix # Check if hostname is already present in Zabbix
if not self._zabbixHostnameExists(): if not self._zabbixHostnameExists():
@ -445,7 +445,7 @@ class PhysicalDevice():
e = f"Host {self.name}: Couldn't create. Zabbix returned {str(e)}." e = f"Host {self.name}: Couldn't create. Zabbix returned {str(e)}."
self.logger.error(e) self.logger.error(e)
raise SyncExternalError(e) from None raise SyncExternalError(e) from None
# Set Netbox custom field to hostID value. # Set NetBox custom field to hostID value.
self.nb.custom_fields[device_cf] = int(self.zabbix_id) self.nb.custom_fields[device_cf] = int(self.zabbix_id)
self.nb.save() self.nb.save()
msg = f"Host {self.name}: Created host in Zabbix." msg = f"Host {self.name}: Created host in Zabbix."
@ -511,7 +511,7 @@ class PhysicalDevice():
def ConsistencyCheck(self, groups, templates, proxies, proxy_power, create_hostgroups): def ConsistencyCheck(self, groups, templates, proxies, proxy_power, create_hostgroups):
# pylint: disable=too-many-branches, too-many-statements # pylint: disable=too-many-branches, too-many-statements
""" """
Checks if Zabbix object is still valid with Netbox parameters. Checks if Zabbix object is still valid with NetBox parameters.
""" """
# If group is found or if the hostgroup is nested # 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.hostgroup.split('/')) > 1:
@ -548,7 +548,7 @@ class PhysicalDevice():
if len(host) == 0: if len(host) == 0:
e = (f"Host {self.name}: No Zabbix host found. " e = (f"Host {self.name}: No Zabbix host found. "
f"This is likely the result of a deleted Zabbix host " f"This is likely the result of a deleted Zabbix host "
f"without zeroing the ID field in Netbox.") f"without zeroing the ID field in NetBox.")
self.logger.error(e) self.logger.error(e)
raise SyncInventoryError(e) raise SyncInventoryError(e)
host = host[0] host = host[0]
@ -615,7 +615,7 @@ class PhysicalDevice():
"monitored_by": self.zbxproxy['monitored_by']} "monitored_by": self.zbxproxy['monitored_by']}
self.updateZabbixHost(**update_data) self.updateZabbixHost(**update_data)
else: else:
# No proxy is defined in Netbox # No proxy is defined in NetBox
proxy_set = False proxy_set = False
# Check if a proxy is defined. Uses the proxy_hostid key for backwards compatibility # Check if a proxy is defined. Uses the proxy_hostid key for backwards compatibility
for key in ("proxy_hostid", "proxyid", "proxy_groupid"): for key in ("proxy_hostid", "proxyid", "proxy_groupid"):
@ -624,7 +624,7 @@ class PhysicalDevice():
proxy_set = True proxy_set = True
if proxy_power and proxy_set: if proxy_power and proxy_set:
# Zabbix <= 6 fix # Zabbix <= 6 fix
self.logger.warning(f"Host {self.name}: no proxy is configured in Netbox " self.logger.warning(f"Host {self.name}: no proxy is configured in NetBox "
"but is configured in Zabbix. Removing proxy config in Zabbix") "but is configured in Zabbix. Removing proxy config in Zabbix")
if "proxy_hostid" in host and bool(host["proxy_hostid"]): if "proxy_hostid" in host and bool(host["proxy_hostid"]):
self.updateZabbixHost(proxy_hostid=0) self.updateZabbixHost(proxy_hostid=0)
@ -638,7 +638,7 @@ class PhysicalDevice():
if proxy_set and not proxy_power: if proxy_set and not proxy_power:
# Display error message # Display error message
self.logger.error(f"Host {self.name} is configured " self.logger.error(f"Host {self.name} is configured "
f"with proxy in Zabbix but not in Netbox. The" f"with proxy in Zabbix but not in NetBox. The"
" -p flag was ommited: no " " -p flag was ommited: no "
"changes have been made.") "changes have been made.")
if not proxy_set: if not proxy_set:
@ -663,7 +663,7 @@ class PhysicalDevice():
updates = {} updates = {}
# Go through each key / item and check if it matches Zabbix # Go through each key / item and check if it matches Zabbix
for key, item in self.setInterfaceDetails()[0].items(): for key, item in self.setInterfaceDetails()[0].items():
# Check if Netbox value is found in Zabbix # Check if NetBox value is found in Zabbix
if key in host["interfaces"][0]: if key in host["interfaces"][0]:
# If SNMP is used, go through nested dict # If SNMP is used, go through nested dict
# to compare SNMP parameters # to compare SNMP parameters
@ -724,8 +724,8 @@ class PhysicalDevice():
def create_journal_entry(self, severity, message): def create_journal_entry(self, severity, message):
""" """
Send a new Journal entry to Netbox. Usefull for viewing actions Send a new Journal entry to NetBox. Usefull for viewing actions
in Netbox without having to look in Zabbix or the script log output in NetBox without having to look in Zabbix or the script log output
""" """
if self.journal: if self.journal:
# Check if the severity is valid # Check if the severity is valid
@ -739,7 +739,7 @@ class PhysicalDevice():
} }
try: try:
self.nb_journals.create(journal) self.nb_journals.create(journal)
self.logger.debug(f"Host {self.name}: Created journal entry in Netbox") self.logger.debug(f"Host {self.name}: Created journal entry in NetBox")
return True return True
except JournalError(e) as e: except JournalError(e) as e:
self.logger.warning("Unable to create journal entry for " self.logger.warning("Unable to create journal entry for "
@ -749,14 +749,14 @@ class PhysicalDevice():
def zbx_template_comparer(self, tmpls_from_zabbix): def zbx_template_comparer(self, tmpls_from_zabbix):
""" """
Compares the Netbox and Zabbix templates with each other. Compares the NetBox and Zabbix templates with each other.
Should there be a mismatch then the function will return false Should there be a mismatch then the function will return false
INPUT: list of NB and ZBX templates INPUT: list of NB and ZBX templates
OUTPUT: Boolean True/False OUTPUT: Boolean True/False
""" """
succesfull_templates = [] succesfull_templates = []
# Go through each Netbox template # Go through each NetBox template
for nb_tmpl in self.zbx_templates: for nb_tmpl in self.zbx_templates:
# Go through each Zabbix template # Go through each Zabbix template
for pos, zbx_tmpl in enumerate(tmpls_from_zabbix): for pos, zbx_tmpl in enumerate(tmpls_from_zabbix):
@ -770,7 +770,7 @@ class PhysicalDevice():
f"{nb_tmpl['name']} is present in Zabbix.") f"{nb_tmpl['name']} is present in Zabbix.")
break break
if len(succesfull_templates) == len(self.zbx_templates) and len(tmpls_from_zabbix) == 0: if len(succesfull_templates) == len(self.zbx_templates) and len(tmpls_from_zabbix) == 0:
# All of the Netbox templates have been confirmed as successfull # All of the NetBox templates have been confirmed as successfull
# and the ZBX template list is empty. This means that # and the ZBX template list is empty. This means that
# all of the templates match. # all of the templates match.
return True return True

View File

@ -34,7 +34,7 @@ class Hostgroup():
format_options = {} format_options = {}
# Set variables for both type of devices # Set variables for both type of devices
if self.type in ("vm", "dev"): if self.type in ("vm", "dev"):
# Role fix for Netbox <=3 # Role fix for NetBox <=3
role = None role = None
if self.nb_version.startswith(("2", "3")) and self.type == "dev": if self.nb_version.startswith(("2", "3")) and self.type == "dev":
role = self.nb.device_role.name if self.nb.device_role else None role = self.nb.device_role.name if self.nb.device_role else None
@ -129,7 +129,7 @@ class Hostgroup():
def custom_field_lookup(self, hg_category): def custom_field_lookup(self, hg_category):
""" """
Checks if a valid custom field is present in Netbox. Checks if a valid custom field is present in NetBox.
INPUT: Custom field name INPUT: Custom field name
OUTPUT: dictionary with 'result' and 'cf' keys. OUTPUT: dictionary with 'result' and 'cf' keys.
""" """

View File

@ -29,7 +29,7 @@ class ZabbixInterface():
return True return True
def get_context(self): def get_context(self):
""" check if Netbox custom context has been defined. """ """ check if NetBox custom context has been defined. """
if "zabbix" in self.context: if "zabbix" in self.context:
zabbix = self.context["zabbix"] zabbix = self.context["zabbix"]
if "interface_type" in zabbix: if "interface_type" in zabbix:
@ -46,7 +46,7 @@ class ZabbixInterface():
""" Check if interface is type SNMP """ """ Check if interface is type SNMP """
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
if self.interface["type"] == 2: if self.interface["type"] == 2:
# Checks if SNMP settings are defined in Netbox # Checks if SNMP settings are defined in NetBox
if "snmp" in self.context["zabbix"]: if "snmp" in self.context["zabbix"]:
snmp = self.context["zabbix"]["snmp"] snmp = self.context["zabbix"]["snmp"]
self.interface["details"] = {} self.interface["details"] = {}
@ -56,7 +56,7 @@ class ZabbixInterface():
else: else:
# Fallback to bulk enabled if not specified # Fallback to bulk enabled if not specified
self.interface["details"]["bulk"] = "1" self.interface["details"]["bulk"] = "1"
# SNMP Version config is required in Netbox config context # SNMP Version config is required in NetBox config context
if snmp.get("version"): if snmp.get("version"):
self.interface["details"]["version"] = str(snmp.pop("version")) self.interface["details"]["version"] = str(snmp.pop("version"))
else: else:
@ -72,7 +72,7 @@ class ZabbixInterface():
community = "{$SNMP_COMMUNITY}" community = "{$SNMP_COMMUNITY}"
self.interface["details"]["community"] = str(community) self.interface["details"]["community"] = str(community)
# If version 3 has been used, get all # If version 3 has been used, get all
# SNMPv3 Netbox related configs # SNMPv3 NetBox related configs
elif self.interface["details"]["version"] == '3': elif self.interface["details"]["version"] == '3':
items = ["securityname", "securitylevel", "authpassphrase", items = ["securityname", "securitylevel", "authpassphrase",
"privpassphrase", "authprotocol", "privprotocol", "privpassphrase", "authprotocol", "privprotocol",

View File

@ -50,7 +50,7 @@ class VirtualMachine(PhysicalDevice):
try: try:
# Initiate interface class # Initiate interface class
interface = ZabbixInterface(self.nb.config_context, self.ip) interface = ZabbixInterface(self.nb.config_context, self.ip)
# Check if Netbox has device context. # Check if NetBox has device context.
# If not fall back to old config. # If not fall back to old config.
if interface.get_context(): if interface.get_context():
# If device is SNMP type, add aditional information. # If device is SNMP type, add aditional information.

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# pylint: disable=invalid-name, logging-not-lazy, too-many-locals, logging-fstring-interpolation # pylint: disable=invalid-name, logging-not-lazy, too-many-locals, logging-fstring-interpolation
"""Netbox to Zabbix sync script.""" """NetBox to Zabbix sync script."""
import logging import logging
import argparse import argparse
import ssl import ssl
@ -45,7 +45,7 @@ lgfile = logging.FileHandler(path.join(path.dirname(
lgfile.setFormatter(log_format) lgfile.setFormatter(log_format)
lgfile.setLevel(logging.DEBUG) lgfile.setLevel(logging.DEBUG)
logger = logging.getLogger("Netbox-Zabbix-sync") logger = logging.getLogger("NetBox-Zabbix-sync")
logger.addHandler(lgout) logger.addHandler(lgout)
logger.addHandler(lgfile) logger.addHandler(lgfile)
logger.setLevel(logging.WARNING) logger.setLevel(logging.WARNING)
@ -80,7 +80,7 @@ def main(arguments):
zabbix_host = environ.get("ZABBIX_HOST") zabbix_host = environ.get("ZABBIX_HOST")
netbox_host = environ.get("NETBOX_HOST") netbox_host = environ.get("NETBOX_HOST")
netbox_token = environ.get("NETBOX_TOKEN") netbox_token = environ.get("NETBOX_TOKEN")
# Set Netbox API # Set NetBox API
netbox = api(netbox_host, token=netbox_token, threading=True) netbox = api(netbox_host, token=netbox_token, threading=True)
# Check if the provided Hostgroup layout is valid # Check if the provided Hostgroup layout is valid
hg_objects = hostgroup_format.split("/") hg_objects = hostgroup_format.split("/")
@ -91,11 +91,11 @@ def main(arguments):
device_cfs = list(netbox.extras.custom_fields.filter( device_cfs = list(netbox.extras.custom_fields.filter(
type="text", content_type_id=23)) type="text", content_type_id=23))
except RequestsConnectionError: except RequestsConnectionError:
logger.error(f"Unable to connect to Netbox with URL {netbox_host}." logger.error(f"Unable to connect to NetBox with URL {netbox_host}."
" Please check the URL and status of Netbox.") " Please check the URL and status of NetBox.")
sys.exit(1) sys.exit(1)
except NBRequestError as e: except NBRequestError as e:
logger.error(f"Netbox error: {e}") logger.error(f"NetBox error: {e}")
sys.exit(1) sys.exit(1)
for cf in device_cfs: for cf in device_cfs:
allowed_objects.append(cf.name) allowed_objects.append(cf.name)
@ -129,7 +129,7 @@ def main(arguments):
proxy_name = "host" proxy_name = "host"
else: else:
proxy_name = "name" proxy_name = "name"
# Get all Zabbix and Netbox data # Get all Zabbix and NetBox data
netbox_devices = list(netbox.dcim.devices.filter(**nb_device_filter)) netbox_devices = list(netbox.dcim.devices.filter(**nb_device_filter))
netbox_vms = [] netbox_vms = []
if sync_vms: if sync_vms:
@ -153,10 +153,10 @@ def main(arguments):
# Prepare list of all proxy and proxy_groups # Prepare list of all proxy and proxy_groups
zabbix_proxy_list = proxy_prepper(zabbix_proxies, zabbix_proxygroups) zabbix_proxy_list = proxy_prepper(zabbix_proxies, zabbix_proxygroups)
# Get Netbox API version # Get NetBox API version
nb_version = netbox.version nb_version = netbox.version
# Go through all Netbox devices # Go through all NetBox devices
for nb_vm in netbox_vms: for nb_vm in netbox_vms:
try: try:
vm = VirtualMachine(nb_vm, zabbix, netbox_journals, nb_version, vm = VirtualMachine(nb_vm, zabbix, netbox_journals, nb_version,
@ -175,11 +175,11 @@ def main(arguments):
if vm.status in zabbix_device_removal: if vm.status in zabbix_device_removal:
if vm.zabbix_id: if vm.zabbix_id:
# Delete device from Zabbix # Delete device from Zabbix
# and remove hostID from Netbox. # and remove hostID from NetBox.
vm.cleanup() vm.cleanup()
logger.info(f"VM {vm.name}: cleanup complete") logger.info(f"VM {vm.name}: cleanup complete")
continue continue
# Device has been added to Netbox # Device has been added to NetBox
# but is not in Activate state # but is not in Activate state
logger.info(f"VM {vm.name}: skipping since this VM is " logger.info(f"VM {vm.name}: skipping since this VM is "
f"not in the active state.") f"not in the active state.")
@ -243,11 +243,11 @@ def main(arguments):
if device.status in zabbix_device_removal: if device.status in zabbix_device_removal:
if device.zabbix_id: if device.zabbix_id:
# Delete device from Zabbix # Delete device from Zabbix
# and remove hostID from Netbox. # and remove hostID from NetBox.
device.cleanup() device.cleanup()
logger.info(f"Device {device.name}: cleanup complete") logger.info(f"Device {device.name}: cleanup complete")
continue continue
# Device has been added to Netbox # Device has been added to NetBox
# but is not in Activate state # but is not in Activate state
logger.info(f"Device {device.name}: skipping since this device is " logger.info(f"Device {device.name}: skipping since this device is "
f"not in the active state.") f"not in the active state.")
@ -278,7 +278,7 @@ def main(arguments):
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='A script to sync Zabbix with Netbox device data.' description='A script to sync Zabbix with NetBox device data.'
) )
parser.add_argument("-v", "--verbose", help="Turn on debugging.", parser.add_argument("-v", "--verbose", help="Turn on debugging.",
action="store_true") action="store_true")