@@ -180,7 +180,7 @@ def test_str(self):
180180 # self.assertEqual(self.peergroup.vrf, vrf)
181181
182182
183- class PeerEndpointTestCase (TestCase ):
183+ class PeerEndpointTestCase (TestCase ): # pylint: disable=too-many-instance-attributes
184184 """Test the PeerEndpoint model."""
185185
186186 @classmethod
@@ -197,15 +197,14 @@ def setUpTestData(cls): # pylint: disable=too-many-locals
197197 location = Location .objects .create (name = "Site 1" , location_type = location_type , status = location_status )
198198 devicerole = Role .objects .create (name = "Router" , color = "ff0000" )
199199 devicerole .content_types .add (ContentType .objects .get_for_model (Device ))
200- device_1 = Device .objects .create (
200+ cls . device_1 = Device .objects .create (
201201 device_type = devicetype , role = devicerole , name = "Device 1" , location = location , status = cls .status_active
202202 )
203- interface_status = Status .objects .get_for_model (Interface ).first ()
204- cls .interface_1 = Interface .objects .create (device = device_1 , name = "Loopback1" , status = interface_status )
203+ cls .interface_status = Status .objects .get_for_model (Interface ).first ()
205204 device_2 = Device .objects .create (
206205 device_type = devicetype , role = devicerole , name = "Device 2" , location = location , status = cls .status_active
207206 )
208- cls .interface_2 = Interface .objects .create (device = device_2 , name = "Loopback1" , status = interface_status )
207+ cls .interface_2 = Interface .objects .create (device = device_2 , name = "Loopback1" , status = cls . interface_status )
209208
210209 cls .peeringrole_internal = Role .objects .create (name = "Internal" , color = "333333" )
211210 cls .peeringrole_internal .content_types .add (ContentType .objects .get_for_model (models .PeerGroup ))
@@ -225,7 +224,7 @@ def setUpTestData(cls): # pylint: disable=too-many-locals
225224 bgp_routing_instance_1 = models .BGPRoutingInstance .objects .create (
226225 description = "BGP Routing Instance for device 1" ,
227226 autonomous_system = autonomous_system_12345 ,
228- device = device_1 ,
227+ device = cls . device_1 ,
229228 status = status_active ,
230229 )
231230 cls .bgp_routing_instance_1 = bgp_routing_instance_1
@@ -238,46 +237,59 @@ def setUpTestData(cls): # pylint: disable=too-many-locals
238237 )
239238 cls .bgp_routing_instance_2 = bgp_routing_instance_2
240239
241- cls .peergroup_1 = models .PeerGroup .objects .create (
242- name = "Peer Group A" ,
243- role = cls .peeringrole_internal ,
244- routing_instance = bgp_routing_instance_1 ,
245- )
246240 cls .peergroup_2 = models .PeerGroup .objects .create (
247241 name = "Peer Group A" ,
248242 role = cls .peeringrole_internal ,
249243 routing_instance = bgp_routing_instance_2 ,
250244 )
251245
252246 cls .namespace = Namespace .objects .first ()
253- prefix_status = Status .objects .get_for_model (Prefix ).first ()
254- Prefix .objects .create (prefix = "1.0.0.0/8" , namespace = cls .namespace , status = prefix_status )
247+ cls .prefix_status = Status .objects .get_for_model (Prefix ).first ()
255248
256- cls .ipaddress_2 = IPAddress .objects .create (
257- address = "1.1.1.2/32" ,
258- status = status_active ,
259- namespace = cls .namespace ,
260- )
261249 vm_cluster_type = ClusterType .objects .create (name = "vShpere" )
262250 vm_cluster = Cluster .objects .create (name = "VM Test Cluster" , cluster_type = vm_cluster_type )
263251 cls .virtual_machine_1 = VirtualMachine .objects .create (name = "VM 1" , cluster = vm_cluster , status = cls .status_active )
264252 cls .vm_interface_1 = VMInterface .objects .create (
265253 name = "Loopback1" , virtual_machine = cls .virtual_machine_1 , status = status_active
266254 )
255+ cls .vrf = VRF .objects .create (name = "VRF" )
267256
268257 def setUp (self ):
269258 """Per-test data setup."""
270259
271260 self .peering = models .Peering .objects .create (status = self .status_active )
272261
262+ self .interface_1 = Interface .objects .create (
263+ device = self .device_1 ,
264+ name = "Loopback1" ,
265+ status = self .interface_status ,
266+ )
267+
268+ self .prefix_1 = Prefix .objects .create (
269+ prefix = "1.0.0.0/8" ,
270+ namespace = self .namespace ,
271+ status = self .prefix_status ,
272+ )
273+
273274 self .ipaddress_1 = IPAddress .objects .create (
274275 address = "1.1.1.1/32" ,
275276 status = self .status_active ,
276277 namespace = self .namespace ,
277278 )
279+ self .ipaddress_2 = IPAddress .objects .create (
280+ address = "1.1.1.2/32" ,
281+ status = self .status_active ,
282+ namespace = self .namespace ,
283+ )
278284
279285 self .interface_1 .add_ip_addresses (self .ipaddress_1 )
280286
287+ self .peergroup_1 = models .PeerGroup .objects .create (
288+ name = "Peer Group A" ,
289+ role = self .peeringrole_internal ,
290+ routing_instance = self .bgp_routing_instance_1 ,
291+ )
292+
281293 self .peerendpoint_1 = models .PeerEndpoint .objects .create (
282294 source_ip = self .ipaddress_1 ,
283295 peer_group = self .peergroup_1 ,
@@ -303,29 +315,107 @@ def test_str(self):
303315 #
304316 # # TODO VRF fixup from router_id?
305317 #
306- # def test_local_ip_vrf_mismatch(self):
307- # """Clean should fail if local_ip is assigned to a different VRF than the specified one."""
308- # self.peerendpoint_1.vrf = VRF.objects.create(name="Some other VRF")
309- # with self.assertRaises(ValidationError) as context:
310- # self.peerendpoint_1.validated_save()
311- # self.assertEqual(
312- # context.exception.messages[0],
313- # "VRF Some other VRF was specified, but one or more attributes refer instead to Ark B",
314- # )
315- #
316- # def test_peer_group_vrf_mismatch(self):
317- # """The specified peer-group must belong to the specified VRF if any."""
318- # self.peerendpoint_1.peer_group = models.PeerGroup.objects.create(
319- # name="Group B",
320- # role=self.peeringrole_internal,
321- # vrf=None,
322- # )
323- # with self.assertRaises(ValidationError) as context:
324- # self.peerendpoint_1.validated_save()
325- # self.assertIn(
326- # "Various attributes refer to different VRFs",
327- # context.exception.messages[0],
328- # )
318+
319+ def test_peer_group_no_vrf (self ):
320+ """Test endpoint VRF passes when peer-group doesn't have VRF assigned."""
321+ self .assertIsNone (self .peergroup_1 .vrf )
322+
323+ self .peerendpoint_1 .peer_group = self .peergroup_1
324+ self .peerendpoint_1 .validated_save ()
325+
326+ def test_peer_group_vrf_ip_match (self ):
327+ """Test peer-group IP VRF countst for matching VRF."""
328+ self .assertIsNone (self .interface_1 .vrf )
329+
330+ self .peergroup_1 .vrf = self .vrf
331+ self .peergroup_1 .save ()
332+ self .prefix_1 .vrfs .add (self .vrf )
333+ self .prefix_1 .save ()
334+
335+ self .peerendpoint_1 .peer_group = self .peergroup_1
336+ self .peerendpoint_1 .validated_save ()
337+
338+ def test_peer_group_vrf_ip_mismatch (self ):
339+ """Test endpoint VRF mismatch raises error when no interface defined."""
340+ self .assertIsNone (self .peerendpoint_1 .source_interface )
341+ self .assertIsNone (self .peergroup_1 .source_interface )
342+ self .assertTrue (self .vrf not in self .prefix_1 .vrfs .all ())
343+
344+ self .peergroup_1 .vrf = self .vrf
345+ self .peergroup_1 .save ()
346+
347+ self .peerendpoint_1 .peer_group = self .peergroup_1
348+
349+ with self .assertRaises (ValidationError ) as context :
350+ self .peerendpoint_1 .validated_save ()
351+
352+ self .assertEqual (
353+ context .exception .messages [0 ],
354+ f"VRF mismatch between { self .ipaddress_1 } (VRF None) "
355+ f"and peer-group { self .peergroup_1 .name } (VRF { self .peergroup_1 .vrf } )" ,
356+ )
357+
358+ def test_vrf_interface_match (self ):
359+ """Test endpoint interface VRF counts for matching VRF."""
360+ self .assertIsNone (self .peergroup_1 .source_interface )
361+
362+ self .interface_1 .vrf = self .vrf
363+ self .interface_1 .save ()
364+ self .peergroup_1 .vrf = self .vrf
365+ self .peergroup_1 .save ()
366+ self .peerendpoint_1 .source_interface = self .interface_1
367+ self .peerendpoint_1 .peer_group = self .peergroup_1
368+ self .peerendpoint_1 .validated_save ()
369+
370+ def test_vrf_interface_mismatch (self ):
371+ """Test endpoint interface VRF mismatch raises error."""
372+ self .assertIsNone (self .peergroup_1 .source_interface )
373+ self .assertIsNone (self .interface_1 .vrf )
374+
375+ self .peergroup_1 .vrf = self .vrf
376+ self .peergroup_1 .save ()
377+ self .peerendpoint_1 .source_interface = self .interface_1
378+ self .peerendpoint_1 .peer_group = self .peergroup_1
379+
380+ with self .assertRaises (ValidationError ) as context :
381+ self .peerendpoint_1 .validated_save ()
382+
383+ self .assertEqual (
384+ context .exception .messages [0 ],
385+ f"VRF mismatch between { self .interface_1 } (VRF None) "
386+ f"and peer-group { self .peergroup_1 .name } (VRF { self .peergroup_1 .vrf } )" ,
387+ )
388+
389+ def test_peer_group_vrf_interface_match (self ):
390+ """Test peer-group interface VRF counts for matching VRF."""
391+ self .assertIsNone (self .peerendpoint_1 .source_interface )
392+
393+ self .interface_1 .vrf = self .vrf
394+ self .interface_1 .save ()
395+ self .peergroup_1 .vrf = self .vrf
396+ self .peergroup_1 .source_interface = self .interface_1
397+ self .peergroup_1 .save ()
398+ self .peerendpoint_1 .peer_group = self .peergroup_1
399+ self .peerendpoint_1 .validated_save ()
400+
401+ def test_peer_group_vrf_interface_mismatch (self ):
402+ """Test peer-group interface VRF mismatch raises error."""
403+ self .assertIsNone (self .peerendpoint_1 .source_interface )
404+ self .assertIsNone (self .interface_1 .vrf )
405+
406+ self .peergroup_1 .source_interface = self .interface_1
407+ self .peergroup_1 .vrf = self .vrf
408+ self .peergroup_1 .save ()
409+ self .peerendpoint_1 .peer_group = self .peergroup_1
410+
411+ with self .assertRaises (ValidationError ) as context :
412+ self .peerendpoint_1 .validated_save ()
413+
414+ self .assertEqual (
415+ context .exception .messages [0 ],
416+ f"VRF mismatch between { self .interface_1 } (VRF None) "
417+ f"and peer-group { self .peergroup_1 .name } (VRF { self .peergroup_1 .vrf } )" ,
418+ )
329419
330420 def test_deleting_ip_address_protects_endpoint (self ):
331421 """Deleting an IPAddress should protect the associated PeerEndpoint(s)."""
0 commit comments