mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-18 09:42:18 -06:00
Compare commits
4 Commits
fix_module
...
a696f71656
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a696f71656 | ||
|
|
60fce84c96 | ||
|
|
f0507d00bf | ||
|
|
77b389f105 |
@@ -119,7 +119,9 @@ def process_event_rules(event_rules, object_type, event_type, data, username=Non
|
|||||||
if snapshots:
|
if snapshots:
|
||||||
params["snapshots"] = snapshots
|
params["snapshots"] = snapshots
|
||||||
if request:
|
if request:
|
||||||
params["request"] = copy_safe_request(request)
|
# Exclude FILES - webhooks don't need uploaded files,
|
||||||
|
# which can cause pickle errors with Pillow.
|
||||||
|
params["request"] = copy_safe_request(request, include_files=False)
|
||||||
|
|
||||||
# Enqueue the task
|
# Enqueue the task
|
||||||
rq_queue.enqueue(
|
rq_queue.enqueue(
|
||||||
|
|||||||
@@ -1071,14 +1071,17 @@ class VLANGroupTest(APIViewTestCases.APIViewTestCase):
|
|||||||
{
|
{
|
||||||
'name': 'VLAN Group 4',
|
'name': 'VLAN Group 4',
|
||||||
'slug': 'vlan-group-4',
|
'slug': 'vlan-group-4',
|
||||||
|
'vid_ranges': [[1, 4094]]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'VLAN Group 5',
|
'name': 'VLAN Group 5',
|
||||||
'slug': 'vlan-group-5',
|
'slug': 'vlan-group-5',
|
||||||
|
'vid_ranges': [[1, 4094]]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'VLAN Group 6',
|
'name': 'VLAN Group 6',
|
||||||
'slug': 'vlan-group-6',
|
'slug': 'vlan-group-6',
|
||||||
|
'vid_ranges': [[1, 4094]]
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
bulk_update_data = {
|
bulk_update_data = {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -35,27 +35,34 @@ class NetBoxFakeRequest:
|
|||||||
# Utility functions
|
# Utility functions
|
||||||
#
|
#
|
||||||
|
|
||||||
def copy_safe_request(request):
|
def copy_safe_request(request, include_files=True):
|
||||||
"""
|
"""
|
||||||
Copy selected attributes from a request object into a new fake request object. This is needed in places where
|
Copy selected attributes from a request object into a new fake request object. This is needed in places where
|
||||||
thread safe pickling of the useful request data is needed.
|
thread safe pickling of the useful request data is needed.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
request: The original request object
|
||||||
|
include_files: Whether to include request.FILES.
|
||||||
"""
|
"""
|
||||||
meta = {
|
meta = {
|
||||||
k: request.META[k]
|
k: request.META[k]
|
||||||
for k in HTTP_REQUEST_META_SAFE_COPY
|
for k in HTTP_REQUEST_META_SAFE_COPY
|
||||||
if k in request.META and isinstance(request.META[k], str)
|
if k in request.META and isinstance(request.META[k], str)
|
||||||
}
|
}
|
||||||
return NetBoxFakeRequest({
|
data = {
|
||||||
'META': meta,
|
'META': meta,
|
||||||
'COOKIES': request.COOKIES,
|
'COOKIES': request.COOKIES,
|
||||||
'POST': request.POST,
|
'POST': request.POST,
|
||||||
'GET': request.GET,
|
'GET': request.GET,
|
||||||
'FILES': request.FILES,
|
|
||||||
'user': request.user,
|
'user': request.user,
|
||||||
'method': request.method,
|
'method': request.method,
|
||||||
'path': request.path,
|
'path': request.path,
|
||||||
'id': getattr(request, 'id', None), # UUID assigned by middleware
|
'id': getattr(request, 'id', None), # UUID assigned by middleware
|
||||||
})
|
}
|
||||||
|
if include_files:
|
||||||
|
data['FILES'] = request.FILES
|
||||||
|
|
||||||
|
return NetBoxFakeRequest(data)
|
||||||
|
|
||||||
|
|
||||||
def get_client_ip(request, additional_headers=()):
|
def get_client_ip(request, additional_headers=()):
|
||||||
|
|||||||
@@ -141,8 +141,8 @@ class ModelTestCase(TestCase):
|
|||||||
elif value and type(field) is GenericForeignKey:
|
elif value and type(field) is GenericForeignKey:
|
||||||
model_dict[key] = value.pk
|
model_dict[key] = value.pk
|
||||||
|
|
||||||
|
# Handle API output
|
||||||
elif api:
|
elif api:
|
||||||
|
|
||||||
# Replace ContentType numeric IDs with <app_label>.<model>
|
# Replace ContentType numeric IDs with <app_label>.<model>
|
||||||
if type(getattr(instance, key)) in (ContentType, ObjectType):
|
if type(getattr(instance, key)) in (ContentType, ObjectType):
|
||||||
object_type = ObjectType.objects.get(pk=value)
|
object_type = ObjectType.objects.get(pk=value)
|
||||||
@@ -152,9 +152,13 @@ class ModelTestCase(TestCase):
|
|||||||
elif type(value) is IPNetwork:
|
elif type(value) is IPNetwork:
|
||||||
model_dict[key] = str(value)
|
model_dict[key] = str(value)
|
||||||
|
|
||||||
else:
|
# Normalize arrays of numeric ranges (e.g. VLAN IDs or port ranges).
|
||||||
field = instance._meta.get_field(key)
|
# DB uses canonical half-open [lo, hi) via NumericRange; API uses inclusive [lo, hi].
|
||||||
|
# Convert to inclusive pairs for stable API comparisons.
|
||||||
|
elif type(field) is ArrayField and issubclass(type(field.base_field), RangeField):
|
||||||
|
model_dict[key] = [[r.lower, r.upper - 1] for r in value]
|
||||||
|
|
||||||
|
else:
|
||||||
# Convert ArrayFields to CSV strings
|
# Convert ArrayFields to CSV strings
|
||||||
if type(field) is ArrayField:
|
if type(field) is ArrayField:
|
||||||
if getattr(field.base_field, 'choices', None):
|
if getattr(field.base_field, 'choices', None):
|
||||||
|
|||||||
Reference in New Issue
Block a user