netbox icon indicating copy to clipboard operation
netbox copied to clipboard

Change interface naturalize function

Open PieterL75 opened this issue 2 years ago • 28 comments

NetBox version

v3.2.2

Feature type

Change to existing functionality

Proposed functionality

The interface name is naturalized to make it sortable in a proper way. (1,2,10,11,20,21; and not 1,10,11,2,20,21) The current implementation is not covering all use cases to sort interfaces properly.

By making the function more generic, it could cover more use cases:

output = ''
parts = re.split(r'(\d+)',value.lower())
for part in parts:
    if part.isdigit():
        output += part.rjust(4, '0')
    elif part not in ['.',':','/']:
        output += part

It splits the interfacename into parts with and without numbers. the numbers are pre-padded with zero's and the chars [dot,colon,slash] are removed from between the numbers. There might be corner cases with mixed number schema's on one device, but it will keep them grouped.

Unless there was a reason why the slot/subslot/position/.. were prepended to the interfacetype, rather then post ?

Use case

On Arista we have interfaces that are split in lanes, without slot/pos/subpos identifiers.

Ethernet1
Ethernet2
Ethernet3
Ethernet48/1
Ethernet48/2
Ethernet48/3
Ethernet48/4
Ethernet49/1
Ethernet49/2
Ethernet49/3
Ethernet49/4

The current rules sorts them as

Ethernet48/1
Ethernet48/2
Ethernet48/3
Ethernet48/4
Ethernet49/1
Ethernet49/2
Ethernet49/3
Ethernet49/4
Ethernet1
Ethernet2
Ethernet3

because the /1 is prepended to the interfacetype, while with non-slashed interfaces, the prepend is 9999

https://github.com/netbox-community/netbox/blob/a2203da1c6fa674a55d3071a287094d70cb1c502/netbox/utilities/ordering.py#L46

Database changes

All _name fields of all interfaces need to be re-calculated.

External dependencies

No response

PieterL75 avatar May 16 '22 12:05 PieterL75

While someone is looking at this... on NetApp an "e" is prepended to Ethernet interfaces whereas FC interfaces have nothing prepended. The current sort looks like this:

10a
10b
10c
10d
e9a
e9e
e11a
e11e

but I would prefer:

e9a
e9e
10a
10b
10c
10d
e11a
e11e

mgoetze5 avatar May 17 '22 10:05 mgoetze5

I have the same issue in two places, but would also need to add '-' to the list of split characters.

On Cisco ASR 9K 1/10G linecards you can specify which interfaces are 1G and which are 10G and the router accordingly labels them as GigabitEthernet and TenGigE, but they currently end up sorted with all the 1G interfaces first, then the 10G ones, and not in proper port order, which is really confusing. With modules now, even putting them all on the same module doesn't fix the sort order.

The other example is on a Cisco ONS 15454/NCS 2K you can have a QSFP+ 4x10G breakout optic inserted that will create something like VCFAC-1-1-1 for the optic and VLINE-1-1-1-1-[1-4] for the individual 10G lanes, except it sorts it so that all the facility interfaces come first, then the line interfaces. In that case, they can even be modeled as child interfaces and that doesn't affect the sort order either.

sleepinggenius2 avatar May 18 '22 21:05 sleepinggenius2

While someone is looking at this... on NetApp an "e" is prepended to Ethernet interfaces whereas FC interfaces have nothing prepended. The current sort looks like this:

10a
10b
10c
10d
e9a
e9e
e11a
e11e

but I would prefer:

e9a
e9e
10a
10b
10c
10d
e11a
e11e

That will be difficult. the order function only knows the interface names, not the underlaying device model.

PieterL75 avatar May 18 '22 22:05 PieterL75

I think there could be some room for improvement, perhaps we have to look at considering how the sort happens when a slot, module, or port are missing.

That said, I think we still need to maintain the sort with the interface type, but perhaps have interface type be sorted just before port (if it isn't already).

Maybe it would make sense for all of these to be individual fields and then have the name be a computed field that is the combination of all fields.

This sort of individual field setup would only work well with most network switches, regular interfaces for the most part, don't have a concept of slot/module.

DanSheps avatar May 18 '22 23:05 DanSheps

Dan, why would we need to name the parts of an interface and try to fit ? I think that is we just make the numbers a zero pretended 5 digit number, that all sorting cases work. (Except the one mgoetze5 mentioned).

PieterL75 avatar May 22 '22 18:05 PieterL75

@PieterL75 you can find the existing tests for the natural ordering of interfaces here. As it has taken several years for us as a community to settle on the current scheme, we will only entertain modifications that do not alter or violate any of the existing tests. Is this something you want to pursue?

jeremystretch avatar May 24 '22 14:05 jeremystretch

So, as long as the new sorting returns the same order for the test , we should be good? The 'calculated' values will change of course, the displayed order must remain the same.

PieterL75 avatar May 24 '22 14:05 PieterL75

So, as long as the new sorting returns the same order for the test , we should be good?

Provided the proposed change makes sense, yes. It'll also need a new test for the scenario you described above.

jeremystretch avatar May 24 '22 14:05 jeremystretch

The 'calculated' values will change of course, the displayed order must remain the same.

We need to be careful with this. Any changes that would result in recalculating raw names will require that users run renaturalize against all interfaces when upgrading, which is best avoided.

jeremystretch avatar May 24 '22 14:05 jeremystretch

Sounds good. Im good to create a PR for this

PieterL75 avatar May 24 '22 14:05 PieterL75

I've been thinking that too, but it might be something that is inevitable and needs to be weighted... Could (if needed) a migration script take care of that?

PieterL75 avatar May 24 '22 14:05 PieterL75

Looking at the code, I think this is because it treats empty slot, subslot, position, subposition as "9999", would it make sense to treat these as "0000" instead? That would likely solve this specific use case.

DanSheps avatar May 24 '22 14:05 DanSheps

I see now in that test script why the interface type is placed after the port's..

            'GigabitEthernet0/1',
            'GigabitEthernet0/2',
            'GigabitEthernet0/10',
            'TenGigabitEthernet0/20',
            'TenGigabitEthernet0/21',

same for junipers where xe, ge and te interfaces can be mixed in one 'module'

We dont want those TenG before the Gig's Going to think some more, and check @DanSheps advise

PieterL75 avatar May 24 '22 14:05 PieterL75

@DanSheps @jeremystretch I have a version of the naturalize_interface ready in my fork. Shall I create a PR to have it reviewed ? or will you first check it out. https://github.com/PieterL75/netbox/tree/issue_9368

It does change the rawnames, as it uses a totally different logic. There is an option to change the logic, based on the name of the interface, and the model properties.. The current implementation passes the ./manage.py test dcim.tests.test_natural_ordering and it also sorts the ones in the comments (netapp, vmac, ....)

PieterL75 avatar Jun 01 '22 14:06 PieterL75

Sure, push up a PR and we will take a look

DanSheps avatar Jun 01 '22 14:06 DanSheps

I have to fix the tests so that they match the new naturalization function.... But, what I see that the biggest 'exception' is that causes my biggest headache : The sorting requirement that 'FastEthernet0' comes after 'GigaEthernet 0/1'. I don't see a reason to do that, except that the FastEthernet0 is a mgmt only interface that you don't want 'sorted' with the rest. For that I added a condition that places the mgmt_only interface always at the end of the sorting. If that adheres the requirements of why Fa0 was after Gi0/1, then I would like to get rid of that hard requirement. (I dont have the history thread on how the current function was born)

PieterL75 avatar Jun 07 '22 18:06 PieterL75

I don't see a reason to do that, except that the FastEthernet0 is a mgmt only interface that you don't want 'sorted' with the rest. For that I added a condition that places the mgmt_only interface always at the end of the sorting.

I will take a look at the tests and see if I can figure out why this is. To me, FA should come before GI, especially because "0" is the port. I believe this is because in the naturalize we use 9999 for slot and module when it is non-existant, but to me that is backwards and it should be 0000 for a null value.

DanSheps avatar Jun 10 '22 14:06 DanSheps

I suggested the same sort of general natural ordering algorithm at https://github.com/netbox-community/netbox/issues/6882#issuecomment-898508667 and https://github.com/netbox-community/netbox/issues/2872#issuecomment-491279206 - rejected both times.

Those links include some discussion of how this doesn't agree with the existing test cases.

candlerb avatar Jun 23 '22 12:06 candlerb

To me, it seems that the decisions made in the past were not the best. We should start a new discussion to agree on a new sorting algorithm that will work for a lot of cases. The corner cases that are now taken into account, and mess up other natural sorting, should go away in favor of a 'logical' scheme without exceptions. (ex : placing FastEthernet1 at the end, because on some switch types that is the mgmt interface).

I'll work out a generic sorting algorithm and post a new PR to test. This will ofcourse change the current values of _name. But that can be handled with a migration schema file. Rollback is not possible, but that is simply not possible in an version of netbox. Forward is the only way :-)

PieterL75 avatar Jun 25 '22 09:06 PieterL75

@PieterL75 if you want to post up the new FR we can definitely discuss modifying the ordering.

DanSheps avatar Jul 02 '22 01:07 DanSheps

@DanSheps I pushed a new PR https://github.com/netbox-community/netbox/pull/9463 I suspect it will not be approved yet, but I hope I was able to build a logic that is easily extendible.

PieterL75 avatar Jul 04 '22 16:07 PieterL75

I had a very interesting discussion.. @jeremystretch @DanSheps Why bother with the naturalize function ? If we could manually set/change/dragdrop the order on the device/module-type, then that order can be taken for the derived devices. That sort-order can be retained on a device. if a new interface is added to the device itself, then it could be placed at any place and stored.... the _name field can then simply become 0001, 0002, 0003, ...

PieterL75 avatar Jul 05 '22 17:07 PieterL75

@jeremystretch @candlerb did you had time to review the pr I submitted? However, I feel more for solution that interfaces are ordered manually in the template, or on the device... No more debates, each model sorts them by it's design

PieterL75 avatar Jul 08 '22 19:07 PieterL75

I don't think a manual sort is going to be in the cards, it is too difficult to manage. We had it, pulled it out for this.

That said, I think a better method could be devised.

DanSheps avatar Jul 09 '22 15:07 DanSheps

Did you had it when templates existed? Because with those, it is just a one time manual sort. An the option to change it a bit when it became a device... Modules might make it a challenge though..

PieterL75 avatar Jul 09 '22 16:07 PieterL75

@jeremystretch On the PR you mention that you will not allow the current naturalization function to be changed. As this current one is really not doing what it should for multiple devicetypes, I have some suggestions.

  • custom naturalization function, either by a plugin or by a config setting
  • manual ordering by using templates.

I prefer the manual ordering, as it will cover all possible situations. The initial ordering can be fine by such a function, but manual reordering should be an option.

PieterL75 avatar Aug 27 '22 19:08 PieterL75

Still wondering on how this can be solved. 'One Solution Fits All' will not work, so we have to be able to provide a way to customize the naturalization.

Either by a plugin that can overrule the default, or by a configuration.py setting that refers to a py function. Or a manual reorder..

PieterL75 avatar Sep 26 '22 10:09 PieterL75

Would it be possible to get the GUI do a multi-column sort? I.e. sort by column A first, then sort by column B? I know this is something that exists in some operating systems and programs, but I don't know how feasible it is to implement within Django...

This could potentially be very helpful, as a user could sort by Interface Type first, and then by Name, which would effectively allow you to "force" (or at least influence) the grouping based on the port speed.

Plus, on many devices, the physical port labels are just a consecutive numeric string, so it would open the possibility to simply sort by "Label" and get everything in the "physical port order". (There currently seems to be a bug in the sorting for the "Label" column - 1, 10, and 11 are next to each other... I was searching to see if it had been reported when I turned up this discussion!)

ZPrimed avatar Sep 30 '22 04:09 ZPrimed

Closing this for inactivity.

jeremystretch avatar May 02 '23 18:05 jeremystretch