diff --git a/netbox/extras/constants.py b/netbox/extras/constants.py index b1e5ebf41..b12bc2f2c 100644 --- a/netbox/extras/constants.py +++ b/netbox/extras/constants.py @@ -139,36 +139,48 @@ LOG_LEVEL_CODES = { } # Models which support registered webhooks -WEBHOOK_MODELS = [ - 'circuits.circuit', - 'circuits.provider', - 'dcim.cable', - 'dcim.consoleport', - 'dcim.consoleserverport', - 'dcim.device', - 'dcim.devicebay', - 'dcim.devicetype', - 'dcim.interface', - 'dcim.inventoryitem', - 'dcim.frontport', - 'dcim.manufacturer', - 'dcim.poweroutlet', - 'dcim.powerpanel', - 'dcim.powerport', - 'dcim.powerfeed', - 'dcim.rack', - 'dcim.rearport', - 'dcim.region', - 'dcim.site', - 'dcim.virtualchassis', - 'ipam.aggregate', - 'ipam.ipaddress', - 'ipam.prefix', - 'ipam.service', - 'ipam.vlan', - 'ipam.vrf', - 'secrets.secret', - 'tenancy.tenant', - 'virtualization.cluster', - 'virtualization.virtualmachine', -] +WEBHOOK_MODELS = Q( + Q(app_label='circuits', model__in=[ + 'circuit', + 'provider', + ]) | + Q(app_label='dcim', model__in=[ + 'cable', + 'consoleport', + 'consoleserverport', + 'device', + 'devicebay', + 'devicetype', + 'frontport', + 'interface', + 'inventoryitem', + 'manufacturer', + 'poweroutlet', + 'powerpanel', + 'powerport', + 'powerfeed', + 'rack', + 'rearport', + 'region', + 'site', + 'virtualchassis', + ]) | + Q(app_label='ipam', model__in=[ + 'aggregate', + 'ipaddress', + 'prefix', + 'service', + 'vlan', + 'vrf', + ]) | + Q(app_label='secrets', model__in=[ + 'secret', + ]) | + Q(app_label='tenancy', model__in=[ + 'tenant', + ]) | + Q(app_label='virtualization', model__in=[ + 'cluster', + 'virtualmachine', + ]) +) diff --git a/netbox/extras/migrations/0022_custom_links.py b/netbox/extras/migrations/0022_custom_links.py index 366863018..54d841a4f 100644 --- a/netbox/extras/migrations/0022_custom_links.py +++ b/netbox/extras/migrations/0022_custom_links.py @@ -43,6 +43,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='webhook', name='obj_type', - field=models.ManyToManyField(limit_choices_to=extras.models.get_webhook_models, related_name='webhooks', to='contenttypes.ContentType'), + field=models.ManyToManyField(related_name='webhooks', to='contenttypes.ContentType'), ), ] diff --git a/netbox/extras/migrations/0022_custom_links_squashed_0034_configcontext_tags.py b/netbox/extras/migrations/0022_custom_links_squashed_0034_configcontext_tags.py index bfa22b7db..b10841a6a 100644 --- a/netbox/extras/migrations/0022_custom_links_squashed_0034_configcontext_tags.py +++ b/netbox/extras/migrations/0022_custom_links_squashed_0034_configcontext_tags.py @@ -125,7 +125,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='webhook', name='obj_type', - field=models.ManyToManyField(limit_choices_to=extras.models.get_webhook_models, related_name='webhooks', to='contenttypes.ContentType'), + field=models.ManyToManyField(related_name='webhooks', to='contenttypes.ContentType'), ), migrations.RunSQL( sql="SELECT setval('extras_tag_id_seq', (SELECT id FROM extras_tag ORDER BY id DESC LIMIT 1) + 1)", diff --git a/netbox/extras/migrations/0036_contenttype_filters_to_q_objects.py b/netbox/extras/migrations/0036_contenttype_filters_to_q_objects.py index 49fcfb782..12e9bdc0b 100644 --- a/netbox/extras/migrations/0036_contenttype_filters_to_q_objects.py +++ b/netbox/extras/migrations/0036_contenttype_filters_to_q_objects.py @@ -1,4 +1,4 @@ -# Generated by Django 2.2.8 on 2020-01-15 21:11 +# Generated by Django 2.2.8 on 2020-01-15 21:18 from django.db import migrations, models import django.db.models.deletion @@ -31,4 +31,9 @@ class Migration(migrations.Migration): name='type', field=models.ForeignKey(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'circuits'), ('model__in', ['provider'])), models.Q(('app_label', 'dcim'), ('model__in', ['device', 'interface', 'site'])), _connector='OR')), on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType'), ), + migrations.AlterField( + model_name='webhook', + name='obj_type', + field=models.ManyToManyField(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'circuits'), ('model__in', ['circuit', 'provider'])), models.Q(('app_label', 'dcim'), ('model__in', ['cable', 'consoleport', 'consoleserverport', 'device', 'devicebay', 'devicetype', 'frontport', 'interface', 'inventoryitem', 'manufacturer', 'poweroutlet', 'powerpanel', 'powerport', 'powerfeed', 'rack', 'rearport', 'region', 'site', 'virtualchassis'])), models.Q(('app_label', 'ipam'), ('model__in', ['aggregate', 'ipaddress', 'prefix', 'service', 'vlan', 'vrf'])), models.Q(('app_label', 'secrets'), ('model__in', ['secret'])), models.Q(('app_label', 'tenancy'), ('model__in', ['tenant'])), models.Q(('app_label', 'virtualization'), ('model__in', ['cluster', 'virtualmachine'])), _connector='OR')), related_name='webhooks', to='contenttypes.ContentType'), + ), ] diff --git a/netbox/extras/models.py b/netbox/extras/models.py index a0f37075c..752892821 100644 --- a/netbox/extras/models.py +++ b/netbox/extras/models.py @@ -43,10 +43,6 @@ __all__ = ( # Webhooks # -def get_webhook_models(): - return model_names_to_filter_dict(WEBHOOK_MODELS) - - class Webhook(models.Model): """ A Webhook defines a request that will be sent to a remote application when an object is created, updated, and/or @@ -58,7 +54,7 @@ class Webhook(models.Model): to=ContentType, related_name='webhooks', verbose_name='Object types', - limit_choices_to=get_webhook_models, + limit_choices_to=WEBHOOK_MODELS, help_text="The object(s) to which this Webhook applies." ) name = models.CharField( diff --git a/netbox/extras/webhooks.py b/netbox/extras/webhooks.py index 00c61cfb3..5017582cc 100644 --- a/netbox/extras/webhooks.py +++ b/netbox/extras/webhooks.py @@ -1,6 +1,5 @@ import datetime -from django.conf import settings from django.contrib.contenttypes.models import ContentType from extras.models import Webhook @@ -14,7 +13,10 @@ def enqueue_webhooks(instance, user, request_id, action): Find Webhook(s) assigned to this instance + action and enqueue them to be processed """ - if instance._meta.label.lower() not in WEBHOOK_MODELS: + obj_type = ContentType.objects.get_for_model(instance.__class__) + + webhook_models = ContentType.objects.filter(WEBHOOK_MODELS) + if obj_type not in webhook_models: return # Retrieve any applicable Webhooks @@ -23,7 +25,6 @@ def enqueue_webhooks(instance, user, request_id, action): ObjectChangeActionChoices.ACTION_UPDATE: 'type_update', ObjectChangeActionChoices.ACTION_DELETE: 'type_delete', }[action] - obj_type = ContentType.objects.get_for_model(instance.__class__) webhooks = Webhook.objects.filter(obj_type=obj_type, enabled=True, **{action_flag: True}) if webhooks.exists():