1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Fixes #6776: Fix erroneous webhook dispatch on failure to save objects

This commit is contained in:
jeremystretch
2021-08-23 12:06:43 -04:00
parent 75c62ff729
commit 0b0ab9277c
4 changed files with 33 additions and 4 deletions

View File

@@ -2,7 +2,7 @@ from contextlib import contextmanager
from django.db.models.signals import m2m_changed, pre_delete, post_save
from extras.signals import _handle_changed_object, _handle_deleted_object
from extras.signals import clear_webhooks, _clear_webhook_queue, _handle_changed_object, _handle_deleted_object
from utilities.utils import curry
from .webhooks import flush_webhooks
@@ -20,11 +20,13 @@ def change_logging(request):
# Curry signals receivers to pass the current request
handle_changed_object = curry(_handle_changed_object, request, webhook_queue)
handle_deleted_object = curry(_handle_deleted_object, request, webhook_queue)
clear_webhook_queue = curry(_clear_webhook_queue, webhook_queue)
# Connect our receivers to the post_save and post_delete signals.
post_save.connect(handle_changed_object, dispatch_uid='handle_changed_object')
m2m_changed.connect(handle_changed_object, dispatch_uid='handle_changed_object')
pre_delete.connect(handle_deleted_object, dispatch_uid='handle_deleted_object')
clear_webhooks.connect(clear_webhook_queue, dispatch_uid='clear_webhook_queue')
yield
@@ -33,6 +35,7 @@ def change_logging(request):
post_save.disconnect(handle_changed_object, dispatch_uid='handle_changed_object')
m2m_changed.disconnect(handle_changed_object, dispatch_uid='handle_changed_object')
pre_delete.disconnect(handle_deleted_object, dispatch_uid='handle_deleted_object')
clear_webhooks.disconnect(clear_webhook_queue, dispatch_uid='clear_webhook_queue')
# Flush queued webhooks to RQ
flush_webhooks(webhook_queue)

View File

@@ -1,3 +1,4 @@
import logging
import random
from datetime import timedelta
@@ -6,6 +7,7 @@ from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db import DEFAULT_DB_ALIAS
from django.db.models.signals import m2m_changed, post_save, pre_delete
from django.dispatch import Signal
from django.utils import timezone
from django_prometheus.models import model_deletes, model_inserts, model_updates
from prometheus_client import Counter
@@ -19,6 +21,10 @@ from .webhooks import enqueue_object, get_snapshots, serialize_for_webhook
# Change logging/webhooks
#
# Define a custom signal that can be sent to clear any queued webhooks
clear_webhooks = Signal()
def _handle_changed_object(request, webhook_queue, sender, instance, **kwargs):
"""
Fires when an object is created or updated.
@@ -104,6 +110,16 @@ def _handle_deleted_object(request, webhook_queue, sender, instance, **kwargs):
model_deletes.labels(instance._meta.model_name).inc()
def _clear_webhook_queue(webhook_queue, sender, **kwargs):
"""
Delete any queued webhooks (e.g. because of an aborted bulk transaction)
"""
logger = logging.getLogger('webhooks')
logger.info(f"Clearing {len(webhook_queue)} queued webhooks ({sender})")
webhook_queue.clear()
#
# Custom fields
#