Added support for Zabbix API tokens and updated README.md

This commit is contained in:
Raymond Kuiper 2024-03-01 08:51:07 +01:00
parent 1f4a81e2e4
commit c8e42b366f
2 changed files with 36 additions and 15 deletions

View File

@ -12,20 +12,20 @@ git clone https://github.com/TheNetworkGuy/netbox-zabbix-sync.git
``` ```
### Packages ### Packages
Make sure that you have a python environment with the following packages installed. You can also use the requirements.txt file for installation with pip. Make sure that you have a python environment with the following packages installed. You can also use the `requirements.txt` file for installation with pip.
``` ```
pynetbox pynetbox
pyzabbix pyzabbix
``` ```
### Config file ### Config file
First time user? Copy the config.py.example file to config.py. This file is used for modifying filters and setting variables such as custom field names. First time user? Copy the `config.py.example` file to `config.py`. This file is used for modifying filters and setting variables such as custom field names.
``` ```
cp config.py.example config.py cp config.py.example config.py
``` ```
### Set environment variables ### Set environment variables
Set the following environment variables Set the following environment variables:
``` ```
ZABBIX_HOST="https://zabbix.local" ZABBIX_HOST="https://zabbix.local"
ZABBIX_USER="username" ZABBIX_USER="username"
@ -33,6 +33,14 @@ ZABBIX_PASS="Password"
NETBOX_HOST="https://netbox.local" NETBOX_HOST="https://netbox.local"
NETBOX_TOKEN="secrettoken" NETBOX_TOKEN="secrettoken"
``` ```
Or, you can use a Zabbix API token to login instead of using a username and password.
In that case `ZABBIX_USER` and `ZABBIX_PASS` will be ignored.
```
ZABBIX_TOKEN=othersecrettoken
```
### Netbox custom fields ### Netbox custom fields
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): 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):
``` ```
@ -49,16 +57,16 @@ Use the following custom fields in Netbox (if you are using config context for t
* Default: null * Default: null
* Object: dcim > device_type * Object: dcim > device_type
``` ```
You can make the hostID field hidden or read-only to prevent human intervention. You can make the `zabbix_hostid` field hidden or read-only to prevent human intervention.
This is optional and there is a use case for leaving it read-write in the UI to manually change the ID. For example to re-run a sync. This is optional and there is a use case for leaving it read-write in the UI to manually change the ID. For example to re-run a sync.
## Config file ## Config file
### Hostgroup ### Hostgroup
Setting the create_hostgroups variable to False requires manual hostgroup creation for devices in a new category. Setting the `create_hostgroups` variable to `False` requires manual hostgroup creation for devices in a new category.
The format can be set with the hostgroup_format variable. The format can be set with the `hostgroup_format` variable.
Make sure that the Zabbix user has proper permissions to create hosts. Make sure that the Zabbix user has proper permissions to create hosts.
The hostgroups are in a nested format. This means that proper permissions only need to be applied to the site name hostgroup and cascaded to any child hostgroups. The hostgroups are in a nested format. This means that proper permissions only need to be applied to the site name hostgroup and cascaded to any child hostgroups.
@ -127,8 +135,8 @@ By setting a status on a Netbox device you determine how the host is added (or u
* Create the host in Zabbix with an enabled status (For now only enabled with the "Active" status) * Create the host in Zabbix with an enabled status (For now only enabled with the "Active" status)
You can modify this behaviour by changing the following list variables in the script: You can modify this behaviour by changing the following list variables in the script:
- zabbix_device_removal - `zabbix_device_removal`
- zabbix_device_disable - `zabbix_device_disable`
### Template source ### Template source
You can either use a Netbox device type custom field or Netbox config context for the Zabbix template information. You can either use a Netbox device type custom field or Netbox config context for the Zabbix template information.
@ -197,7 +205,7 @@ You can set the proxy for a device using the 'proxy' key in config context.
} }
} }
``` ```
Because of the posible amount of destruction when setting up Netbox but 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 configured but nothing is configured in Netbox. To force deletion and a full sync, set the full_proxy_sync variable in the config file. Because of the possible amount of destruction when setting up Netbox but 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 configured but nothing is configured in Netbox. To force deletion and a full 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 default, the following configuration is applied when no config context is provided: 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 provided:

View File

@ -48,17 +48,24 @@ def main(arguments):
# set environment variables # set environment variables
if(arguments.verbose): if(arguments.verbose):
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
env_vars = ["ZABBIX_HOST", "ZABBIX_USER", "ZABBIX_PASS", env_vars = ["ZABBIX_HOST", "NETBOX_HOST", "NETBOX_TOKEN"]
"NETBOX_HOST", "NETBOX_TOKEN"] if "ZABBIX_TOKEN" in environ:
env_vars.append("ZABBIX_TOKEN")
else:
env_vars.append("ZABBIX_USER")
env_vars.append("ZABBIX_PASS")
for var in env_vars: for var in env_vars:
if var not in environ: if var not in environ:
e = f"Environment variable {var} has not been defined." e = f"Environment variable {var} has not been defined."
logger.error(e) logger.error(e)
raise EnvironmentVarError(e) raise EnvironmentVarError(e)
# Get all virtual environment variables # Get all virtual environment variables
if "ZABBIX_TOKEN" in env_vars:
zabbix_token = environ.get("ZABBIX_TOKEN")
else:
zabbix_user = environ.get("ZABBIX_USER")
zabbix_pass = environ.get("ZABBIX_PASS")
zabbix_host = environ.get("ZABBIX_HOST") zabbix_host = environ.get("ZABBIX_HOST")
zabbix_user = environ.get("ZABBIX_USER")
zabbix_pass = environ.get("ZABBIX_PASS")
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
@ -80,7 +87,13 @@ def main(arguments):
# Set Zabbix API # Set Zabbix API
try: try:
zabbix = ZabbixAPI(zabbix_host) zabbix = ZabbixAPI(zabbix_host)
zabbix.login(zabbix_user, zabbix_pass) if "ZABBIX_TOKEN" in env_vars:
zabbix.login(api_token=zabbix_token)
else:
m=(f"Logging in with Zabbix user and password,"
" consider using an API token instead.")
logger.warning(m)
zabbix.login(zabbix_user, zabbix_pass)
except ZabbixAPIException as e: except ZabbixAPIException as e:
e = f"Zabbix returned the following error: {str(e)}." e = f"Zabbix returned the following error: {str(e)}."
logger.error(e) logger.error(e)