Added journal functionality for write action

This commit is contained in:
Twan K 2022-01-10 21:33:02 +01:00
parent 992fcda351
commit c2525a1122
2 changed files with 37 additions and 4 deletions

View File

@ -19,6 +19,7 @@ From now on only compatible with Netbox 3.x.
| -H | hostgroup | Create non-existing hostgroups in Zabbix. Usefull for a first run to add all required hostgroups. | | -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) | | -t | tenant | Add the tenant name to the hostgroup format (Tenant/Site/Manufacturer/Role) |
| -v | verbose | Log with debugging on. | | -v | verbose | Log with debugging on. |
| -j | journal | Create journal entries in Netbox when a host gets added, modified or deleted in Zabbix |
| -p | proxy-power | Force a full proxy sync. USE WITH CAUTION, see "Set proxy within Netbox" for more information | | -p | proxy-power | Force a full proxy sync. USE WITH CAUTION, see "Set proxy within Netbox" for more information |
#### Logging #### Logging

View File

@ -63,13 +63,15 @@ def main(arguments):
netbox = api(netbox_host, token=netbox_token, threading=True) netbox = api(netbox_host, token=netbox_token, threading=True)
# Get all Zabbix and Netbox data # Get all Zabbix and Netbox data
netbox_devices = netbox.dcim.devices.all() netbox_devices = netbox.dcim.devices.all()
netbox_journals = netbox.extras.journal_entries
zabbix_groups = zabbix.hostgroup.get(output=['name']) zabbix_groups = zabbix.hostgroup.get(output=['name'])
zabbix_templates = zabbix.template.get(output=['name']) zabbix_templates = zabbix.template.get(output=['name'])
zabbix_proxys = zabbix.proxy.get(output=['host']) zabbix_proxys = zabbix.proxy.get(output=['host'])
# Go through all Netbox devices # Go through all Netbox devices
for nb_device in netbox_devices: for nb_device in netbox_devices:
try: try:
device = NetworkDevice(nb_device, zabbix) device = NetworkDevice(nb_device, zabbix, netbox_journals,
arguments.journal)
# Checks if device is part of cluster. # Checks if device is part of cluster.
# Requires the cluster argument. # Requires the cluster argument.
if(device.isCluster() and arguments.cluster): if(device.isCluster() and arguments.cluster):
@ -166,10 +168,10 @@ class NetworkDevice():
""" """
Represents Network device. Represents Network device.
INPUT: (Netbox device class, ZabbixAPI class) INPUT: (Netbox device class, ZabbixAPI class, journal flag, NB journal class)
""" """
def __init__(self, nb, zabbix): def __init__(self, nb, zabbix, nb_journal_class, journal=None):
self.nb = nb self.nb = nb
self.id = nb.id self.id = nb.id
self.name = nb.name self.name = nb.name
@ -182,6 +184,8 @@ class NetworkDevice():
self.hg_format = [self.nb.site.name, self.hg_format = [self.nb.site.name,
self.nb.device_type.manufacturer.name, self.nb.device_type.manufacturer.name,
self.nb.device_role.name] self.nb.device_role.name]
self.journal = journal
self.nb_journals = nb_journal_class
self._setBasics() self._setBasics()
self.setHostgroup() self.setHostgroup()
@ -314,6 +318,7 @@ class NetworkDevice():
self.nb.save() self.nb.save()
e = f"Deleted host {self.name} from Zabbix." e = f"Deleted host {self.name} from Zabbix."
logger.info(e) logger.info(e)
self.create_journal_entry("warning", "Deleted host from Zabbix")
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)
@ -402,7 +407,9 @@ class NetworkDevice():
# 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()
logger.info(f"Created host {self.name} in Zabbix.") msg = f"Created host {self.name} in Zabbix."
logger.info(msg)
self.create_journal_entry("success", msg)
else: else:
e = f"Unable to add {self.name} to Zabbix: host already present." e = f"Unable to add {self.name} to Zabbix: host already present."
logger.warning(e) logger.warning(e)
@ -434,6 +441,7 @@ class NetworkDevice():
logger.error(e) logger.error(e)
raise SyncExternalError(e) raise SyncExternalError(e)
logger.info(f"Updated host {self.name} with data {kwargs}.") logger.info(f"Updated host {self.name} with data {kwargs}.")
self.create_journal_entry("info", f"Updated host in Zabbix with latest NB data.")
def ConsistencyCheck(self, groups, templates, proxys, proxy_power): def ConsistencyCheck(self, groups, templates, proxys, proxy_power):
""" """
@ -562,6 +570,7 @@ class NetworkDevice():
self.zabbix.hostinterface.update(updates) self.zabbix.hostinterface.update(updates)
e = f"Solved {self.name} interface conflict." e = f"Solved {self.name} interface conflict."
logger.info(e) logger.info(e)
self.create_journal_entry("info", e)
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)
@ -577,6 +586,27 @@ class NetworkDevice():
logger.error(e) logger.error(e)
SyncInventoryError(e) SyncInventoryError(e)
def create_journal_entry(self, severity, message):
# Send a new Journal entry to Netbox. Usefull for viewing actions
# in Netbox without having to look in Zabbix or the script log output
if(self.journal):
# Check if the severity is valid
if severity not in ["info", "success", "warning", "danger"]:
logger.warning(f"Value {severity} not valid for NB journal entries.")
return False
journal = {"assigned_object_type": "dcim.device",
"assigned_object_id": self.id,
"kind": severity,
"comments": message
}
try:
self.nb_journals.create(journal)
return True
logger.debug(f"Crated journal entry in NB for host {self.name}")
except pynetbox.RequestError as e:
logger.warning("Unable to create journal entry for "
f"{self.name}: NB returned {e}")
class ZabbixInterface(): class ZabbixInterface():
"""Class that represents a Zabbix interface.""" """Class that represents a Zabbix interface."""
@ -679,6 +709,8 @@ if(__name__ == "__main__"):
"configured in Zabbix but not in Netbox, sync " "configured in Zabbix but not in Netbox, sync "
"the device and remove the host - proxy " "the device and remove the host - proxy "
"link in Zabbix.")) "link in Zabbix."))
parser.add_argument("-j", "--journal", action="store_true",
help="Create journal entries in Netbox at write actions")
args = parser.parse_args() args = parser.parse_args()
main(args) main(args)