Replies: 4 comments 12 replies
-
It sounds like you have several ideas, and need some help deciding which one to pursue and developing an implementation proposal. I'm going to convert this to a discussion. Once you've identified a direction and can provide a reasonably detailed proposal, please open a new feature request. Please also be aware that we have several tests in place to validate the current behavior, and that invalidating any of these tests would be considered a break change by many users. |
Beta Was this translation helpful? Give feedback.
-
I've encountered this for Arista interfaces as detailed above, it's very annoying. The naturalisation in the function naturalize_interface seems like it should work reasonably for anything? Is this what is used currently? If so, why doesn't it work? In terms of options: I would be more than happy with the padded number ordering. |
Beta Was this translation helpful? Give feedback.
-
One of my major complaints at the moment is with Cisco ONS devices, or really any devices that use TL1 AIDs for interface naming, as they use a '-' (hyphen-minus) separator and not a '/' (solidus) separator. As the Current: class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEndpoint, TrackingModelMixin):
"""
A network interface within a Device. A physical Interface can connect to exactly one other Interface.
"""
# Override ComponentModel._name to specify naturalize_interface function
_name = NaturalOrderingField(
target_field='name',
naturalize_function=naturalize_interface,
max_length=100,
blank=True
)
...
# =====
class VMInterface(ComponentModel, BaseInterface, TrackingModelMixin):
name = models.CharField(
verbose_name=_('name'),
max_length=64,
)
_name = NaturalOrderingField(
target_field='name',
naturalize_function=naturalize_interface,
max_length=100,
blank=True
)
# =====
class NaturalOrderingField(models.CharField):
...
def pre_save(self, model_instance, add):
"""
Generate a naturalized value from the target field
"""
original_value = getattr(model_instance, self.target_field)
naturalized_value = self.naturalize_function(original_value, max_length=self.max_length)
setattr(model_instance, self.attname, naturalized_value)
return naturalized_value
# =====
def naturalize_interface(value, max_length):
"""
Similar in nature to naturalize(), but takes into account a particular naming format adapted from the old
InterfaceManager.
:param value: The value to be naturalized
:param max_length: The maximum length of the returned string. Characters beyond this length will be stripped.
"""
output = ''
... Proposed: def get_naturalize_interface_function():
if f := get_config().NATURALIZE_INTERFACE_FUNCTION:
# Loading a naturalize function by a dotted path
if type(f) is str:
module, func = f.rsplit('.', 1)
f = getattr(importlib.import_module(module), func)()
if not callable(f):
raise ImproperlyConfigured(f"Invalid value for naturalize interface function: {f}")
return f
return naturalize_interface
class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEndpoint, TrackingModelMixin):
"""
A network interface within a Device. A physical Interface can connect to exactly one other Interface.
"""
# Override ComponentModel._name to specify naturalize_interface function
_name = NaturalOrderingField(
target_field='name',
naturalize_function=get_naturalize_interface_function(),
max_length=100,
blank=True
)
...
# =====
class VMInterface(ComponentModel, BaseInterface, TrackingModelMixin):
name = models.CharField(
verbose_name=_('name'),
max_length=64,
)
_name = NaturalOrderingField(
target_field='name',
naturalize_function=get_naturalize_interface_function(),
max_length=100,
blank=True
)
# =====
class NaturalOrderingField(models.CharField):
...
def pre_save(self, model_instance, add):
"""
Generate a naturalized value from the target field
"""
naturalized_value = self.naturalize_function(model_instance, self.target_field, max_length=self.max_length)
setattr(model_instance, self.attname, naturalized_value)
return naturalized_value
# =====
def naturalize_interface(model_instance, target_field, max_length):
"""
Similar in nature to naturalize(), but takes into account a particular naming format adapted from the old
InterfaceManager.
:param model_instance: The model instance
:param target_field: The target field to be naturalized
:param max_length: The maximum length of the returned string. Characters beyond this length will be stripped.
"""
value = getattr(model_instance, target_field)
output = ''
... |
Beta Was this translation helpful? Give feedback.
-
@jeremystretch Is this something we can move to a FR, or do you have any concerns on this way of implementation |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
NetBox version
v4.2.9
Feature type
Change to existing functionality
Proposed functionality
Interfaces are sorted according a specific interface naturalization function
netbox/netbox/utilities/ordering.py
Line 51 in cf0ef92
This function suits very well for Cisco branded devices, but does not always work for other vendors.
There has been few proposals (can only find this one #9368 ) to address this, but for now non has been accepted,
I see few options
Use case
A recent poll in #netbox shows that there is a need for this: https://netdev-community.slack.com/archives/C01P0FRSXRV/p1757313471550629?thread_ts=1757065483.482359&cid=C01P0FRSXRV
On Arista we have interfaces that are split in lanes, without slot/pos/subpos identifiers.
The current rules sorts them as
Juniper interfaces get different prefixes depending on the speed
get sorted as
Netapp interfaces are even more difficult. they sometimes have a prefix 'e' and sometimes not, but the number is the way to sort
is sorted as
Database changes
No response
External dependencies
No response
Beta Was this translation helpful? Give feedback.
All reactions