Exemple #1
0
    def test_create_relationship_associations_valid_1(self):
        """
        A new record can create ONE_TO_ONE and ONE_TO_MANY associations where it is the "source" object.
        """
        form = DeviceForm(data=dict(
            **self.device_form_base_data,
            **{
                f"cr_{self.relationship_1.slug}__destination":
                self.ipaddress_1.pk,
                f"cr_{self.relationship_2.slug}__destination":
                [self.vlangroup_1.pk, self.vlangroup_2.pk],
            },
        ))
        self.assertTrue(form.is_valid())
        self.assertTrue(form.save())

        new_device = dcim_models.Device.objects.get(
            name=self.device_form_base_data["name"])
        # Verify that RelationshipAssociations were created
        RelationshipAssociation.objects.get(relationship=self.relationship_1,
                                            source_id=new_device.pk,
                                            destination_id=self.ipaddress_1.pk)
        RelationshipAssociation.objects.get(relationship=self.relationship_2,
                                            source_id=new_device.pk,
                                            destination_id=self.vlangroup_1.pk)
        RelationshipAssociation.objects.get(relationship=self.relationship_2,
                                            source_id=new_device.pk,
                                            destination_id=self.vlangroup_2.pk)
Exemple #2
0
    def test_create_relationship_associations_invalid_2(self):
        """
        A new record CANNOT create ONE_TO_MANY relations where any of its "destinations" are already associated.
        """
        # Existing ONE_TO_MANY relation
        RelationshipAssociation.objects.create(
            relationship=self.relationship_2,
            source_type=self.relationship_2.source_type,
            source_id=self.device_1.pk,
            destination_type=self.relationship_2.destination_type,
            destination_id=self.vlangroup_1.pk,
        )

        # Can't associate New Device with VLAN Group 1 (already associated to Device 1)
        form = DeviceForm(data=dict(
            **self.device_form_base_data,
            **{
                f"cr_{self.relationship_2.slug}__destination":
                [self.vlangroup_1.pk, self.vlangroup_2.pk]
            },
        ))
        self.assertFalse(form.is_valid())
        self.assertEqual(
            "VLAN Group 1 is already involved in a Device VLAN Groups relationship",
            form.errors[f"cr_{self.relationship_2.slug}__destination"][0],
        )
Exemple #3
0
    def test_create_relationship_associations_invalid_1(self):
        """
        A new record CANNOT create ONE_TO_ONE relations where its "destination" is already associated.
        """
        # Existing ONE_TO_ONE relation
        RelationshipAssociation.objects.create(
            relationship=self.relationship_1,
            source_type=self.relationship_1.source_type,
            source_id=self.device_1.pk,
            destination_type=self.relationship_1.destination_type,
            destination_id=self.ipaddress_1.pk,
        )

        # Can't associate New Device with IP Address 1 (already associated to Device 1)
        form = DeviceForm(data=dict(
            **self.device_form_base_data, **{
                f"cr_{self.relationship_1.slug}__destination":
                self.ipaddress_1.pk
            }))
        self.assertFalse(form.is_valid())
        self.assertEqual(
            "10.1.1.1/24 is already involved in a BGP Router-ID relationship",
            form.errors[f"cr_{self.relationship_1.slug}__destination"][0],
        )

        # Can't associate new IP address with Device 1 (already associated with IP Address 1)
        form = IPAddressForm(data=dict(
            **self.ipaddress_form_base_data, **
            {f"cr_{self.relationship_1.slug}__source": self.device_1.pk}))
        self.assertFalse(form.is_valid())
        self.assertEqual(
            "Device 1 is already involved in a BGP Router-ID relationship",
            form.errors[f"cr_{self.relationship_1.slug}__source"][0],
        )
Exemple #4
0
    def test_update_relationship_associations_valid_1(self):
        """
        An existing record with an existing ONE_TO_ONE or ONE_TO_MANY association can change its destination(s).
        """
        # Existing ONE_TO_ONE relation
        RelationshipAssociation.objects.create(
            relationship=self.relationship_1,
            source_type=self.relationship_1.source_type,
            source_id=self.device_1.pk,
            destination_type=self.relationship_1.destination_type,
            destination_id=self.ipaddress_1.pk,
        )
        # Existing ONE_TO_MANY relation
        RelationshipAssociation.objects.create(
            relationship=self.relationship_2,
            source_type=self.relationship_2.source_type,
            source_id=self.device_1.pk,
            destination_type=self.relationship_2.destination_type,
            destination_id=self.vlangroup_1.pk,
        )

        form = DeviceForm(
            instance=self.device_1,
            data={
                "site":
                self.site,
                "device_role":
                self.device_role,
                "device_type":
                self.device_type,
                "status":
                self.status_active,
                f"cr_{self.relationship_1.slug}__destination":
                self.ipaddress_2.pk,
                f"cr_{self.relationship_2.slug}__destination":
                [self.vlangroup_2.pk],
            },
        )
        self.assertTrue(form.is_valid(), form.errors)
        self.assertTrue(form.save())

        # Existing ONE_TO_ONE relation should have been deleted and replaced
        with self.assertRaises(RelationshipAssociation.DoesNotExist):
            RelationshipAssociation.objects.get(
                relationship=self.relationship_1,
                destination_id=self.ipaddress_1.pk)
        RelationshipAssociation.objects.get(relationship=self.relationship_1,
                                            source_id=self.device_1.pk,
                                            destination_id=self.ipaddress_2.pk)

        # Existing ONE_TO_MANY relation should have been deleted and replaced
        with self.assertRaises(RelationshipAssociation.DoesNotExist):
            RelationshipAssociation.objects.get(
                relationship=self.relationship_2,
                destination_id=self.vlangroup_1.pk)
        RelationshipAssociation.objects.get(relationship=self.relationship_2,
                                            source_id=self.device_1.pk,
                                            destination_id=self.vlangroup_2.pk)
Exemple #5
0
 def test_non_racked_device_with_position(self):
     form = DeviceForm(
         data={
             "name": "New Device",
             "device_role": DeviceRole.objects.first().pk,
             "tenant": None,
             "manufacturer": Manufacturer.objects.first().pk,
             "device_type": DeviceType.objects.first().pk,
             "site": Site.objects.first().pk,
             "rack": None,
             "position": 10,
             "platform": None,
             "status": self.device_status.pk,
         })
     self.assertFalse(form.is_valid())
     self.assertIn("position", form.errors)
Exemple #6
0
 def test_racked_device_occupied(self):
     form = DeviceForm(
         data={
             "name": "test",
             "device_role": DeviceRole.objects.first().pk,
             "tenant": None,
             "manufacturer": Manufacturer.objects.first().pk,
             "device_type": DeviceType.objects.first().pk,
             "site": Site.objects.first().pk,
             "rack": Rack.objects.first().pk,
             "face": DeviceFaceChoices.FACE_FRONT,
             "position": 1,
             "platform": Platform.objects.first().pk,
             "status": self.device_status.pk,
         })
     self.assertFalse(form.is_valid())
     self.assertIn("position", form.errors)
Exemple #7
0
 def test_racked_device(self):
     form = DeviceForm(
         data={
             "name": "New Device",
             "device_role": DeviceRole.objects.first().pk,
             "tenant": None,
             "manufacturer": Manufacturer.objects.first().pk,
             "device_type": DeviceType.objects.first().pk,
             "site": Site.objects.first().pk,
             "rack": Rack.objects.first().pk,
             "face": DeviceFaceChoices.FACE_FRONT,
             "position": 2,
             "platform": Platform.objects.first().pk,
             "status": self.device_status.pk,
         })
     self.assertTrue(form.is_valid())
     self.assertTrue(form.save())
Exemple #8
0
 def test_non_racked_device(self):
     form = DeviceForm(
         data={
             "name": "New Device",
             "device_role": DeviceRole.objects.first().pk,
             "tenant": None,
             "manufacturer": Manufacturer.objects.first().pk,
             "device_type": DeviceType.objects.first().pk,
             "site": Site.objects.first().pk,
             "rack": None,
             "face": None,
             "position": None,
             "platform": Platform.objects.first().pk,
             "status": self.device_status.pk,
             "secrets_group": SecretsGroup.objects.first().pk,
         })
     self.assertTrue(form.is_valid())
     self.assertTrue(form.save())
Exemple #9
0
 def test_update_relationship_associatioins_invalid_1(self):
     """
     A record CANNOT form a relationship to itself.
     """
     form = DeviceForm(
         instance=self.device_1,
         data={
             "site": self.site,
             "device_role": self.device_role,
             "device_type": self.device_type,
             "status": self.status_active,
             f"cr_{self.relationship_3.slug}__peer": self.device_1.pk,
         },
     )
     self.assertFalse(form.is_valid())
     self.assertEqual(
         "Object Device 1 cannot form a relationship to itself!",
         form.errors[f"cr_{self.relationship_3.slug}__peer"][0],
     )
Exemple #10
0
    def test_create_relationship_associations_invalid_3(self):
        """
        A new record CANNOT create ONE_TO_ONE_SYMMETRIC relations where its peer is already associated.
        """
        # Existing ONE_TO_ONE_SYMMETRIC relation
        RelationshipAssociation(
            relationship=self.relationship_3,
            source_type=self.relationship_3.source_type,
            source_id=self.device_1.pk,
            destination_type=self.relationship_3.destination_type,
            destination_id=self.device_2.pk,
        ).validated_save()

        # Peer is already a source for this relationship
        form = DeviceForm(data=dict(
            **self.device_form_base_data, **
            {f"cr_{self.relationship_3.slug}__peer": self.device_1.pk}))
        self.assertFalse(form.is_valid())
        self.assertEqual(
            "Device 1 is already involved in a HA Device Peer relationship",
            form.errors[f"cr_{self.relationship_3.slug}__peer"][0],
        )

        # Peer is already a destination for this relationship
        form = DeviceForm(data=dict(
            **self.device_form_base_data, **
            {f"cr_{self.relationship_3.slug}__peer": self.device_2.pk}))
        self.assertFalse(form.is_valid())
        self.assertEqual(
            "Device 2 is already involved in a HA Device Peer relationship",
            form.errors[f"cr_{self.relationship_3.slug}__peer"][0],
        )
Exemple #11
0
    def test_update_relationship_associations_valid_4(self):
        """
        An existing record with an existing ONE_TO_ONE_SYMMETRIC association can change its peer.

        This differs from test_update_relationship_associations_valid_1 in that the existing association has this
        record as the destination rather than the source, which *should* work either way.
        """
        # Existing ONE_TO_ONE_SYMMETRIC relation
        RelationshipAssociation(
            relationship=self.relationship_3,
            source_type=self.relationship_3.source_type,
            source_id=self.device_3.pk,
            destination_type=self.relationship_3.destination_type,
            destination_id=self.device_1.pk,
        ).validated_save()

        form = DeviceForm(
            instance=self.device_1,
            data={
                "site": self.site,
                "device_role": self.device_role,
                "device_type": self.device_type,
                "status": self.status_active,
                f"cr_{self.relationship_3.slug}__peer": self.device_2.pk,
            },
        )
        self.assertTrue(form.is_valid(), form.errors)
        self.assertTrue(form.save())

        # Existing ONE_TO_ONE_SYMMETRIC relation should have been deleted and replaced
        with self.assertRaises(RelationshipAssociation.DoesNotExist):
            RelationshipAssociation.objects.get(
                relationship=self.relationship_3, source_id=self.device_3.pk)
        RelationshipAssociation.objects.get(
            Q(source_id=self.device_1.pk, destination_id=self.device_2.pk)
            | Q(source_id=self.device_2.pk, destination_id=self.device_1.pk),
            relationship=self.relationship_3,
        )
Exemple #12
0
    def test_create_relationship_associations_valid_1(self):
        """
        A new record can create ONE_TO_ONE and ONE_TO_MANY associations where it is the "source" object.

        It can also create ONE_TO_ONE_SYMMETRIC associations where it is a "peer" object.
        """
        form = DeviceForm(data=dict(
            **self.device_form_base_data,
            **{
                f"cr_{self.relationship_1.slug}__destination":
                self.ipaddress_1.pk,
                f"cr_{self.relationship_2.slug}__destination":
                [self.vlangroup_1.pk, self.vlangroup_2.pk],
                f"cr_{self.relationship_3.slug}__peer":
                self.device_1.pk,
            },
        ))
        self.assertTrue(form.is_valid())
        self.assertTrue(form.save())

        new_device = dcim_models.Device.objects.get(
            name=self.device_form_base_data["name"])
        # Verify that RelationshipAssociations were created
        RelationshipAssociation.objects.get(relationship=self.relationship_1,
                                            source_id=new_device.pk,
                                            destination_id=self.ipaddress_1.pk)
        RelationshipAssociation.objects.get(relationship=self.relationship_2,
                                            source_id=new_device.pk,
                                            destination_id=self.vlangroup_1.pk)
        RelationshipAssociation.objects.get(relationship=self.relationship_2,
                                            source_id=new_device.pk,
                                            destination_id=self.vlangroup_2.pk)
        # relationship_3 is symmetric, we don't care which side is "source" or "destination" as long as it exists
        RelationshipAssociation.objects.get(
            Q(source_id=new_device.pk, destination_id=self.device_1.pk)
            | Q(source_id=self.device_1.pk, destination_id=new_device.pk),
            relationship=self.relationship_3,
        )