mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
ObjectChange.action to slug (#3569)
This commit is contained in:
@ -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(
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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
netbox/extras/migrations/0030_3569_objectchange_fields.py
Normal file
37
netbox/extras/migrations/0030_3569_objectchange_fields.py
Normal file
@ -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
|
||||
),
|
||||
|
||||
]
|
@ -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,
|
||||
|
@ -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'])
|
||||
|
@ -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()
|
||||
|
@ -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})
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user