mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Fixes #4336: Ensure interfaces without a subinterface ID are ordered before subinterface zero
This commit is contained in:
@ -10,6 +10,7 @@
|
||||
|
||||
* [#2994](https://github.com/netbox-community/netbox/issues/2994) - Prevent modifying termination points of existing cable to ensure end-to-end path integrity
|
||||
* [#3356](https://github.com/netbox-community/netbox/issues/3356) - Correct Swagger schema specification for the available prefixes/IPs API endpoints
|
||||
* [#4336](https://github.com/netbox-community/netbox/issues/4336) - Ensure interfaces without a subinterface ID are ordered before subinterface zero
|
||||
* [#4361](https://github.com/netbox-community/netbox/issues/4361) - Fix Type of `connection_state` in Swagger schema
|
||||
* [#4388](https://github.com/netbox-community/netbox/issues/4388) - Fix detection of connected endpoints when connecting rear ports
|
||||
* [#4489](https://github.com/netbox-community/netbox/issues/4489) - Fix display of parent/child role on device type view
|
||||
|
18
netbox/dcim/migrations/0105_interface_name_collation.py
Normal file
18
netbox/dcim/migrations/0105_interface_name_collation.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.0.5 on 2020-04-21 20:13
|
||||
|
||||
from django.db import migrations
|
||||
import utilities.query_functions
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dcim', '0104_correct_infiniband_types'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='interface',
|
||||
options={'ordering': ('device', utilities.query_functions.CollateAsChar('_name'))},
|
||||
),
|
||||
]
|
@ -16,6 +16,7 @@ from extras.models import ObjectChange, TaggedItem
|
||||
from extras.utils import extras_features
|
||||
from utilities.fields import NaturalOrderingField
|
||||
from utilities.ordering import naturalize_interface
|
||||
from utilities.query_functions import CollateAsChar
|
||||
from utilities.utils import serialize_object
|
||||
from virtualization.choices import VMInterfaceTypeChoices
|
||||
|
||||
@ -676,7 +677,7 @@ class Interface(CableTermination, ComponentModel):
|
||||
|
||||
class Meta:
|
||||
# TODO: ordering and unique_together should include virtual_machine
|
||||
ordering = ('device', '_name')
|
||||
ordering = ('device', CollateAsChar('_name'))
|
||||
unique_together = ('device', 'name')
|
||||
|
||||
def __str__(self):
|
||||
|
@ -23,28 +23,34 @@ class NaturalOrderingTestCase(TestCase):
|
||||
|
||||
INTERFACES = [
|
||||
'0',
|
||||
'0.0',
|
||||
'0.1',
|
||||
'0.2',
|
||||
'0.10',
|
||||
'0.100',
|
||||
'0:1',
|
||||
'0:1.0',
|
||||
'0:1.1',
|
||||
'0:1.2',
|
||||
'0:1.10',
|
||||
'0:2',
|
||||
'0:2.0',
|
||||
'0:2.1',
|
||||
'0:2.2',
|
||||
'0:2.10',
|
||||
'1',
|
||||
'1.0',
|
||||
'1.1',
|
||||
'1.2',
|
||||
'1.10',
|
||||
'1.100',
|
||||
'1:1',
|
||||
'1:1.0',
|
||||
'1:1.1',
|
||||
'1:1.2',
|
||||
'1:1.10',
|
||||
'1:2',
|
||||
'1:2.0',
|
||||
'1:2.1',
|
||||
'1:2.2',
|
||||
'1:2.10',
|
||||
|
@ -75,7 +75,7 @@ def naturalize_interface(value, max_length):
|
||||
if part is not None:
|
||||
output += part.rjust(6, '0')
|
||||
else:
|
||||
output += '000000'
|
||||
output += '......'
|
||||
|
||||
# Finally, naturalize any remaining text and append it
|
||||
if match.group('remainder') is not None and len(output) < max_length:
|
||||
|
9
netbox/utilities/query_functions.py
Normal file
9
netbox/utilities/query_functions.py
Normal file
@ -0,0 +1,9 @@
|
||||
from django.db.models import F, Func
|
||||
|
||||
|
||||
class CollateAsChar(Func):
|
||||
"""
|
||||
Disregard localization by collating a field as a plain character string. Helpful for ensuring predictable ordering.
|
||||
"""
|
||||
function = 'C'
|
||||
template = '(%(expressions)s) COLLATE "%(function)s"'
|
@ -30,29 +30,32 @@ class NaturalizationTestCase(TestCase):
|
||||
|
||||
# Original, naturalized
|
||||
data = (
|
||||
|
||||
# IOS/JunOS-style
|
||||
('Gi', '9999999999999999Gi000000000000000000'),
|
||||
('Gi1', '9999999999999999Gi000001000000000000'),
|
||||
('Gi1.0', '9999999999999999Gi000001000000000000'),
|
||||
('Gi1.1', '9999999999999999Gi000001000000000001'),
|
||||
('Gi1:0', '9999999999999999Gi000001000000000000'),
|
||||
('Gi', '9999999999999999Gi..................'),
|
||||
('Gi1', '9999999999999999Gi000001............'),
|
||||
('Gi1.0', '9999999999999999Gi000001......000000'),
|
||||
('Gi1.1', '9999999999999999Gi000001......000001'),
|
||||
('Gi1:0', '9999999999999999Gi000001000000......'),
|
||||
('Gi1:0.0', '9999999999999999Gi000001000000000000'),
|
||||
('Gi1:0.1', '9999999999999999Gi000001000000000001'),
|
||||
('Gi1:1', '9999999999999999Gi000001000001000000'),
|
||||
('Gi1:1', '9999999999999999Gi000001000001......'),
|
||||
('Gi1:1.0', '9999999999999999Gi000001000001000000'),
|
||||
('Gi1:1.1', '9999999999999999Gi000001000001000001'),
|
||||
('Gi1/2', '0001999999999999Gi000002000000000000'),
|
||||
('Gi1/2/3', '0001000299999999Gi000003000000000000'),
|
||||
('Gi1/2/3/4', '0001000200039999Gi000004000000000000'),
|
||||
('Gi1/2/3/4/5', '0001000200030004Gi000005000000000000'),
|
||||
('Gi1/2/3/4/5:6', '0001000200030004Gi000005000006000000'),
|
||||
('Gi1/2', '0001999999999999Gi000002............'),
|
||||
('Gi1/2/3', '0001000299999999Gi000003............'),
|
||||
('Gi1/2/3/4', '0001000200039999Gi000004............'),
|
||||
('Gi1/2/3/4/5', '0001000200030004Gi000005............'),
|
||||
('Gi1/2/3/4/5:6', '0001000200030004Gi000005000006......'),
|
||||
('Gi1/2/3/4/5:6.7', '0001000200030004Gi000005000006000007'),
|
||||
|
||||
# Generic
|
||||
('Interface 1', '9999999999999999Interface 000001000000000000'),
|
||||
('Interface 1 (other)', '9999999999999999Interface 000001000000000000 (other)'),
|
||||
('Interface 99', '9999999999999999Interface 000099000000000000'),
|
||||
('PCIe1-p1', '9999999999999999PCIe000001000000000000-p00000001'),
|
||||
('PCIe1-p99', '9999999999999999PCIe000001000000000000-p00000099'),
|
||||
('Interface 1', '9999999999999999Interface 000001............'),
|
||||
('Interface 1 (other)', '9999999999999999Interface 000001............ (other)'),
|
||||
('Interface 99', '9999999999999999Interface 000099............'),
|
||||
('PCIe1-p1', '9999999999999999PCIe000001............-p00000001'),
|
||||
('PCIe1-p99', '9999999999999999PCIe000001............-p00000099'),
|
||||
|
||||
)
|
||||
|
||||
for origin, naturalized in data:
|
||||
|
Reference in New Issue
Block a user