Skip to content

Commit

Permalink
Fixes #70
Browse files Browse the repository at this point in the history
  • Loading branch information
TheNetworkGuy committed Jul 24, 2024
1 parent c0c52f9 commit d1ec111
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 26 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,9 @@ You can modify this behaviour by changing the following list variables in the sc

### Zabbix Inventory
This script allows you to enable the inventory on managed Zabbix hosts and sync NetBox device properties to the specified inventory fields.
To enable, set `inventory_sync` to `True`.
Set `inventory_automatic` to `False` to use manual inventory, or `True` for automatic.
To map Netbox information to Netbox inventory fields, set `inventory_sync` to `True`.

You can set the inventory mode to "disabled", "manual" or "automatic" with the inventory_mode variable.
See [Zabbix Manual](https://www.zabbix.com/documentation/current/en/manual/config/hosts/inventory#building-inventory) for more information about the modes.

Use the `inventory_map` variable to map which NetBox properties are used in which Zabbix Inventory fields.
Expand Down
9 changes: 5 additions & 4 deletions config.py.example
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,14 @@ traverse_site_groups = False
nb_device_filter = {"name__n": "null"}

## Inventory
# See https://www.zabbix.com/documentation/current/en/manual/config/hosts/inventory#building-inventory
# Choice between disabled, manual or automatic.
# Make sure to select at least manual or automatic in use with the inventory_sync function.
inventory_mode = "disabled"

# To allow syncing of NetBox device properties, set inventory_sync to True
inventory_sync = False

# Set inventory_automatic to False to use manual inventory, True for automatic
# See https://www.zabbix.com/documentation/current/en/manual/config/hosts/inventory#building-inventory
inventory_automatic = True

# inventory_map is used to map NetBox properties to Zabbix Inventory fields.
# For nested properties, you can use the '/' seperator.
# For example, the following map will assign the custom field 'mycustomfield' to the 'alias' Zabbix inventory field:
Expand Down
51 changes: 31 additions & 20 deletions modules/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
traverse_site_groups,
traverse_regions,
inventory_sync,
inventory_automatic,
inventory_mode,
inventory_map
)
except ModuleNotFoundError:
Expand Down Expand Up @@ -196,12 +196,23 @@ def get_templates_context(self):

def set_inventory(self, nbdevice):
""" Set host inventory """
self.inventory_mode = -1
# Set inventory mode. Default is disabled (see class init function).
if inventory_mode == "disabled":
if inventory_sync:
self.logger.error(f"Device {self.name}: Unable to map Netbox inventory to Zabbix. "
"Inventory sync is enabled in config but inventory mode is disabled.")
return True
if inventory_mode == "manual":
self.inventory_mode = 0
elif inventory_mode == "automatic":
self.inventory_mode = 1
else:
self.logger.error(f"Device {self.name}: Specified value for inventory mode in"
f" config is not valid. Got value {inventory_mode}")
return False
self.inventory = {}
if inventory_sync:
# Set inventory mode to automatic or manual
self.inventory_mode = 1 if inventory_automatic else 0

if inventory_sync and self.inventory_mode in [0,1]:
self.logger.debug(f"Device {self.name}: Starting inventory mapper")
# Let's build an inventory dict for each property in the inventory_map
for nb_inv_field, zbx_inv_field in inventory_map.items():
field_list = nb_inv_field.split("/") # convert str to list based on delimiter
Expand All @@ -218,13 +229,15 @@ def set_inventory(self, nbdevice):
self.inventory[zbx_inv_field] = str(value)
elif not value:
# empty value should just be an empty string for API compatibility
self.logger.debug(f"Inventory lookup for '{nb_inv_field}'"
" returned an empty value")
self.logger.debug(f"Device {self.name}: Netbox inventory lookup for "
f"'{nb_inv_field}' returned an empty value")
self.inventory[zbx_inv_field] = ""
else:
# Value is not a string or numeral, probably not what the user expected.
self.logger.error(f"Inventory lookup for '{nb_inv_field}' returned"
" an unexpected type: it will be skipped.")
self.logger.error(f"Device {self.name}: Inventory lookup for '{nb_inv_field}'"
" returned an unexpected type: it will be skipped.")
self.logger.debug(f"Device {self.name}: Inventory mapping complete. "
f"Mapped {len(list(filter(None, self.inventory.values())))} field(s)")
return True

def isCluster(self):
Expand Down Expand Up @@ -617,16 +630,14 @@ def ConsistencyCheck(self, groups, templates, proxies, proxy_power, create_hostg
"changes have been made.")
if not proxy_set:
self.logger.debug(f"Device {self.name}: proxy in-sync.")
# Check host inventory
if inventory_sync:
# check inventory mode first, as we need it set to parse
# actual inventory values
if str(host['inventory_mode']) == str(self.inventory_mode):
self.logger.debug(f"Device {self.name}: inventory_mode in-sync.")
else:
self.logger.warning(f"Device {self.name}: inventory_mode OUT of sync.")
self.updateZabbixHost(inventory_mode=str(self.inventory_mode))
# Now we can check if inventory is in-sync.
# Check host inventory mode
if str(host['inventory_mode']) == str(self.inventory_mode):
self.logger.debug(f"Device {self.name}: inventory_mode in-sync.")
else:
self.logger.warning(f"Device {self.name}: inventory_mode OUT of sync.")
self.updateZabbixHost(inventory_mode=str(self.inventory_mode))
if inventory_sync and self.inventory_mode in [0,1]:
# Check host inventory mapping
if host['inventory'] == self.inventory:
self.logger.debug(f"Device {self.name}: inventory in-sync.")
else:
Expand Down

0 comments on commit d1ec111

Please sign in to comment.