mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-09 01:49:35 -06:00
This commit is contained in:
parent
c902a1c510
commit
addda0538f
@ -7,6 +7,7 @@ from mptt.models import MPTTModel, TreeForeignKey
|
|||||||
|
|
||||||
from dcim.choices import *
|
from dcim.choices import *
|
||||||
from dcim.constants import *
|
from dcim.constants import *
|
||||||
|
from dcim.models.mixins import InterfaceValidationMixin
|
||||||
from netbox.models import ChangeLoggedModel
|
from netbox.models import ChangeLoggedModel
|
||||||
from utilities.fields import ColorField, NaturalOrderingField
|
from utilities.fields import ColorField, NaturalOrderingField
|
||||||
from utilities.mptt import TreeManager
|
from utilities.mptt import TreeManager
|
||||||
@ -405,7 +406,7 @@ class PowerOutletTemplate(ModularComponentTemplateModel):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class InterfaceTemplate(ModularComponentTemplateModel):
|
class InterfaceTemplate(InterfaceValidationMixin, ModularComponentTemplateModel):
|
||||||
"""
|
"""
|
||||||
A template for a physical data interface on a new Device.
|
A template for a physical data interface on a new Device.
|
||||||
"""
|
"""
|
||||||
@ -469,8 +470,6 @@ class InterfaceTemplate(ModularComponentTemplateModel):
|
|||||||
super().clean()
|
super().clean()
|
||||||
|
|
||||||
if self.bridge:
|
if self.bridge:
|
||||||
if self.pk and self.bridge_id == self.pk:
|
|
||||||
raise ValidationError({'bridge': _("An interface cannot be bridged to itself.")})
|
|
||||||
if self.device_type and self.device_type != self.bridge.device_type:
|
if self.device_type and self.device_type != self.bridge.device_type:
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'bridge': _(
|
'bridge': _(
|
||||||
@ -484,11 +483,6 @@ class InterfaceTemplate(ModularComponentTemplateModel):
|
|||||||
).format(bridge=self.bridge)
|
).format(bridge=self.bridge)
|
||||||
})
|
})
|
||||||
|
|
||||||
if self.rf_role and self.type not in WIRELESS_IFACE_TYPES:
|
|
||||||
raise ValidationError({
|
|
||||||
'rf_role': "Wireless role may be set only on wireless interfaces."
|
|
||||||
})
|
|
||||||
|
|
||||||
def instantiate(self, **kwargs):
|
def instantiate(self, **kwargs):
|
||||||
return self.component_model(
|
return self.component_model(
|
||||||
name=self.resolve_name(kwargs.get('module')),
|
name=self.resolve_name(kwargs.get('module')),
|
||||||
|
|||||||
@ -11,6 +11,7 @@ from mptt.models import MPTTModel, TreeForeignKey
|
|||||||
from dcim.choices import *
|
from dcim.choices import *
|
||||||
from dcim.constants import *
|
from dcim.constants import *
|
||||||
from dcim.fields import WWNField
|
from dcim.fields import WWNField
|
||||||
|
from dcim.models.mixins import InterfaceValidationMixin
|
||||||
from netbox.choices import ColorChoices
|
from netbox.choices import ColorChoices
|
||||||
from netbox.models import OrganizationalModel, NetBoxModel
|
from netbox.models import OrganizationalModel, NetBoxModel
|
||||||
from utilities.fields import ColorField, NaturalOrderingField
|
from utilities.fields import ColorField, NaturalOrderingField
|
||||||
@ -676,7 +677,14 @@ class BaseInterface(models.Model):
|
|||||||
return self.primary_mac_address.mac_address
|
return self.primary_mac_address.mac_address
|
||||||
|
|
||||||
|
|
||||||
class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEndpoint, TrackingModelMixin):
|
class Interface(
|
||||||
|
InterfaceValidationMixin,
|
||||||
|
ModularComponentModel,
|
||||||
|
BaseInterface,
|
||||||
|
CabledObjectModel,
|
||||||
|
PathEndpoint,
|
||||||
|
TrackingModelMixin,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
A network interface within a Device. A physical Interface can connect to exactly one other Interface.
|
A network interface within a Device. A physical Interface can connect to exactly one other Interface.
|
||||||
"""
|
"""
|
||||||
@ -893,10 +901,6 @@ class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEnd
|
|||||||
|
|
||||||
# Bridge validation
|
# Bridge validation
|
||||||
|
|
||||||
# An interface cannot be bridged to itself
|
|
||||||
if self.pk and self.bridge_id == self.pk:
|
|
||||||
raise ValidationError({'bridge': _("An interface cannot be bridged to itself.")})
|
|
||||||
|
|
||||||
# A bridged interface belongs to the same device or virtual chassis
|
# A bridged interface belongs to the same device or virtual chassis
|
||||||
if self.bridge and self.bridge.device != self.device:
|
if self.bridge and self.bridge.device != self.device:
|
||||||
if self.device.virtual_chassis is None:
|
if self.device.virtual_chassis is None:
|
||||||
@ -942,29 +946,9 @@ class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEnd
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
# PoE validation
|
|
||||||
|
|
||||||
# Only physical interfaces may have a PoE mode/type assigned
|
|
||||||
if self.poe_mode and self.is_virtual:
|
|
||||||
raise ValidationError({
|
|
||||||
'poe_mode': _("Virtual interfaces cannot have a PoE mode.")
|
|
||||||
})
|
|
||||||
if self.poe_type and self.is_virtual:
|
|
||||||
raise ValidationError({
|
|
||||||
'poe_type': _("Virtual interfaces cannot have a PoE type.")
|
|
||||||
})
|
|
||||||
|
|
||||||
# An interface with a PoE type set must also specify a mode
|
|
||||||
if self.poe_type and not self.poe_mode:
|
|
||||||
raise ValidationError({
|
|
||||||
'poe_type': _("Must specify PoE mode when designating a PoE type.")
|
|
||||||
})
|
|
||||||
|
|
||||||
# Wireless validation
|
# Wireless validation
|
||||||
|
|
||||||
# RF role & channel may only be set for wireless interfaces
|
# RF channel may only be set for wireless interfaces
|
||||||
if self.rf_role and not self.is_wireless:
|
|
||||||
raise ValidationError({'rf_role': _("Wireless role may be set only on wireless interfaces.")})
|
|
||||||
if self.rf_channel and not self.is_wireless:
|
if self.rf_channel and not self.is_wireless:
|
||||||
raise ValidationError({'rf_channel': _("Channel may be set only on wireless interfaces.")})
|
raise ValidationError({'rf_channel': _("Channel may be set only on wireless interfaces.")})
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,11 @@ from django.core.exceptions import ValidationError
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from dcim.constants import VIRTUAL_IFACE_TYPES, WIRELESS_IFACE_TYPES
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'CachedScopeMixin',
|
'CachedScopeMixin',
|
||||||
|
'InterfaceValidationMixin',
|
||||||
'RenderConfigMixin',
|
'RenderConfigMixin',
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -116,3 +119,33 @@ class CachedScopeMixin(models.Model):
|
|||||||
self._site = self.scope.site
|
self._site = self.scope.site
|
||||||
self._location = self.scope
|
self._location = self.scope
|
||||||
cache_related_objects.alters_data = True
|
cache_related_objects.alters_data = True
|
||||||
|
|
||||||
|
|
||||||
|
class InterfaceValidationMixin:
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
super().clean()
|
||||||
|
|
||||||
|
# An interface cannot be bridged to itself
|
||||||
|
if self.pk and self.bridge_id == self.pk:
|
||||||
|
raise ValidationError({'bridge': _("An interface cannot be bridged to itself.")})
|
||||||
|
|
||||||
|
# Only physical interfaces may have a PoE mode/type assigned
|
||||||
|
if self.poe_mode and self.type in VIRTUAL_IFACE_TYPES:
|
||||||
|
raise ValidationError({
|
||||||
|
'poe_mode': _("Virtual interfaces cannot have a PoE mode.")
|
||||||
|
})
|
||||||
|
if self.poe_type and self.type in VIRTUAL_IFACE_TYPES:
|
||||||
|
raise ValidationError({
|
||||||
|
'poe_type': _("Virtual interfaces cannot have a PoE type.")
|
||||||
|
})
|
||||||
|
|
||||||
|
# An interface with a PoE type set must also specify a mode
|
||||||
|
if self.poe_type and not self.poe_mode:
|
||||||
|
raise ValidationError({
|
||||||
|
'poe_type': _("Must specify PoE mode when designating a PoE type.")
|
||||||
|
})
|
||||||
|
|
||||||
|
# RF role may be set only for wireless interfaces
|
||||||
|
if self.rf_role and self.type not in WIRELESS_IFACE_TYPES:
|
||||||
|
raise ValidationError({'rf_role': _("Wireless role may be set only on wireless interfaces.")})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user