فهرست منبع

Fixes #3519: Prevent cables from being terminated to virtual/wireless interfaces

Jeremy Stretch 6 سال پیش
والد
کامیت
ffc6eec483
3فایلهای تغییر یافته به همراه32 افزوده شده و 22 حذف شده
  1. 2 1
      CHANGELOG.md
  2. 14 14
      netbox/dcim/models.py
  3. 16 7
      netbox/dcim/tests/test_models.py

+ 2 - 1
CHANGELOG.md

@@ -2,7 +2,8 @@ v2.6.5 (FUTURE)
 
 ## 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)
 

+ 14 - 14
netbox/dcim/models.py

@@ -2817,6 +2817,20 @@ class Cable(ChangeLoggedModel):
         type_a = self.termination_a_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
         if type_b not in COMPATIBLE_TERMINATION_TYPES.get(type_a):
             raise ValidationError("Incompatible termination types: {} and {}".format(
@@ -2858,20 +2872,6 @@ class Cable(ChangeLoggedModel):
                 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
         if self.length is not None and self.length_unit is None:
             raise ValidationError("Must specify a unit when setting a cable length")

+ 16 - 7
netbox/dcim/tests/test_models.py

@@ -343,7 +343,7 @@ class CableTestCase(TestCase):
 
     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
         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):
         """
-        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)
         with self.assertRaises(ValidationError):
             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
         cable = Cable(termination_a=self.interface2, termination_b=self.interface1)
         with self.assertRaises(ValidationError):
             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)
         with self.assertRaises(ValidationError):
             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):