mirror of
https://github.com/TheNetworkGuy/netbox-zabbix-sync.git
synced 2025-07-14 01:41:25 -06:00
Added functionality to build full region and site_group paths to be used in hostgroup names.
This commit is contained in:
parent
b94a0df02d
commit
71f604a6f6
@ -119,6 +119,11 @@ You can specify the value like so, sperated by a "/":
|
|||||||
```
|
```
|
||||||
hostgroup_format = "tenant/site/dev_location/dev_role"
|
hostgroup_format = "tenant/site/dev_location/dev_role"
|
||||||
```
|
```
|
||||||
|
** Group traversal **
|
||||||
|
The default behaviour for `region` is to only use the directly assigned region in the rendered hostgroup name.
|
||||||
|
However, by setting `traverse_region` to `True` in `config.py` the script will render a full region path of all parent regions for the hostgroup name.
|
||||||
|
`traverse_site_groups` controls the same behaviour for site_groups.
|
||||||
|
|
||||||
**custom fields**
|
**custom fields**
|
||||||
|
|
||||||
You can also use the value of custom fields under the device object.
|
You can also use the value of custom fields under the device object.
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
# Template logic.
|
## Template logic.
|
||||||
# Set to true to enable the template source information
|
# Set to true to enable the template source information
|
||||||
# coming from config context instead of a custom field.
|
# coming from config context instead of a custom field.
|
||||||
templates_config_context = False
|
templates_config_context = False
|
||||||
|
|
||||||
# Set to true to give config context templates a
|
# Set to true to give config context templates a
|
||||||
# higher priority then custom field templates
|
# higher priority then custom field templates
|
||||||
templates_config_context_overrule = False
|
templates_config_context_overrule = False
|
||||||
@ -11,37 +12,47 @@ templates_config_context_overrule = False
|
|||||||
template_cf = "zabbix_template"
|
template_cf = "zabbix_template"
|
||||||
device_cf = "zabbix_hostid"
|
device_cf = "zabbix_hostid"
|
||||||
|
|
||||||
# Enable clustering of devices with virtual chassis setup
|
## Enable clustering of devices with virtual chassis setup
|
||||||
clustering = False
|
clustering = False
|
||||||
|
|
||||||
# Enable hostgroup generation. Requires permissions in Zabbix
|
## Enable hostgroup generation. Requires permissions in Zabbix
|
||||||
create_hostgroups = True
|
create_hostgroups = True
|
||||||
|
|
||||||
# Create journal entries
|
## Create journal entries
|
||||||
create_journal = False
|
create_journal = False
|
||||||
|
|
||||||
|
## Proxy Sync
|
||||||
# Set to true to enable removal of proxy's under hosts. Use with caution and make sure that you specified
|
# Set to true to enable removal of proxy's under hosts. Use with caution and make sure that you specified
|
||||||
# all the required proxy's in the device config context before enabeling this option.
|
# all the required proxy's in the device config context before enabeling this option.
|
||||||
# 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"]
|
||||||
|
|
||||||
# Hostgroup mapping
|
## Hostgroup mapping
|
||||||
# Available choices: dev_location, dev_role, manufacturer, region, site, site_group, tenant, tenant_group
|
# Available choices: dev_location, dev_role, manufacturer, region, site, site_group, tenant, tenant_group
|
||||||
# You can also use CF (custom field) names under the device. The CF content will be used for the hostgroup generation.
|
# You can also use CF (custom field) names under the device. The CF content will be used for the hostgroup generation.
|
||||||
|
#
|
||||||
|
# When using region in the group name, the default behaviour is to use name of the directly assigned region.
|
||||||
|
# By setting traverse_regions to True the full path of all parent regions will be used in the hostgroup, e.g.:
|
||||||
|
#
|
||||||
|
# 'Global/Europe/Netherlands/Amsterdam' instead of just 'Amsterdam'.
|
||||||
|
#
|
||||||
|
# traverse_site_groups controls the same behaviour for any assigned site_groups.
|
||||||
hostgroup_format = "site/manufacturer/dev_role"
|
hostgroup_format = "site/manufacturer/dev_role"
|
||||||
|
traverse_regions = False
|
||||||
|
traverse_site_groups = False
|
||||||
|
|
||||||
# Custom filter for device filtering. Variable must be present but can be left empty with no filtering.
|
## Filtering
|
||||||
# A couple of examples are as follows:
|
# Custom device filter, variable must be present but can be left empty with no filtering.
|
||||||
|
# A couple of examples:
|
||||||
|
# nb_device_filter = {} #No filter
|
||||||
|
# nb_device_filter = {"tag": "zabbix"} #Use a tag
|
||||||
|
# nb_device_filter = {"site": "HQ-AMS"} #Use a site name
|
||||||
|
# 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 = {} #No filter
|
# Default device filter, only get devices which have a name in Netbox:
|
||||||
# nb_device_filter = {"tag": "zabbix"} #Use a tag
|
|
||||||
# nb_device_filter = {"site": "HQ-AMS"} #Use a site name
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# Default device filter, only get devices which have a name in Netbox.
|
|
||||||
nb_device_filter = {"name__n": "null"}
|
nb_device_filter = {"name__n": "null"}
|
@ -20,6 +20,8 @@ try:
|
|||||||
zabbix_device_removal,
|
zabbix_device_removal,
|
||||||
zabbix_device_disable,
|
zabbix_device_disable,
|
||||||
hostgroup_format,
|
hostgroup_format,
|
||||||
|
traverse_site_groups,
|
||||||
|
traverse_regions,
|
||||||
nb_device_filter
|
nb_device_filter
|
||||||
)
|
)
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
@ -45,6 +47,30 @@ logger.addHandler(lgfile)
|
|||||||
logger.setLevel(logging.WARNING)
|
logger.setLevel(logging.WARNING)
|
||||||
|
|
||||||
|
|
||||||
|
def convert_recordset(recordset):
|
||||||
|
""" Converts netbox RedcordSet to list of dicts. """
|
||||||
|
recordlist = []
|
||||||
|
for record in recordset:
|
||||||
|
recordlist.append(record.__dict__)
|
||||||
|
return recordlist
|
||||||
|
|
||||||
|
def build_path(endpoint, list_of_dicts):
|
||||||
|
"""
|
||||||
|
Builds a path list of related parent/child items.
|
||||||
|
This can be used to generate a joinable list to
|
||||||
|
be used in hostgroups.
|
||||||
|
"""
|
||||||
|
path = []
|
||||||
|
itemlist = [i for i in list_of_dicts if i['name'] == endpoint]
|
||||||
|
item = itemlist[0] if len(itemlist) == 1 else None
|
||||||
|
path.append(item['name'])
|
||||||
|
while item['_depth'] > 0:
|
||||||
|
itemlist = [i for i in list_of_dicts if i['name'] == str(item['parent'])]
|
||||||
|
item = itemlist[0] if len(itemlist) == 1 else None
|
||||||
|
path.append(item['name'])
|
||||||
|
path.reverse()
|
||||||
|
return(path)
|
||||||
|
|
||||||
def main(arguments):
|
def main(arguments):
|
||||||
"""Run the sync process."""
|
"""Run the sync process."""
|
||||||
# pylint: disable=too-many-branches, too-many-statements
|
# pylint: disable=too-many-branches, too-many-statements
|
||||||
@ -110,6 +136,8 @@ 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_site_groups = convert_recordset((netbox.dcim.site_groups.all()))
|
||||||
|
netbox_regions = convert_recordset(netbox.dcim.regions.all())
|
||||||
netbox_journals = netbox.extras.journal_entries
|
netbox_journals = netbox.extras.journal_entries
|
||||||
zabbix_groups = zabbix.hostgroup.get(output=['groupid', 'name'])
|
zabbix_groups = zabbix.hostgroup.get(output=['groupid', 'name'])
|
||||||
zabbix_templates = zabbix.template.get(output=['templateid', 'name'])
|
zabbix_templates = zabbix.template.get(output=['templateid', 'name'])
|
||||||
@ -125,7 +153,7 @@ def main(arguments):
|
|||||||
try:
|
try:
|
||||||
device = NetworkDevice(nb_device, zabbix, netbox_journals,
|
device = NetworkDevice(nb_device, zabbix, netbox_journals,
|
||||||
create_journal)
|
create_journal)
|
||||||
device.set_hostgroup(hostgroup_format)
|
device.set_hostgroup(hostgroup_format,netbox_site_groups,netbox_regions)
|
||||||
device.set_template(templates_config_context, templates_config_context_overrule)
|
device.set_template(templates_config_context, templates_config_context_overrule)
|
||||||
# Checks if device is part of cluster.
|
# Checks if device is part of cluster.
|
||||||
# Requires clustering variable
|
# Requires clustering variable
|
||||||
@ -259,7 +287,7 @@ class NetworkDevice():
|
|||||||
logger.warning(e)
|
logger.warning(e)
|
||||||
raise SyncInventoryError(e)
|
raise SyncInventoryError(e)
|
||||||
|
|
||||||
def set_hostgroup(self, hg_format):
|
def set_hostgroup(self, hg_format, nb_site_groups, nb_regions):
|
||||||
"""Set the hostgroup for this device"""
|
"""Set the hostgroup for this device"""
|
||||||
# Get all variables from the NB data
|
# Get all variables from the NB data
|
||||||
dev_location = str(self.nb.location) if self.nb.location else None
|
dev_location = str(self.nb.location) if self.nb.location else None
|
||||||
@ -293,7 +321,14 @@ class NetworkDevice():
|
|||||||
# the variable is invalid. Skip regardless.
|
# the variable is invalid. Skip regardless.
|
||||||
continue
|
continue
|
||||||
# Add value of predefined variable to hostgroup format
|
# Add value of predefined variable to hostgroup format
|
||||||
hostgroup += hostgroup_vars[item] + "/"
|
if item == "site_group" and nb_site_groups and traverse_site_groups:
|
||||||
|
path = build_path(site_group, nb_site_groups)
|
||||||
|
hostgroup += "/".join(path) + "/"
|
||||||
|
elif item == "region" and nb_regions and traverse_regions:
|
||||||
|
path = build_path(region, nb_regions)
|
||||||
|
hostgroup += "/".join(path) + "/"
|
||||||
|
else:
|
||||||
|
hostgroup += hostgroup_vars[item] + "/"
|
||||||
# If the final hostgroup variable is empty
|
# If the final hostgroup variable is empty
|
||||||
if not hostgroup:
|
if not hostgroup:
|
||||||
e = (f"{self.name} has no reliable hostgroup. This is"
|
e = (f"{self.name} has no reliable hostgroup. This is"
|
||||||
|
Loading…
Reference in New Issue
Block a user