diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index d5d09301c..b429c3e5c 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -61,7 +61,7 @@ __all__ = ( # Webhooks # -class WebhookSerializer(ValidatedModelSerializer): +class WebhookSerializer(NetBoxModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='extras-api:webhook-detail') content_types = ContentTypeField( queryset=ContentType.objects.filter(FeatureQuery('webhooks').get_query()), @@ -74,7 +74,7 @@ class WebhookSerializer(ValidatedModelSerializer): 'id', 'url', 'display', 'content_types', 'name', 'type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end', 'payload_url', 'enabled', 'http_method', 'http_content_type', 'additional_headers', 'body_template', 'secret', 'conditions', 'ssl_verification', 'ca_file_path', - 'created', 'last_updated', + 'custom_fields', 'tags', 'created', 'last_updated', ] diff --git a/netbox/extras/filtersets.py b/netbox/extras/filtersets.py index 80fe2d253..fec067263 100644 --- a/netbox/extras/filtersets.py +++ b/netbox/extras/filtersets.py @@ -34,7 +34,7 @@ __all__ = ( ) -class WebhookFilterSet(BaseFilterSet): +class WebhookFilterSet(NetBoxModelFilterSet): q = django_filters.CharFilter( method='search', label=_('Search'), diff --git a/netbox/extras/forms/bulk_edit.py b/netbox/extras/forms/bulk_edit.py index 46bd4d64c..821ce7eb2 100644 --- a/netbox/extras/forms/bulk_edit.py +++ b/netbox/extras/forms/bulk_edit.py @@ -3,6 +3,7 @@ from django.utils.translation import gettext_lazy as _ from extras.choices import * from extras.models import * +from netbox.forms import NetBoxModelBulkEditForm from utilities.forms import BulkEditForm, add_blank_choice from utilities.forms.fields import ColorField, DynamicModelChoiceField from utilities.forms.widgets import BulkEditNullBooleanSelect @@ -165,7 +166,9 @@ class SavedFilterBulkEditForm(BulkEditForm): nullable_fields = ('description',) -class WebhookBulkEditForm(BulkEditForm): +class WebhookBulkEditForm(NetBoxModelBulkEditForm): + model = Webhook + pk = forms.ModelMultipleChoiceField( queryset=Webhook.objects.all(), widget=forms.MultipleHiddenInput diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 31afbd39d..466baa241 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -140,7 +140,7 @@ class SavedFilterImportForm(CSVModelForm): ) -class WebhookImportForm(CSVModelForm): +class WebhookImportForm(NetBoxModelImportForm): content_types = CSVMultipleContentTypeField( label=_('Content types'), queryset=ContentType.objects.all(), @@ -153,7 +153,7 @@ class WebhookImportForm(CSVModelForm): fields = ( 'name', 'enabled', 'content_types', 'type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end', 'payload_url', 'http_method', 'http_content_type', 'additional_headers', 'body_template', - 'secret', 'ssl_verification', 'ca_file_path' + 'secret', 'ssl_verification', 'ca_file_path', 'tags' ) diff --git a/netbox/extras/forms/filtersets.py b/netbox/extras/forms/filtersets.py index 5d1d2015e..88cbf9e4d 100644 --- a/netbox/extras/forms/filtersets.py +++ b/netbox/extras/forms/filtersets.py @@ -16,7 +16,7 @@ from utilities.forms.fields import ( ) from utilities.forms.widgets import APISelectMultiple, DateTimePicker from virtualization.models import Cluster, ClusterGroup, ClusterType -from .mixins import SavedFiltersMixin +from .mixins import * __all__ = ( 'ConfigContextFilterForm', @@ -219,9 +219,12 @@ class SavedFilterFilterForm(SavedFiltersMixin, FilterForm): ) -class WebhookFilterForm(SavedFiltersMixin, FilterForm): +class WebhookFilterForm(NetBoxModelFilterSetForm): + model = Webhook + tag = TagFilterField(model) + fieldsets = ( - (None, ('q', 'filter_id')), + (None, ('q', 'filter_id', 'tag')), (_('Attributes'), ('content_type_id', 'http_method', 'enabled')), (_('Events'), ('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end')), ) diff --git a/netbox/extras/forms/model_forms.py b/netbox/extras/forms/model_forms.py index 414563f59..0dc384867 100644 --- a/netbox/extras/forms/model_forms.py +++ b/netbox/extras/forms/model_forms.py @@ -214,7 +214,7 @@ class BookmarkForm(BootstrapMixin, forms.ModelForm): fields = ('object_type', 'object_id') -class WebhookForm(BootstrapMixin, forms.ModelForm): +class WebhookForm(NetBoxModelForm): content_types = ContentTypeMultipleChoiceField( label=_('Content types'), queryset=ContentType.objects.all(), @@ -222,7 +222,7 @@ class WebhookForm(BootstrapMixin, forms.ModelForm): ) fieldsets = ( - (_('Webhook'), ('name', 'content_types', 'enabled')), + (_('Webhook'), ('name', 'content_types', 'enabled', 'tags')), (_('Events'), ('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end')), (_('HTTP Request'), ( 'payload_url', 'http_method', 'http_content_type', 'additional_headers', 'body_template', 'secret', diff --git a/netbox/extras/graphql/types.py b/netbox/extras/graphql/types.py index 73ff8eb8a..068da02f2 100644 --- a/netbox/extras/graphql/types.py +++ b/netbox/extras/graphql/types.py @@ -1,6 +1,6 @@ from extras import filtersets, models from extras.graphql.mixins import CustomFieldsMixin, TagsMixin -from netbox.graphql.types import BaseObjectType, ObjectType +from netbox.graphql.types import BaseObjectType, ObjectType, OrganizationalObjectType __all__ = ( 'ConfigContextType', @@ -106,7 +106,7 @@ class TagType(ObjectType): filterset_class = filtersets.TagFilterSet -class WebhookType(ObjectType): +class WebhookType(OrganizationalObjectType): class Meta: model = models.Webhook diff --git a/netbox/extras/migrations/0098_webhook_custom_field_data_webhook_tags.py b/netbox/extras/migrations/0098_webhook_custom_field_data_webhook_tags.py new file mode 100644 index 000000000..3fd294388 --- /dev/null +++ b/netbox/extras/migrations/0098_webhook_custom_field_data_webhook_tags.py @@ -0,0 +1,25 @@ +# Generated by Django 4.1.10 on 2023-08-01 16:32 + +from django.db import migrations, models +import taggit.managers +import utilities.json + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0097_customfield_remove_choices'), + ] + + operations = [ + migrations.AddField( + model_name='webhook', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder), + ), + migrations.AddField( + model_name='webhook', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + ] diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index b209f0d5b..47aa557db 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -39,7 +39,7 @@ __all__ = ( ) -class Webhook(ExportTemplatesMixin, ChangeLoggedModel): +class Webhook(CustomFieldsMixin, ExportTemplatesMixin, TagsMixin, ChangeLoggedModel): """ A Webhook defines a request that will be sent to a remote application when an object is created, updated, and/or delete in NetBox. The request will contain a representation of the object, which the remote application can act on. diff --git a/netbox/extras/tables/tables.py b/netbox/extras/tables/tables.py index baff0efbb..9e14a2d27 100644 --- a/netbox/extras/tables/tables.py +++ b/netbox/extras/tables/tables.py @@ -297,13 +297,16 @@ class WebhookTable(NetBoxTable): ssl_validation = columns.BooleanColumn( verbose_name=_('SSL Validation') ) + tags = columns.TagColumn( + url_name='extras:webhook_list' + ) class Meta(NetBoxTable.Meta): model = Webhook fields = ( 'pk', 'id', 'name', 'content_types', 'enabled', 'type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end', 'http_method', 'payload_url', 'secret', 'ssl_validation', 'ca_file_path', - 'created', 'last_updated', + 'tags', 'created', 'last_updated', ) default_columns = ( 'pk', 'name', 'content_types', 'enabled', 'type_create', 'type_update', 'type_delete', 'type_job_start', diff --git a/netbox/templates/extras/webhook.html b/netbox/templates/extras/webhook.html index dde5d6897..5137b0103 100644 --- a/netbox/templates/extras/webhook.html +++ b/netbox/templates/extras/webhook.html @@ -147,6 +147,8 @@ {% endif %} + {% include 'inc/panels/custom_fields.html' %} + {% include 'inc/panels/tags.html' %} {% plugin_right_page object %}