Jeremy Stretch 6 лет назад
Родитель
Сommit
2bcbcd3458

+ 2 - 1
netbox/extras/api/serializers.py

@@ -8,6 +8,7 @@ from dcim.api.nested_serializers import (
     NestedRegionSerializer, NestedSiteSerializer,
 )
 from dcim.models import Device, DeviceRole, Platform, Rack, Region, Site
+from extras.choices import *
 from extras.constants import *
 from extras.models import (
     ConfigContext, ExportTemplate, Graph, ImageAttachment, ObjectChange, ReportResult, Tag,
@@ -255,7 +256,7 @@ class ObjectChangeSerializer(serializers.ModelSerializer):
         read_only=True
     )
     action = ChoiceField(
-        choices=OBJECTCHANGE_ACTION_CHOICES,
+        choices=ObjectChangeActionChoices,
         read_only=True
     )
     changed_object_type = ContentTypeField(

+ 23 - 0
netbox/extras/choices.py

@@ -75,3 +75,26 @@ class CustomLinkButtonClassChoices(ChoiceSet):
         (CLASS_DANGER, 'Danger (red)'),
         (CLASS_LINK, 'None (link)'),
     )
+
+
+#
+# ObjectChanges
+#
+
+class ObjectChangeActionChoices(ChoiceSet):
+
+    ACTION_CREATE = 'create'
+    ACTION_UPDATE = 'update'
+    ACTION_DELETE = 'delete'
+
+    CHOICES = (
+        (ACTION_CREATE, 'Created'),
+        (ACTION_UPDATE, 'Updated'),
+        (ACTION_DELETE, 'Deleted'),
+    )
+
+    LEGACY_MAP = {
+        ACTION_CREATE: 1,
+        ACTION_UPDATE: 2,
+        ACTION_DELETE: 3,
+    }

+ 0 - 10
netbox/extras/constants.py

@@ -93,16 +93,6 @@ TEMPLATE_LANGUAGE_CHOICES = (
     (TEMPLATE_LANGUAGE_JINJA2, 'Jinja2'),
 )
 
-# Change log actions
-OBJECTCHANGE_ACTION_CREATE = 1
-OBJECTCHANGE_ACTION_UPDATE = 2
-OBJECTCHANGE_ACTION_DELETE = 3
-OBJECTCHANGE_ACTION_CHOICES = (
-    (OBJECTCHANGE_ACTION_CREATE, 'Created'),
-    (OBJECTCHANGE_ACTION_UPDATE, 'Updated'),
-    (OBJECTCHANGE_ACTION_DELETE, 'Deleted'),
-)
-
 # User action types
 ACTION_CREATE = 1
 ACTION_IMPORT = 2

+ 1 - 1
netbox/extras/forms.py

@@ -401,7 +401,7 @@ class ObjectChangeFilterForm(BootstrapMixin, forms.Form):
         )
     )
     action = forms.ChoiceField(
-        choices=add_blank_choice(OBJECTCHANGE_ACTION_CHOICES),
+        choices=add_blank_choice(ObjectChangeActionChoices),
         required=False
     )
     user = forms.ModelChoiceField(

+ 7 - 7
netbox/extras/middleware.py

@@ -10,7 +10,7 @@ from django.utils import timezone
 from django_prometheus.models import model_deletes, model_inserts, model_updates
 
 from utilities.querysets import DummyQuerySet
-from .constants import *
+from .choices import ObjectChangeActionChoices
 from .models import ObjectChange
 from .signals import purge_changelog
 from .webhooks import enqueue_webhooks
@@ -23,7 +23,7 @@ def handle_changed_object(sender, instance, **kwargs):
     Fires when an object is created or updated.
     """
     # Queue the object for processing once the request completes
-    action = OBJECTCHANGE_ACTION_CREATE if kwargs['created'] else OBJECTCHANGE_ACTION_UPDATE
+    action = ObjectChangeActionChoices.ACTION_CREATE if kwargs['created'] else ObjectChangeActionChoices.ACTION_UPDATE
     _thread_locals.changed_objects.append(
         (instance, action)
     )
@@ -46,7 +46,7 @@ def handle_deleted_object(sender, instance, **kwargs):
 
     # Queue the copy of the object for processing once the request completes
     _thread_locals.changed_objects.append(
-        (copy, OBJECTCHANGE_ACTION_DELETE)
+        (copy, ObjectChangeActionChoices.ACTION_DELETE)
     )
 
 
@@ -101,7 +101,7 @@ class ObjectChangeMiddleware(object):
         for instance, action in _thread_locals.changed_objects:
 
             # Refresh cached custom field values
-            if action in [OBJECTCHANGE_ACTION_CREATE, OBJECTCHANGE_ACTION_UPDATE]:
+            if action in [ObjectChangeActionChoices.ACTION_CREATE, ObjectChangeActionChoices.ACTION_UPDATE]:
                 if hasattr(instance, 'cache_custom_fields'):
                     instance.cache_custom_fields()
 
@@ -116,11 +116,11 @@ class ObjectChangeMiddleware(object):
             enqueue_webhooks(instance, request.user, request.id, action)
 
             # Increment metric counters
-            if action == OBJECTCHANGE_ACTION_CREATE:
+            if action == ObjectChangeActionChoices.ACTION_CREATE:
                 model_inserts.labels(instance._meta.model_name).inc()
-            elif action == OBJECTCHANGE_ACTION_UPDATE:
+            elif action == ObjectChangeActionChoices.ACTION_UPDATE:
                 model_updates.labels(instance._meta.model_name).inc()
-            elif action == OBJECTCHANGE_ACTION_DELETE:
+            elif action == ObjectChangeActionChoices.ACTION_DELETE:
                 model_deletes.labels(instance._meta.model_name).inc()
 
         # Housekeeping: 1% chance of clearing out expired ObjectChanges. This applies only to requests which result in

+ 37 - 0
netbox/extras/migrations/0030_3569_objectchange_fields.py

@@ -0,0 +1,37 @@
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+OBJECTCHANGE_ACTION_CHOICES = (
+    (1, 'create'),
+    (2, 'update'),
+    (3, 'delete'),
+)
+
+
+def objectchange_action_to_slug(apps, schema_editor):
+    ObjectChange = apps.get_model('extras', 'ObjectChange')
+    for id, slug in OBJECTCHANGE_ACTION_CHOICES:
+        ObjectChange.objects.filter(action=str(id)).update(action=slug)
+
+
+class Migration(migrations.Migration):
+    atomic = False
+
+    dependencies = [
+        ('extras', '0029_3569_customfield_fields'),
+    ]
+
+    operations = [
+
+        # ObjectChange.action
+        migrations.AlterField(
+            model_name='objectchange',
+            name='action',
+            field=models.CharField(max_length=50),
+        ),
+        migrations.RunPython(
+            code=objectchange_action_to_slug
+        ),
+
+    ]

+ 3 - 2
netbox/extras/models.py

@@ -802,8 +802,9 @@ class ObjectChange(models.Model):
     request_id = models.UUIDField(
         editable=False
     )
-    action = models.PositiveSmallIntegerField(
-        choices=OBJECTCHANGE_ACTION_CHOICES
+    action = models.CharField(
+        max_length=50,
+        choices=ObjectChangeActionChoices
     )
     changed_object_type = models.ForeignKey(
         to=ContentType,

+ 3 - 3
netbox/extras/tests/test_changelog.py

@@ -50,7 +50,7 @@ class ChangeLogTest(APITestCase):
             changed_object_id=site.pk
         )
         self.assertEqual(oc.changed_object, site)
-        self.assertEqual(oc.action, OBJECTCHANGE_ACTION_CREATE)
+        self.assertEqual(oc.action, ObjectChangeActionChoices.ACTION_CREATE)
         self.assertEqual(oc.object_data['custom_fields'], data['custom_fields'])
         self.assertListEqual(sorted(oc.object_data['tags']), data['tags'])
 
@@ -82,7 +82,7 @@ class ChangeLogTest(APITestCase):
             changed_object_id=site.pk
         )
         self.assertEqual(oc.changed_object, site)
-        self.assertEqual(oc.action, OBJECTCHANGE_ACTION_UPDATE)
+        self.assertEqual(oc.action, ObjectChangeActionChoices.ACTION_UPDATE)
         self.assertEqual(oc.object_data['custom_fields'], data['custom_fields'])
         self.assertListEqual(sorted(oc.object_data['tags']), data['tags'])
 
@@ -111,6 +111,6 @@ class ChangeLogTest(APITestCase):
         oc = ObjectChange.objects.first()
         self.assertEqual(oc.changed_object, None)
         self.assertEqual(oc.object_repr, site.name)
-        self.assertEqual(oc.action, OBJECTCHANGE_ACTION_DELETE)
+        self.assertEqual(oc.action, ObjectChangeActionChoices.ACTION_DELETE)
         self.assertEqual(oc.object_data['custom_fields'], {'my_field': 'ABC'})
         self.assertListEqual(sorted(oc.object_data['tags']), ['bar', 'foo'])

+ 2 - 2
netbox/extras/tests/test_views.py

@@ -6,7 +6,7 @@ from django.test import Client, TestCase
 from django.urls import reverse
 
 from dcim.models import Site
-from extras.constants import OBJECTCHANGE_ACTION_UPDATE
+from extras.choices import ObjectChangeActionChoices
 from extras.models import ConfigContext, ObjectChange, Tag
 from utilities.testing import create_test_user
 
@@ -83,7 +83,7 @@ class ObjectChangeTestCase(TestCase):
 
         # Create three ObjectChanges
         for i in range(1, 4):
-            oc = site.to_objectchange(action=OBJECTCHANGE_ACTION_UPDATE)
+            oc = site.to_objectchange(action=ObjectChangeActionChoices.ACTION_UPDATE)
             oc.user = user
             oc.request_id = uuid.uuid4()
             oc.save()

+ 4 - 3
netbox/extras/webhooks.py

@@ -5,6 +5,7 @@ from django.contrib.contenttypes.models import ContentType
 
 from extras.models import Webhook
 from utilities.api import get_serializer_for_model
+from .choices import *
 from .constants import *
 
 
@@ -18,9 +19,9 @@ def enqueue_webhooks(instance, user, request_id, action):
 
     # Retrieve any applicable Webhooks
     action_flag = {
-        OBJECTCHANGE_ACTION_CREATE: 'type_create',
-        OBJECTCHANGE_ACTION_UPDATE: 'type_update',
-        OBJECTCHANGE_ACTION_DELETE: 'type_delete',
+        ObjectChangeActionChoices.ACTION_CREATE: 'type_create',
+        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})

+ 1 - 1
netbox/extras/webhooks_worker.py

@@ -15,7 +15,7 @@ def process_webhook(webhook, data, model_name, event, timestamp, username, reque
     Make a POST request to the defined Webhook
     """
     payload = {
-        'event': dict(OBJECTCHANGE_ACTION_CHOICES)[event].lower(),
+        'event': event,
         'timestamp': timestamp,
         'model': model_name,
         'username': username,