|
|
@@ -5681,6 +5681,55 @@ class VirtualChassisTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
self.assertEqual(member.virtual_chassis.name, 'VC1')
|
|
|
self.assertEqual(member.vc_position, 2)
|
|
|
|
|
|
+ @tag('regression') # Ref: #23212
|
|
|
+ def test_add_member_blocked_by_cross_chassis_lag(self):
|
|
|
+ self.add_permissions('dcim.change_virtualchassis')
|
|
|
+ vc1_member = Device.objects.get(name='Device 1')
|
|
|
+ device = Device.objects.get(name='Device 10')
|
|
|
+ lag = Interface.objects.create(device=vc1_member, name='lag0', type=InterfaceTypeChoices.TYPE_LAG)
|
|
|
+ Interface.objects.create(device=device, name='eth0', type=InterfaceTypeChoices.TYPE_1GE_FIXED, lag=lag)
|
|
|
+
|
|
|
+ vc2 = VirtualChassis.objects.get(name='VC2')
|
|
|
+ url = reverse('dcim:virtualchassis_add_member', kwargs={'pk': vc2.pk})
|
|
|
+ response = self.client.post(url, {'device': device.pk, 'vc_position': 4, 'vc_priority': ''})
|
|
|
+ self.assertHttpStatus(response, 200)
|
|
|
+ self.assertIn('outside the virtual chassis', str(response.content))
|
|
|
+
|
|
|
+ device.refresh_from_db()
|
|
|
+ self.assertIsNone(device.virtual_chassis)
|
|
|
+ self.assertIsNone(device.vc_position)
|
|
|
+
|
|
|
+ @tag('regression') # Ref: #23212
|
|
|
+ def test_create_with_members_blocked_by_cross_chassis_lag(self):
|
|
|
+ self.add_permissions('dcim.add_virtualchassis', 'dcim.view_device')
|
|
|
+ vc1_member = Device.objects.get(name='Device 1')
|
|
|
+ device = Device.objects.get(name='Device 10')
|
|
|
+ lag = Interface.objects.create(device=vc1_member, name='lag0', type=InterfaceTypeChoices.TYPE_LAG)
|
|
|
+ Interface.objects.create(device=device, name='eth0', type=InterfaceTypeChoices.TYPE_1GE_FIXED, lag=lag)
|
|
|
+
|
|
|
+ data = {'name': 'VC4', 'members': [device.pk], 'initial_position': 1}
|
|
|
+ response = self.client.post(reverse('dcim:virtualchassis_add'), data)
|
|
|
+ self.assertHttpStatus(response, 200)
|
|
|
+ self.assertIn('outside the virtual chassis', str(response.content))
|
|
|
+ self.assertFalse(VirtualChassis.objects.filter(name='VC4').exists())
|
|
|
+
|
|
|
+ device.refresh_from_db()
|
|
|
+ self.assertIsNone(device.virtual_chassis)
|
|
|
+
|
|
|
+ def test_create_with_members_allowed_with_lag_between_new_members(self):
|
|
|
+ self.add_permissions('dcim.add_virtualchassis', 'dcim.view_device')
|
|
|
+ device1 = Device.objects.get(name='Device 10')
|
|
|
+ device2 = Device.objects.get(name='Device 11')
|
|
|
+ lag = Interface.objects.create(device=device1, name='lag0', type=InterfaceTypeChoices.TYPE_LAG)
|
|
|
+ Interface.objects.create(device=device2, name='eth0', type=InterfaceTypeChoices.TYPE_1GE_FIXED, lag=lag)
|
|
|
+
|
|
|
+ data = {'name': 'VC4', 'members': [device1.pk, device2.pk], 'initial_position': 1}
|
|
|
+ response = self.client.post(reverse('dcim:virtualchassis_add'), data)
|
|
|
+ self.assertHttpStatus(response, 302)
|
|
|
+
|
|
|
+ vc = VirtualChassis.objects.get(name='VC4')
|
|
|
+ self.assertEqual(set(vc.members.values_list('name', flat=True)), {'Device 10', 'Device 11'})
|
|
|
+
|
|
|
def test_remove_member(self):
|
|
|
self.add_permissions('dcim.change_device')
|
|
|
master = Device.objects.get(name='Device 1')
|