From 4a7758c84786d0338ce88574ecc81e18d06649c1 Mon Sep 17 00:00:00 2001 From: Protsenko Andrey Date: Fri, 7 Jun 2019 13:56:00 +0300 Subject: [PATCH] Fixes: #3242 Adds HUAWEI CE interface naming scheme ordering support --- netbox/dcim/managers.py | 16 +++++++------ netbox/dcim/tests/test_natural_ordering.py | 27 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/netbox/dcim/managers.py b/netbox/dcim/managers.py index 53f627a5b..d476f420c 100644 --- a/netbox/dcim/managers.py +++ b/netbox/dcim/managers.py @@ -4,12 +4,14 @@ from django.db.models.expressions import RawSQL from .constants import NONCONNECTABLE_IFACE_TYPES # Regular expressions for parsing Interface names -TYPE_RE = r"SUBSTRING({} FROM '^([^0-9\.:]+)')" -SLOT_RE = r"COALESCE(CAST(SUBSTRING({} FROM '^(?:[^0-9]+)?(\d{{1,9}})/') AS integer), NULL)" -SUBSLOT_RE = r"COALESCE(CAST(SUBSTRING({} FROM '^(?:[^0-9\.:]+)?\d{{1,9}}/(\d{{1,9}})') AS integer), NULL)" -POSITION_RE = r"COALESCE(CAST(SUBSTRING({} FROM '^(?:[^0-9]+)?(?:\d{{1,9}}/){{2}}(\d{{1,9}})') AS integer), NULL)" -SUBPOSITION_RE = r"COALESCE(CAST(SUBSTRING({} FROM '^(?:[^0-9]+)?(?:\d{{1,9}}/){{3}}(\d{{1,9}})') AS integer), NULL)" -ID_RE = r"CAST(SUBSTRING({} FROM '^(?:[^0-9\.:]+)?(\d{{1,9}})([^/]|$)') AS integer)" +TYPE_RE = r"SUBSTRING({} FROM '^([^0-9\.:]+|\d{{2,3}}GE)')" +SLOT_RE = r"COALESCE(CAST(SUBSTRING({} FROM '^(?:[^0-9]+|\d{{2,3}}GE)?(\d{{1,9}})/') AS integer), NULL)" +SUBSLOT_RE = r"COALESCE(CAST(SUBSTRING({} FROM '^(?:[^0-9\.:]+|\d{{2,3}}GE)?\d{{1,9}}/(\d{{1,9}})') AS integer), NULL)" +POSITION_RE = \ + r"COALESCE(CAST(SUBSTRING({} FROM '^(?:[^0-9]+|\d{{2,3}}GE)?(?:\d{{1,9}}/){{2}}(\d{{1,9}})') AS integer), NULL)" +SUBPOSITION_RE = \ + r"COALESCE(CAST(SUBSTRING({} FROM '^(?:[^0-9]+|\d{{2,3}}GE)?(?:\d{{1,9}}/){{3}}(\d{{1,9}})') AS integer), NULL)" +ID_RE = r"CAST(SUBSTRING({} FROM '^(?:[^0-9\.:]+|\d{{2,3}}GE)?(\d{{1,9}})([^/]|$)') AS integer)" CHANNEL_RE = r"COALESCE(CAST(SUBSTRING({} FROM '^.*:(\d{{1,9}})(\.\d{{1,9}})?$') AS integer), 0)" VC_RE = r"COALESCE(CAST(SUBSTRING({} FROM '^.*\.(\d{{1,9}})$') AS integer), 0)" @@ -55,7 +57,7 @@ class InterfaceManager(Manager): sql_col = '{}.name'.format(self.model._meta.db_table) ordering = [ - '_slot', '_subslot', '_position', '_subposition', '_type', '_id', '_channel', '_vc', 'name', 'pk' + '_slot', '_type', '_subslot', '_position', '_subposition', '_id', '_channel', '_vc', 'name', 'pk' ] diff --git a/netbox/dcim/tests/test_natural_ordering.py b/netbox/dcim/tests/test_natural_ordering.py index d4dca43d7..4e71474cc 100644 --- a/netbox/dcim/tests/test_natural_ordering.py +++ b/netbox/dcim/tests/test_natural_ordering.py @@ -155,3 +155,30 @@ class NaturalOrderingTestCase(TestCase): iface.save() self._compare_names(Interface.objects.filter(device=self.device), INTERFACES) + + + def test_interface_ordering_huawei_vrp(self): + + INTERFACES = ( + '100GE1/0/1', + '100GE1/0/2', + '100GE1/0/10', + '10GE1/0/1', + '10GE1/0/2', + '10GE1/0/10', + '25GE1/0/1', + '25GE1/0/2', + '25GE1/0/10', + '40GE1/0/1', + '40GE1/0/2', + '40GE1/0/10', + '10GE2/0/1', + '25GE2/0/1', + '100GE/2/0/4', + ) + + for name in INTERFACES: + iface = Interface(device=self.device, name=name) + iface.save() + + self._compare_names(Interface.objects.filter(device=self.device), INTERFACES)