mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Fixes #3519: Prevent cables from being terminated to virtual/wireless interfaces
This commit is contained in:
@ -2,7 +2,8 @@ v2.6.5 (FUTURE)
|
|||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [#3521](https://github.com/netbox-community/netbox/issues/3521) - Fixed error in parseURL related to {{variables}} in API url
|
* [#3519](https://github.com/netbox-community/netbox/issues/3519) - Prevent cables from being terminated to virtual/wireless interfaces via API
|
||||||
|
* [#3521](https://github.com/netbox-community/netbox/issues/3521) - Fix error in `parseURL` related to variables in API URL
|
||||||
|
|
||||||
v2.6.4 (2019-09-19)
|
v2.6.4 (2019-09-19)
|
||||||
|
|
||||||
|
@ -2817,6 +2817,20 @@ class Cable(ChangeLoggedModel):
|
|||||||
type_a = self.termination_a_type.model
|
type_a = self.termination_a_type.model
|
||||||
type_b = self.termination_b_type.model
|
type_b = self.termination_b_type.model
|
||||||
|
|
||||||
|
# Validate interface types
|
||||||
|
if type_a == 'interface' and self.termination_a.type in NONCONNECTABLE_IFACE_TYPES:
|
||||||
|
raise ValidationError({
|
||||||
|
'termination_a_id': 'Cables cannot be terminated to {} interfaces'.format(
|
||||||
|
self.termination_a.get_type_display()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
if type_b == 'interface' and self.termination_b.type in NONCONNECTABLE_IFACE_TYPES:
|
||||||
|
raise ValidationError({
|
||||||
|
'termination_b_id': 'Cables cannot be terminated to {} interfaces'.format(
|
||||||
|
self.termination_b.get_type_display()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
# Check that termination types are compatible
|
# Check that termination types are compatible
|
||||||
if type_b not in COMPATIBLE_TERMINATION_TYPES.get(type_a):
|
if type_b not in COMPATIBLE_TERMINATION_TYPES.get(type_a):
|
||||||
raise ValidationError("Incompatible termination types: {} and {}".format(
|
raise ValidationError("Incompatible termination types: {} and {}".format(
|
||||||
@ -2858,20 +2872,6 @@ class Cable(ChangeLoggedModel):
|
|||||||
self.termination_b, self.termination_b.cable_id
|
self.termination_b, self.termination_b.cable_id
|
||||||
))
|
))
|
||||||
|
|
||||||
# Virtual interfaces cannot be connected
|
|
||||||
endpoint_a, endpoint_b, _ = self.get_path_endpoints()
|
|
||||||
if (
|
|
||||||
(
|
|
||||||
isinstance(endpoint_a, Interface) and
|
|
||||||
endpoint_a.type == IFACE_TYPE_VIRTUAL
|
|
||||||
) or
|
|
||||||
(
|
|
||||||
isinstance(endpoint_b, Interface) and
|
|
||||||
endpoint_b.type == IFACE_TYPE_VIRTUAL
|
|
||||||
)
|
|
||||||
):
|
|
||||||
raise ValidationError("Cannot connect to a virtual interface")
|
|
||||||
|
|
||||||
# Validate length and length_unit
|
# Validate length and length_unit
|
||||||
if self.length is not None and self.length_unit is None:
|
if self.length is not None and self.length_unit is None:
|
||||||
raise ValidationError("Must specify a unit when setting a cable length")
|
raise ValidationError("Must specify a unit when setting a cable length")
|
||||||
|
@ -343,7 +343,7 @@ class CableTestCase(TestCase):
|
|||||||
|
|
||||||
def test_cable_validates_compatibale_types(self):
|
def test_cable_validates_compatibale_types(self):
|
||||||
"""
|
"""
|
||||||
The clean method should have a check to ensure only compatiable port types can be connected by a cable
|
The clean method should have a check to ensure only compatible port types can be connected by a cable
|
||||||
"""
|
"""
|
||||||
# An interface cannot be connected to a power port
|
# An interface cannot be connected to a power port
|
||||||
cable = Cable(termination_a=self.interface1, termination_b=self.power_port1)
|
cable = Cable(termination_a=self.interface1, termination_b=self.power_port1)
|
||||||
@ -360,30 +360,39 @@ class CableTestCase(TestCase):
|
|||||||
|
|
||||||
def test_cable_front_port_cannot_connect_to_corresponding_rear_port(self):
|
def test_cable_front_port_cannot_connect_to_corresponding_rear_port(self):
|
||||||
"""
|
"""
|
||||||
A cable cannot connect a front port to its sorresponding rear port
|
A cable cannot connect a front port to its corresponding rear port
|
||||||
"""
|
"""
|
||||||
cable = Cable(termination_a=self.front_port, termination_b=self.rear_port)
|
cable = Cable(termination_a=self.front_port, termination_b=self.rear_port)
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
cable.clean()
|
cable.clean()
|
||||||
|
|
||||||
def test_cable_cannot_be_connected_to_an_existing_connection(self):
|
def test_cable_cannot_terminate_to_an_existing_connection(self):
|
||||||
"""
|
"""
|
||||||
Either side of a cable cannot be terminated when that side aready has a connection
|
Either side of a cable cannot be terminated when that side already has a connection
|
||||||
"""
|
"""
|
||||||
# Try to create a cable with the same interface terminations
|
# Try to create a cable with the same interface terminations
|
||||||
cable = Cable(termination_a=self.interface2, termination_b=self.interface1)
|
cable = Cable(termination_a=self.interface2, termination_b=self.interface1)
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
cable.clean()
|
cable.clean()
|
||||||
|
|
||||||
def test_cable_cannot_connect_to_a_virtual_inteface(self):
|
def test_cable_cannot_terminate_to_a_virtual_inteface(self):
|
||||||
"""
|
"""
|
||||||
A cable connection cannot include a virtual interface
|
A cable cannot terminate to a virtual interface
|
||||||
"""
|
"""
|
||||||
virtual_interface = Interface(device=self.device1, name="V1", type=0)
|
virtual_interface = Interface(device=self.device1, name="V1", type=IFACE_TYPE_VIRTUAL)
|
||||||
cable = Cable(termination_a=self.interface2, termination_b=virtual_interface)
|
cable = Cable(termination_a=self.interface2, termination_b=virtual_interface)
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
cable.clean()
|
cable.clean()
|
||||||
|
|
||||||
|
def test_cable_cannot_terminate_to_a_wireless_inteface(self):
|
||||||
|
"""
|
||||||
|
A cable cannot terminate to a wireless interface
|
||||||
|
"""
|
||||||
|
wireless_interface = Interface(device=self.device1, name="W1", type=IFACE_TYPE_80211A)
|
||||||
|
cable = Cable(termination_a=self.interface2, termination_b=wireless_interface)
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
cable.clean()
|
||||||
|
|
||||||
|
|
||||||
class CablePathTestCase(TestCase):
|
class CablePathTestCase(TestCase):
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user