示例#1
0
    def test_clean_invalid_asymmetric(self):
        """For a symmetric relationship, source and destination properties must match if specified."""
        o2os = Relationship(
            name="Site to Site",
            slug="site-to-site",
            source_type=self.site_ct,
            source_label="Site A",
            source_hidden=True,
            source_filter={"name": ["site-a"]},
            destination_type=self.rack_ct,
            destination_label="Site B",
            destination_hidden=False,
            destination_filter={"name": ["site-b"]},
            type=RelationshipTypeChoices.TYPE_ONE_TO_ONE_SYMMETRIC,
        )

        with self.assertRaises(ValidationError) as handler:
            o2os.clean()
        expected_errors = {
            "destination_type":
            ["Must match source_type for a symmetric relationship"],
            "destination_label":
            ["Must match source_label for a symmetric relationship"],
            "destination_hidden":
            ["Must match source_hidden for a symmetric relationship"],
            "destination_filter":
            ["Must match source_filter for a symmetric relationship"],
        }
        self.assertEqual(handler.exception.message_dict, expected_errors)
示例#2
0
    def setUpTestData(cls):
        device_type = ContentType.objects.get_for_model(Device)
        interface_type = ContentType.objects.get_for_model(Interface)
        vlan_type = ContentType.objects.get_for_model(VLAN)

        Relationship(
            name="Device VLANs",
            slug="device-vlans",
            type="many-to-many",
            source_type=device_type,
            destination_type=vlan_type,
        ).validated_save()
        Relationship(
            name="Primary VLAN",
            slug="primary-vlan",
            type="one-to-many",
            source_type=vlan_type,
            destination_type=device_type,
        ).validated_save()
        Relationship(
            name="Primary Interface",
            slug="primary-interface",
            type="one-to-one",
            source_type=device_type,
            destination_type=interface_type,
        ).validated_save()
示例#3
0
    def test_clean_same_object(self):
        m2m = Relationship(
            name="Another Vlan to Rack",
            slug="vlan-rack-2",
            source_type=self.rack_ct,
            destination_type=self.rack_ct,
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )

        with self.assertRaises(ValidationError):
            m2m.clean()
示例#4
0
    def test_clean_filter_not_valid(self):
        m2m = Relationship(
            name="Another Vlan to Rack",
            slug="vlan-rack-2",
            source_type=self.site_ct,
            source_filter={"notvalid": "not a region"},
            destination_type=self.rack_ct,
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )

        with self.assertRaises(ValidationError):
            m2m.clean()
示例#5
0
    def test_clean_valid(self):
        m2m = Relationship(
            name="Another Vlan to Rack",
            slug="vlan-rack-2",
            source_type=self.site_ct,
            source_filter={"name": ["site-b"]},
            destination_type=self.rack_ct,
            destination_filter={"site": ["site-a"]},
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )

        m2m.clean()
示例#6
0
    def test_clean_valid(self):
        m2m = Relationship(
            name="Another Vlan to Rack",
            slug="vlan-rack-2",
            source_type=self.site_ct,
            source_filter={"region": "myregion"},
            destination_type=self.rack_ct,
            destination_filter={"site": "mysite"},
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )

        m2m.clean()

        self.assertTrue(True)
示例#7
0
    def test_clean_filter_not_dict(self):
        m2m = Relationship(
            name="Another Vlan to Rack",
            slug="vlan-rack-2",
            source_type=self.site_ct,
            source_filter=["a list not a dict"],
            destination_type=self.rack_ct,
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )

        with self.assertRaises(ValidationError) as handler:
            m2m.clean()
        expected_errors = {
            "source_filter": ["Filter for dcim.Site must be a dictionary"]
        }
        self.assertEqual(handler.exception.message_dict, expected_errors)
示例#8
0
    def test_clean_valid_symmetric_implicit(self):
        """For a symmetric relationship, omitted relevant properties are autofilled on clean."""
        o2os = Relationship(
            name="Site to Site",
            slug="site-to-site",
            source_type=self.site_ct,
            destination_type=self.site_ct,
            source_label="Site",
            destination_filter={"name": ["site-b"]},
            type=RelationshipTypeChoices.TYPE_ONE_TO_ONE_SYMMETRIC,
        )

        o2os.clean()
        self.assertEqual(o2os.destination_label, "Site")
        self.assertEqual(o2os.source_filter, {"name": ["site-b"]})
        self.assertEqual(o2os.source_type, o2os.destination_type)
        self.assertEqual(o2os.source_label, o2os.destination_label)
        self.assertEqual(o2os.source_hidden, o2os.destination_hidden)
        self.assertEqual(o2os.source_filter, o2os.destination_filter)
示例#9
0
    def setUp(self):

        self.site_ct = ContentType.objects.get_for_model(Site)
        self.rack_ct = ContentType.objects.get_for_model(Rack)
        self.vlan_ct = ContentType.objects.get_for_model(VLAN)

        self.m2m_1 = Relationship(
            name="Vlan to Rack",
            slug="vlan-rack",
            source_type=self.rack_ct,
            source_label="My Vlans",
            source_filter={"site": "mysite"},
            destination_type=self.vlan_ct,
            destination_label="My Racks",
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )
        self.m2m_1.save()

        self.m2m_2 = Relationship(
            name="Another Vlan to Rack",
            slug="vlan-rack-2",
            source_type=self.rack_ct,
            destination_type=self.vlan_ct,
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )
        self.m2m_2.save()

        self.o2m_1 = Relationship(
            name="generic site to vlan",
            slug="site-vlan",
            source_type=self.site_ct,
            destination_type=self.vlan_ct,
            type=RelationshipTypeChoices.TYPE_ONE_TO_MANY,
        )
        self.o2m_1.save()

        self.o2o_1 = Relationship(
            name="Primary Rack per Site",
            slug="primary-rack-site",
            source_type=self.rack_ct,
            source_hidden=True,
            destination_type=self.site_ct,
            destination_label="Primary Rack",
            type=RelationshipTypeChoices.TYPE_ONE_TO_ONE,
        )
        self.o2o_1.save()

        self.sites = [
            Site.objects.create(name="Site A", slug="site-a"),
            Site.objects.create(name="Site B", slug="site-b"),
            Site.objects.create(name="Site C", slug="site-c"),
        ]

        self.racks = [
            Rack.objects.create(name="Rack A", site=self.sites[0]),
            Rack.objects.create(name="Rack B", site=self.sites[1]),
            Rack.objects.create(name="Rack C", site=self.sites[2]),
        ]

        self.vlans = [
            VLAN.objects.create(name="VLAN A", vid=100, site=self.sites[0]),
            VLAN.objects.create(name="VLAN B", vid=100, site=self.sites[1]),
            VLAN.objects.create(name="VLAN C", vid=100, site=self.sites[2]),
        ]
示例#10
0
    def setUpTestData(cls):
        cls.device_type = ContentType.objects.get_for_model(Device)
        cls.vlan_type = ContentType.objects.get_for_model(VLAN)

        cls.relationships = (
            Relationship(
                name="Device VLANs",
                slug="device-vlans",
                type="many-to-many",
                source_type=cls.device_type,
                destination_type=cls.vlan_type,
            ),
            Relationship(
                name="Primary VLAN",
                slug="primary-vlan",
                type="one-to-many",
                source_type=cls.vlan_type,
                destination_type=cls.device_type,
            ),
        )
        for relationship in cls.relationships:
            relationship.validated_save()

        manufacturer = Manufacturer.objects.create(name="Manufacturer 1", slug="manufacturer-1")
        devicetype = DeviceType.objects.create(manufacturer=manufacturer, model="Device Type 1", slug="device-type-1")
        devicerole = DeviceRole.objects.create(name="Device Role 1", slug="device-role-1")
        site = Site.objects.create(name="Site 1", slug="site-1")
        cls.devices = (
            Device.objects.create(name="Device 1", device_type=devicetype, device_role=devicerole, site=site),
            Device.objects.create(name="Device 2", device_type=devicetype, device_role=devicerole, site=site),
        )
        cls.vlans = (
            VLAN.objects.create(vid=1, name="VLAN 1"),
            VLAN.objects.create(vid=2, name="VLAN 2"),
        )

        RelationshipAssociation(
            relationship=cls.relationships[0],
            source_type=cls.device_type,
            source_id=cls.devices[0].pk,
            destination_type=cls.vlan_type,
            destination_id=cls.vlans[0].pk,
        ).validated_save()
        RelationshipAssociation(
            relationship=cls.relationships[0],
            source_type=cls.device_type,
            source_id=cls.devices[1].pk,
            destination_type=cls.vlan_type,
            destination_id=cls.vlans[1].pk,
        ).validated_save()
        RelationshipAssociation(
            relationship=cls.relationships[1],
            source_type=cls.vlan_type,
            source_id=cls.vlans[0].pk,
            destination_type=cls.device_type,
            destination_id=cls.devices[0].pk,
        ).validated_save()
        RelationshipAssociation(
            relationship=cls.relationships[1],
            source_type=cls.vlan_type,
            source_id=cls.vlans[1].pk,
            destination_type=cls.device_type,
            destination_id=cls.devices[1].pk,
        ).validated_save()
示例#11
0
    def setUpTestData(cls):
        cls.site = dcim_models.Site.objects.create(name="Site 1",
                                                   slug="site-1")
        cls.manufacturer = dcim_models.Manufacturer.objects.create(
            name="Manufacturer 1", slug="manufacturer-1")
        cls.device_type = dcim_models.DeviceType.objects.create(
            model="Device Type 1", manufacturer=cls.manufacturer)
        cls.device_role = dcim_models.DeviceRole.objects.create(
            name="Device Role 1", slug="device-role-1")
        cls.platform = dcim_models.Platform.objects.create(name="Platform 1",
                                                           slug="platform-1")
        cls.status_active = Status.objects.get(slug="active")
        cls.device_1 = dcim_models.Device.objects.create(
            name="Device 1",
            site=cls.site,
            device_type=cls.device_type,
            device_role=cls.device_role,
            platform=cls.platform,
            status=cls.status_active,
        )
        cls.device_2 = dcim_models.Device.objects.create(
            name="Device 2",
            site=cls.site,
            device_type=cls.device_type,
            device_role=cls.device_role,
            platform=cls.platform,
            status=cls.status_active,
        )
        cls.device_3 = dcim_models.Device.objects.create(
            name="Device 3",
            site=cls.site,
            device_type=cls.device_type,
            device_role=cls.device_role,
            platform=cls.platform,
            status=cls.status_active,
        )

        cls.ipaddress_1 = ipam_models.IPAddress.objects.create(
            address="10.1.1.1/24", status=cls.status_active)
        cls.ipaddress_2 = ipam_models.IPAddress.objects.create(
            address="10.2.2.2/24", status=cls.status_active)

        cls.vlangroup_1 = ipam_models.VLANGroup.objects.create(
            name="VLAN Group 1", slug="vlan-group-1", site=cls.site)
        cls.vlangroup_2 = ipam_models.VLANGroup.objects.create(
            name="VLAN Group 2", slug="vlan-group-2", site=cls.site)

        cls.relationship_1 = Relationship(
            name="BGP Router-ID",
            slug="bgp-router-id",
            source_type=ContentType.objects.get_for_model(dcim_models.Device),
            destination_type=ContentType.objects.get_for_model(
                ipam_models.IPAddress),
            type=RelationshipTypeChoices.TYPE_ONE_TO_ONE,
        )
        cls.relationship_1.validated_save()
        cls.relationship_2 = Relationship(
            name="Device VLAN Groups",
            slug="device-vlan-groups",
            source_type=ContentType.objects.get_for_model(dcim_models.Device),
            destination_type=ContentType.objects.get_for_model(
                ipam_models.VLANGroup),
            type=RelationshipTypeChoices.TYPE_ONE_TO_MANY,
        )
        cls.relationship_2.validated_save()
        cls.relationship_3 = Relationship(
            name="HA Device Peer",
            slug="ha-device-peer",
            source_type=ContentType.objects.get_for_model(dcim_models.Device),
            destination_type=ContentType.objects.get_for_model(
                dcim_models.Device),
            type=RelationshipTypeChoices.TYPE_ONE_TO_ONE_SYMMETRIC,
        )
        cls.relationship_3.validated_save()

        cls.device_form_base_data = {
            "name": "New Device",
            "device_role": cls.device_role.pk,
            "tenant": None,
            "manufacturer": cls.manufacturer.pk,
            "device_type": cls.device_type.pk,
            "site": cls.site.pk,
            "rack": None,
            "face": None,
            "position": None,
            "platform": cls.platform.pk,
            "status": cls.status_active.pk,
        }
        cls.ipaddress_form_base_data = {
            "address": "10.3.3.3/24",
            "status": cls.status_active.pk,
        }
        cls.vlangroup_form_base_data = {
            "site": cls.site.pk,
            "name": "New VLAN Group",
            "slug": "new-vlan-group",
        }
示例#12
0
    def setUp(self):

        self.site_ct = ContentType.objects.get_for_model(Site)
        self.rack_ct = ContentType.objects.get_for_model(Rack)
        self.vlan_ct = ContentType.objects.get_for_model(VLAN)

        self.sites = [
            Site.objects.create(name="Site A", slug="site-a"),
            Site.objects.create(name="Site B", slug="site-b"),
            Site.objects.create(name="Site C", slug="site-c"),
            Site.objects.create(name="Site D", slug="site-d"),
            Site.objects.create(name="Site E", slug="site-e"),
        ]

        self.racks = [
            Rack.objects.create(name="Rack A", site=self.sites[0]),
            Rack.objects.create(name="Rack B", site=self.sites[1]),
            Rack.objects.create(name="Rack C", site=self.sites[2]),
        ]

        self.vlans = [
            VLAN.objects.create(name="VLAN A", vid=100, site=self.sites[0]),
            VLAN.objects.create(name="VLAN B", vid=100, site=self.sites[1]),
            VLAN.objects.create(name="VLAN C", vid=100, site=self.sites[2]),
        ]

        self.m2m_1 = Relationship(
            name="Vlan to Rack",
            slug="vlan-rack",
            source_type=self.rack_ct,
            source_label="My Vlans",
            source_filter={"site": ["site-a"]},
            destination_type=self.vlan_ct,
            destination_label="My Racks",
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )
        self.m2m_1.validated_save()

        self.m2m_2 = Relationship(
            name="Another Vlan to Rack",
            slug="vlan-rack-2",
            source_type=self.rack_ct,
            destination_type=self.vlan_ct,
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )
        self.m2m_2.validated_save()

        self.o2m_1 = Relationship(
            name="generic site to vlan",
            slug="site-vlan",
            source_type=self.site_ct,
            destination_type=self.vlan_ct,
            type=RelationshipTypeChoices.TYPE_ONE_TO_MANY,
        )
        self.o2m_1.validated_save()

        self.o2o_1 = Relationship(
            name="Primary Rack per Site",
            slug="primary-rack-site",
            source_type=self.rack_ct,
            source_hidden=True,
            destination_type=self.site_ct,
            destination_label="Primary Rack",
            type=RelationshipTypeChoices.TYPE_ONE_TO_ONE,
        )
        self.o2o_1.validated_save()

        # Relationships between objects of the same type

        self.o2o_2 = Relationship(
            name="Alphabetical Sites",
            slug="alphabetical-sites",
            source_type=self.site_ct,
            source_label="Alphabetically Prior",
            destination_type=self.site_ct,
            destination_label="Alphabetically Subsequent",
            type=RelationshipTypeChoices.TYPE_ONE_TO_ONE,
        )
        self.o2o_2.validated_save()

        self.o2os_1 = Relationship(
            name="Redundant Rack",
            slug="redundant-rack",
            source_type=self.rack_ct,
            destination_type=self.rack_ct,
            type=RelationshipTypeChoices.TYPE_ONE_TO_ONE_SYMMETRIC,
        )
        self.o2os_1.validated_save()

        self.m2ms_1 = Relationship(
            name="Related Sites",
            slug="related-sites",
            source_type=self.site_ct,
            destination_type=self.site_ct,
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY_SYMMETRIC,
        )
        self.m2ms_1.validated_save()
示例#13
0
    def test_clean_filter_not_valid(self):
        m2m = Relationship(
            name="Another Vlan to Rack",
            slug="vlan-rack-2",
            source_type=self.site_ct,
            source_filter={"notvalid": "not a region"},
            destination_type=self.rack_ct,
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )

        with self.assertRaises(ValidationError) as handler:
            m2m.clean()
        expected_errors = {
            "source_filter": [
                "'notvalid' is not a valid filter parameter for dcim.Site object"
            ]
        }
        self.assertEqual(handler.exception.message_dict, expected_errors)

        m2m = Relationship(
            name="Another Vlan to Rack",
            slug="vlan-rack-2",
            source_type=self.site_ct,
            source_filter={"region": "not a list"},
            destination_type=self.rack_ct,
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )

        with self.assertRaises(ValidationError) as handler:
            m2m.clean()
        expected_errors = {
            "source_filter": ["'region': Enter a list of values."]
        }
        self.assertEqual(handler.exception.message_dict, expected_errors)

        m2m = Relationship(
            name="Another Vlan to Rack",
            slug="vlan-rack-2",
            source_type=self.site_ct,
            source_filter={"region": ["not a valid region"]},
            destination_type=self.rack_ct,
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )

        with self.assertRaises(ValidationError) as handler:
            m2m.clean()
        expected_errors = {
            "source_filter": [
                "'region': Select a valid choice. not a valid region is not one of the available choices."
            ]
        }
        self.assertEqual(handler.exception.message_dict, expected_errors)
示例#14
0
    def setUp(self):

        self.site_ct = ContentType.objects.get_for_model(Site)
        self.rack_ct = ContentType.objects.get_for_model(Rack)
        self.vlan_ct = ContentType.objects.get_for_model(VLAN)

        self.sites = [
            Site.objects.create(name="Site A", slug="site-a"),
            Site.objects.create(name="Site B", slug="site-b"),
            Site.objects.create(name="Site C", slug="site-c"),
            Site.objects.create(name="Site D", slug="site-d"),
            Site.objects.create(name="Site E", slug="site-e"),
        ]

        self.racks = [
            Rack.objects.create(name="Rack A", site=self.sites[0]),
            Rack.objects.create(name="Rack B", site=self.sites[1]),
            Rack.objects.create(name="Rack C", site=self.sites[2]),
        ]

        self.vlans = [
            VLAN.objects.create(name="VLAN A", vid=100, site=self.sites[0]),
            VLAN.objects.create(name="VLAN B", vid=100, site=self.sites[1]),
            VLAN.objects.create(name="VLAN C", vid=100, site=self.sites[2]),
        ]

        self.m2m_1 = Relationship(
            name="Vlan to Rack",
            slug="vlan-rack",
            source_type=self.rack_ct,
            source_label="My Vlans",
            source_filter={"site": ["site-a", "site-b", "site-c"]},
            destination_type=self.vlan_ct,
            destination_label="My Racks",
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )
        self.m2m_1.validated_save()

        self.m2m_2 = Relationship(
            name="Another Vlan to Rack",
            slug="vlan-rack-2",
            source_type=self.rack_ct,
            destination_type=self.vlan_ct,
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY,
        )
        self.m2m_2.validated_save()

        self.o2m_1 = Relationship(
            name="generic site to vlan",
            slug="site-vlan",
            source_type=self.site_ct,
            destination_type=self.vlan_ct,
            type=RelationshipTypeChoices.TYPE_ONE_TO_MANY,
        )
        self.o2m_1.validated_save()

        self.o2o_1 = Relationship(
            name="Primary Rack per Site",
            slug="primary-rack-site",
            source_type=self.rack_ct,
            source_hidden=True,
            destination_type=self.site_ct,
            destination_label="Primary Rack",
            type=RelationshipTypeChoices.TYPE_ONE_TO_ONE,
        )
        self.o2o_1.validated_save()

        # Relationships between objects of the same type

        self.o2o_2 = Relationship(
            name="Alphabetical Sites",
            slug="alphabetical-sites",
            source_type=self.site_ct,
            source_label="Alphabetically Prior",
            destination_type=self.site_ct,
            destination_label="Alphabetically Subsequent",
            type=RelationshipTypeChoices.TYPE_ONE_TO_ONE,
        )
        self.o2o_2.validated_save()

        self.o2os_1 = Relationship(
            name="Redundant Rack",
            slug="redundant-rack",
            source_type=self.rack_ct,
            destination_type=self.rack_ct,
            type=RelationshipTypeChoices.TYPE_ONE_TO_ONE_SYMMETRIC,
        )
        self.o2os_1.validated_save()

        self.m2ms_1 = Relationship(
            name="Related Sites",
            slug="related-sites",
            source_type=self.site_ct,
            destination_type=self.site_ct,
            type=RelationshipTypeChoices.TYPE_MANY_TO_MANY_SYMMETRIC,
        )
        self.m2ms_1.validated_save()

        # Relationships involving a content type that doesn't actually have a backing model.
        # This can occur in practice if, for example, a relationship is defined for a plugin-defined model,
        # then the plugin is subsequently uninstalled or deactivated.
        self.invalid_ct = ContentType.objects.create(app_label="nonexistent",
                                                     model="nosuchmodel")

        # Don't use validated_save() on these as it will fail due to the invalid content-type
        self.invalid_relationships = [
            Relationship.objects.create(
                name="Invalid Relationship 1",
                slug="invalid-relationship-1",
                source_type=self.site_ct,
                destination_type=self.invalid_ct,
                type=RelationshipTypeChoices.TYPE_ONE_TO_ONE,
            ),
            Relationship.objects.create(
                name="Invalid Relationship 2",
                slug="invalid-relationship-2",
                source_type=self.invalid_ct,
                destination_type=self.site_ct,
                type=RelationshipTypeChoices.TYPE_ONE_TO_MANY,
            ),
            Relationship.objects.create(
                name="Invalid Relationship 3",
                slug="invalid-relationship-3",
                source_type=self.invalid_ct,
                destination_type=self.invalid_ct,
                type=RelationshipTypeChoices.TYPE_MANY_TO_MANY_SYMMETRIC,
            ),
        ]