From cef24a768db598ce449510dce8789d68bac09e3e Mon Sep 17 00:00:00 2001 From: Twan Kamans Date: Thu, 29 Apr 2021 09:40:23 +0200 Subject: [PATCH] Updated README and modified interface update log messages. --- README.md | 13 +++++++++++-- netbox_zabbix_sync.py | 17 +++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3e72926..f83323e 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ A script to sync the Netbox device inventory to Zabbix. * ZABBIX_PASS="Password" * NETBOX_HOST="https://netbox.local" * NETBOX_TOKEN="secrettoken" +Optional: +* NETBOX_KEY="Private user key" #### Flags | Flag | Option | Description | @@ -17,7 +19,8 @@ A script to sync the Netbox device inventory to Zabbix. | -c | cluster | For clustered devices: only add the primary node of a cluster and use the cluster name as hostname. | | -H | hostgroup | Create non-existing hostgroups in Zabbix. Usefull for a first run to add all required hostgroups. | | -t | tenant | Add the tenant name to the hostgroup format (Tenant/Site/Manufacturer/Role) | -| -v | Verbose | Log with debugging on. | +| -s | secret | Use Netbox secrets if present on device for SNMP parameters +| -v | verbose | Log with debugging on. | #### Logging @@ -30,7 +33,7 @@ In case of omitting the -H flag, manual hostgroup creation is required for devic This is in the format: {Site name}/{Manufacturer name}/{Device role name} And with tenants (-t flag): -{Tenant name}/{Site name}/{Manufacturer name}/{Device role name} +{Site name}/{Tenant name}/{Manufacturer name}/{Device role name} 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. @@ -109,6 +112,12 @@ To configure the interface parameters you'll need to use custom context. Custom ``` 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 are not all required, depending on your environment. +##### Secrets +Instead of having the password in plain-text in the config context, you can also set the password as secret in the Netbox device configuration. +You will need to use the -s option for this. Keep in mind that you will need a Netbox private user key for this functionality. + +This method of setting device SNMP parameters is working, but i would recommend going for a "secret macro" implementation to keep your environment more predictable. Refer to the macro from the config context and set the macro inside of Zabbix to the actual community string / authentication secret etc. + #### Permissions Make sure that the user has proper permissions for device read and modify (modify to set the Zabbix HostID custom field) operations. diff --git a/netbox_zabbix_sync.py b/netbox_zabbix_sync.py index b0878ea..bf58d72 100755 --- a/netbox_zabbix_sync.py +++ b/netbox_zabbix_sync.py @@ -49,6 +49,11 @@ def main(arguments): netbox_token = environ.get("NETBOX_TOKEN") netbox_key = environ.get("NETBOX_KEY") + if(arguments.secret and not netbox_key): + e = ("You need a private user key to" + " use the Netbox secrets functionality.") + logger.warning(e) + EnvironmentVarError(e) # Set Zabbix API try: zabbix = ZabbixAPI(zabbix_host) @@ -94,7 +99,6 @@ def main(arguments): f"Using HG format '{device.hostgroup}'.") # -s flag: collect secrets from this device if(arguments.secret): - # This triggers another API query, might cause delay. device.getNetboxSecrets(netbox) # Checks if device is in cleanup state if(device.status != "Active"): @@ -261,7 +265,7 @@ class NetworkDevice(): logger.debug(f"Got {len(self.secrets)} secret(s)" f" for host {self.name}.") except NetboxRequestError as e: - e = f"Couldn't get Netbox secrets, error {e}." + e = f"Device {self.name}: unable to get Netbox secrets, error: {e}" logger.warning(e) def getZabbixTemplate(self, templates): @@ -512,8 +516,6 @@ class NetworkDevice(): raise InterfaceConfigError(e) # Set interfaceID for Zabbix config updates["interfaceid"] = host["interfaces"][0]['interfaceid'] - logger.debug(f"{self.name}: Updating interface with " - f"config {updates}") try: # API call to Zabbix self.zabbix.hostinterface.update(updates) @@ -567,10 +569,13 @@ class ZabbixInterface(): if("snmp" in self.context["zabbix"]): snmp = self.context["zabbix"]["snmp"] # Check if matching SNMP Netbox secret is found for host. - secrets = ["community", "authpassphrase", "privpassphrase"] + supported_secrets = ["community", "authpassphrase", + "privpassphrase"] + # Check if Netbox host has secrets if(self.secrets): for secret in self.secrets: - if(secret.name in secrets): + # If secret is supported, add to SNMP details + if(secret.name in supported_secrets): snmp[secret.name] = secret.plaintext self.interface["details"] = {} # Checks if bulk config has been defined