diff --git a/netbox/dcim/graphql/__init__.py b/netbox/dcim/graphql/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/netbox/dcim/graphql/schema.py b/netbox/dcim/graphql/schema.py new file mode 100644 index 000000000..d296c3ebc --- /dev/null +++ b/netbox/dcim/graphql/schema.py @@ -0,0 +1,106 @@ +import graphene + +from netbox.graphql.fields import ObjectField, ObjectListField +from .types import * + + +class DCIMQuery(graphene.ObjectType): + cable = ObjectField(CableType) + cables = ObjectListField(CableType) + + console_port = ObjectField(ConsolePortType) + console_ports = ObjectListField(ConsolePortType) + + console_port_template = ObjectField(ConsolePortTemplateType) + console_port_templates = ObjectListField(ConsolePortTemplateType) + + console_server_port = ObjectField(ConsoleServerPortType) + console_server_ports = ObjectListField(ConsoleServerPortType) + + console_server_port_template = ObjectField(ConsoleServerPortTemplateType) + console_server_port_templates = ObjectListField(ConsoleServerPortTemplateType) + + device = ObjectField(DeviceType) + devices = ObjectListField(DeviceType) + + device_bay = ObjectField(DeviceBayType) + device_bays = ObjectListField(DeviceBayType) + + device_bay_template = ObjectField(DeviceBayTemplateType) + device_bay_templates = ObjectListField(DeviceBayTemplateType) + + device_role = ObjectField(DeviceRoleType) + device_roles = ObjectListField(DeviceRoleType) + + device_type = ObjectField(DeviceTypeType) + device_types = ObjectListField(DeviceTypeType) + + front_port = ObjectField(FrontPortType) + front_ports = ObjectListField(FrontPortType) + + front_port_template = ObjectField(FrontPortTemplateType) + front_port_templates = ObjectListField(FrontPortTemplateType) + + interface = ObjectField(InterfaceType) + interfaces = ObjectListField(InterfaceType) + + interface_template = ObjectField(InterfaceTemplateType) + interface_templates = ObjectListField(InterfaceTemplateType) + + inventory_item = ObjectField(InventoryItemType) + inventory_items = ObjectListField(InventoryItemType) + + location = ObjectField(LocationType) + locations = ObjectListField(LocationType) + + manufacturer = ObjectField(ManufacturerType) + manufacturers = ObjectListField(ManufacturerType) + + platform = ObjectField(PlatformType) + platforms = ObjectListField(PlatformType) + + power_feed = ObjectField(PowerFeedType) + power_feeds = ObjectListField(PowerFeedType) + + power_outlet = ObjectField(PowerOutletType) + power_outlets = ObjectListField(PowerOutletType) + + power_outlet_template = ObjectField(PowerOutletTemplateType) + power_outlet_templates = ObjectListField(PowerOutletTemplateType) + + power_panel = ObjectField(PowerPanelType) + power_panels = ObjectListField(PowerPanelType) + + power_port = ObjectField(PowerPortType) + power_ports = ObjectListField(PowerPortType) + + power_port_template = ObjectField(PowerPortTemplateType) + power_port_templates = ObjectListField(PowerPortTemplateType) + + rack = ObjectField(RackType) + racks = ObjectListField(RackType) + + rack_reservation = ObjectField(RackReservationType) + rack_reservations = ObjectListField(RackReservationType) + + rack_role = ObjectField(RackRoleType) + rack_roles = ObjectListField(RackRoleType) + + rear_port = ObjectField(RearPortType) + rear_ports = ObjectListField(RearPortType) + + rear_port_template = ObjectField(RearPortTemplateType) + rear_port_templates = ObjectListField(RearPortTemplateType) + + region = ObjectField(RegionType) + regions = ObjectListField(RegionType) + + site = ObjectField(SiteType) + sites = ObjectListField(SiteType) + + site_group = ObjectField(SiteGroupType) + site_groups = ObjectListField(SiteGroupType) + + virtual_chassis = ObjectField(VirtualChassisType) + # TODO: Rectify list field name + virtual_chassis_list = ObjectListField(VirtualChassisType) diff --git a/netbox/dcim/graphql/types.py b/netbox/dcim/graphql/types.py new file mode 100644 index 000000000..a11f2334a --- /dev/null +++ b/netbox/dcim/graphql/types.py @@ -0,0 +1,302 @@ +from dcim import filtersets, models +from netbox.graphql.types import BaseObjectType, ObjectType, TaggedObjectType + +__all__ = ( + 'CableType', + 'ConsolePortType', + 'ConsolePortTemplateType', + 'ConsoleServerPortType', + 'ConsoleServerPortTemplateType', + 'DeviceType', + 'DeviceBayType', + 'DeviceBayTemplateType', + 'DeviceRoleType', + 'DeviceTypeType', + 'FrontPortType', + 'FrontPortTemplateType', + 'InterfaceType', + 'InterfaceTemplateType', + 'InventoryItemType', + 'LocationType', + 'ManufacturerType', + 'PlatformType', + 'PowerFeedType', + 'PowerOutletType', + 'PowerOutletTemplateType', + 'PowerPanelType', + 'PowerPortType', + 'PowerPortTemplateType', + 'RackType', + 'RackReservationType', + 'RackRoleType', + 'RearPortType', + 'RearPortTemplateType', + 'RegionType', + 'SiteType', + 'SiteGroupType', + 'VirtualChassisType', +) + + +class CableType(TaggedObjectType): + + class Meta: + model = models.Cable + fields = '__all__' + filterset_class = filtersets.CableFilterSet + + +class ConsolePortType(TaggedObjectType): + + class Meta: + model = models.ConsolePort + fields = '__all__' + filterset_class = filtersets.ConsolePortFilterSet + + +class ConsolePortTemplateType(BaseObjectType): + + class Meta: + model = models.ConsolePortTemplate + fields = '__all__' + filterset_class = filtersets.ConsolePortTemplateFilterSet + + +class ConsoleServerPortType(TaggedObjectType): + + class Meta: + model = models.ConsoleServerPort + fields = '__all__' + filterset_class = filtersets.ConsoleServerPortFilterSet + + +class ConsoleServerPortTemplateType(BaseObjectType): + + class Meta: + model = models.ConsoleServerPortTemplate + fields = '__all__' + filterset_class = filtersets.ConsoleServerPortTemplateFilterSet + + +class DeviceType(TaggedObjectType): + + class Meta: + model = models.Device + fields = '__all__' + filterset_class = filtersets.DeviceFilterSet + + +class DeviceBayType(TaggedObjectType): + + class Meta: + model = models.DeviceBay + fields = '__all__' + filterset_class = filtersets.DeviceBayFilterSet + + +class DeviceBayTemplateType(BaseObjectType): + + class Meta: + model = models.DeviceBayTemplate + fields = '__all__' + filterset_class = filtersets.DeviceBayTemplateFilterSet + + +class DeviceRoleType(ObjectType): + + class Meta: + model = models.DeviceRole + fields = '__all__' + filterset_class = filtersets.DeviceRoleFilterSet + + +class DeviceTypeType(TaggedObjectType): + + class Meta: + model = models.DeviceType + fields = '__all__' + filterset_class = filtersets.DeviceTypeFilterSet + + +class FrontPortType(TaggedObjectType): + + class Meta: + model = models.FrontPort + fields = '__all__' + filterset_class = filtersets.FrontPortFilterSet + + +class FrontPortTemplateType(BaseObjectType): + + class Meta: + model = models.FrontPortTemplate + fields = '__all__' + filterset_class = filtersets.FrontPortTemplateFilterSet + + +class InterfaceType(TaggedObjectType): + + class Meta: + model = models.Interface + fields = '__all__' + filterset_class = filtersets.InterfaceFilterSet + + +class InterfaceTemplateType(BaseObjectType): + + class Meta: + model = models.InterfaceTemplate + fields = '__all__' + filterset_class = filtersets.InterfaceTemplateFilterSet + + +class InventoryItemType(ObjectType): + + class Meta: + model = models.InventoryItem + fields = '__all__' + filterset_class = filtersets.InventoryItemFilterSet + + +class LocationType(TaggedObjectType): + + class Meta: + model = models.Location + fields = '__all__' + filterset_class = filtersets.LocationFilterSet + + +class ManufacturerType(ObjectType): + + class Meta: + model = models.Manufacturer + fields = '__all__' + filterset_class = filtersets.ManufacturerFilterSet + + +class PlatformType(ObjectType): + + class Meta: + model = models.Platform + fields = '__all__' + filterset_class = filtersets.PlatformFilterSet + + +class PowerFeedType(TaggedObjectType): + + class Meta: + model = models.PowerFeed + fields = '__all__' + filterset_class = filtersets.PowerFeedFilterSet + + +class PowerOutletType(TaggedObjectType): + + class Meta: + model = models.PowerOutlet + fields = '__all__' + filterset_class = filtersets.PowerOutletFilterSet + + +class PowerOutletTemplateType(BaseObjectType): + + class Meta: + model = models.PowerOutletTemplate + fields = '__all__' + filterset_class = filtersets.PowerOutletTemplateFilterSet + + +class PowerPanelType(TaggedObjectType): + + class Meta: + model = models.PowerPanel + fields = '__all__' + filterset_class = filtersets.PowerPanelFilterSet + + +class PowerPortType(TaggedObjectType): + + class Meta: + model = models.PowerPort + fields = '__all__' + filterset_class = filtersets.PowerPortFilterSet + + +class PowerPortTemplateType(BaseObjectType): + + class Meta: + model = models.PowerPortTemplate + fields = '__all__' + filterset_class = filtersets.PowerPortTemplateFilterSet + + +class RackType(TaggedObjectType): + + class Meta: + model = models.Rack + fields = '__all__' + filterset_class = filtersets.RackFilterSet + + +class RackReservationType(TaggedObjectType): + + class Meta: + model = models.RackReservation + fields = '__all__' + filterset_class = filtersets.RackReservationFilterSet + + +class RackRoleType(ObjectType): + + class Meta: + model = models.RackRole + fields = '__all__' + filterset_class = filtersets.RackRoleFilterSet + + +class RearPortType(TaggedObjectType): + + class Meta: + model = models.RearPort + fields = '__all__' + filterset_class = filtersets.RearPortFilterSet + + +class RearPortTemplateType(BaseObjectType): + + class Meta: + model = models.RearPortTemplate + fields = '__all__' + filterset_class = filtersets.RearPortTemplateFilterSet + + +class RegionType(ObjectType): + + class Meta: + model = models.Region + fields = '__all__' + filterset_class = filtersets.RegionFilterSet + + +class SiteType(TaggedObjectType): + + class Meta: + model = models.Site + fields = '__all__' + filterset_class = filtersets.SiteFilterSet + + +class SiteGroupType(ObjectType): + + class Meta: + model = models.SiteGroup + fields = '__all__' + filterset_class = filtersets.SiteGroupFilterSet + + +class VirtualChassisType(TaggedObjectType): + + class Meta: + model = models.VirtualChassis + fields = '__all__' + filterset_class = filtersets.VirtualChassisFilterSet diff --git a/netbox/dcim/models/__init__.py b/netbox/dcim/models/__init__.py index ee19d553d..0375a9fb4 100644 --- a/netbox/dcim/models/__init__.py +++ b/netbox/dcim/models/__init__.py @@ -25,6 +25,7 @@ __all__ = ( 'Interface', 'InterfaceTemplate', 'InventoryItem', + 'Location', 'Manufacturer', 'Platform', 'PowerFeed', @@ -34,7 +35,6 @@ __all__ = ( 'PowerPort', 'PowerPortTemplate', 'Rack', - 'Location', 'RackReservation', 'RackRole', 'RearPort', diff --git a/netbox/dcim/tests/test_api.py b/netbox/dcim/tests/test_api.py index 2c64ad294..7e9687ed8 100644 --- a/netbox/dcim/tests/test_api.py +++ b/netbox/dcim/tests/test_api.py @@ -57,7 +57,7 @@ class Mixins: self.assertEqual(segment1[2]['name'], peer_obj.name) -class RegionTest(APIViewTestCases.APIViewTestCase): +class RegionTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = Region brief_fields = ['_depth', 'display', 'id', 'name', 'site_count', 'slug', 'url'] create_data = [ @@ -86,7 +86,7 @@ class RegionTest(APIViewTestCases.APIViewTestCase): Region.objects.create(name='Region 3', slug='region-3') -class SiteGroupTest(APIViewTestCases.APIViewTestCase): +class SiteGroupTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = SiteGroup brief_fields = ['_depth', 'display', 'id', 'name', 'site_count', 'slug', 'url'] create_data = [ @@ -115,7 +115,7 @@ class SiteGroupTest(APIViewTestCases.APIViewTestCase): SiteGroup.objects.create(name='Site Group 3', slug='site-group-3') -class SiteTest(APIViewTestCases.APIViewTestCase): +class SiteTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = Site brief_fields = ['display', 'id', 'name', 'slug', 'url'] bulk_update_data = { @@ -167,7 +167,7 @@ class SiteTest(APIViewTestCases.APIViewTestCase): ] -class LocationTest(APIViewTestCases.APIViewTestCase): +class LocationTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = Location brief_fields = ['_depth', 'display', 'id', 'name', 'rack_count', 'slug', 'url'] bulk_update_data = { @@ -214,7 +214,7 @@ class LocationTest(APIViewTestCases.APIViewTestCase): ] -class RackRoleTest(APIViewTestCases.APIViewTestCase): +class RackRoleTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = RackRole brief_fields = ['display', 'id', 'name', 'rack_count', 'slug', 'url'] create_data = [ @@ -249,7 +249,7 @@ class RackRoleTest(APIViewTestCases.APIViewTestCase): RackRole.objects.bulk_create(rack_roles) -class RackTest(APIViewTestCases.APIViewTestCase): +class RackTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = Rack brief_fields = ['device_count', 'display', 'id', 'name', 'url'] bulk_update_data = { @@ -337,7 +337,7 @@ class RackTest(APIViewTestCases.APIViewTestCase): self.assertEqual(response.get('Content-Type'), 'image/svg+xml') -class RackReservationTest(APIViewTestCases.APIViewTestCase): +class RackReservationTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = RackReservation brief_fields = ['display', 'id', 'units', 'url', 'user'] bulk_update_data = { @@ -384,7 +384,7 @@ class RackReservationTest(APIViewTestCases.APIViewTestCase): ] -class ManufacturerTest(APIViewTestCases.APIViewTestCase): +class ManufacturerTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = Manufacturer brief_fields = ['devicetype_count', 'display', 'id', 'name', 'slug', 'url'] create_data = [ @@ -416,7 +416,7 @@ class ManufacturerTest(APIViewTestCases.APIViewTestCase): Manufacturer.objects.bulk_create(manufacturers) -class DeviceTypeTest(APIViewTestCases.APIViewTestCase): +class DeviceTypeTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = DeviceType brief_fields = ['device_count', 'display', 'id', 'manufacturer', 'model', 'slug', 'url'] bulk_update_data = { @@ -458,7 +458,7 @@ class DeviceTypeTest(APIViewTestCases.APIViewTestCase): ] -class ConsolePortTemplateTest(APIViewTestCases.APIViewTestCase): +class ConsolePortTemplateTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = ConsolePortTemplate brief_fields = ['display', 'id', 'name', 'url'] bulk_update_data = { @@ -495,7 +495,7 @@ class ConsolePortTemplateTest(APIViewTestCases.APIViewTestCase): ] -class ConsoleServerPortTemplateTest(APIViewTestCases.APIViewTestCase): +class ConsoleServerPortTemplateTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = ConsoleServerPortTemplate brief_fields = ['display', 'id', 'name', 'url'] bulk_update_data = { @@ -532,7 +532,7 @@ class ConsoleServerPortTemplateTest(APIViewTestCases.APIViewTestCase): ] -class PowerPortTemplateTest(APIViewTestCases.APIViewTestCase): +class PowerPortTemplateTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = PowerPortTemplate brief_fields = ['display', 'id', 'name', 'url'] bulk_update_data = { @@ -569,7 +569,7 @@ class PowerPortTemplateTest(APIViewTestCases.APIViewTestCase): ] -class PowerOutletTemplateTest(APIViewTestCases.APIViewTestCase): +class PowerOutletTemplateTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = PowerOutletTemplate brief_fields = ['display', 'id', 'name', 'url'] bulk_update_data = { @@ -606,7 +606,7 @@ class PowerOutletTemplateTest(APIViewTestCases.APIViewTestCase): ] -class InterfaceTemplateTest(APIViewTestCases.APIViewTestCase): +class InterfaceTemplateTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = InterfaceTemplate brief_fields = ['display', 'id', 'name', 'url'] bulk_update_data = { @@ -646,7 +646,7 @@ class InterfaceTemplateTest(APIViewTestCases.APIViewTestCase): ] -class FrontPortTemplateTest(APIViewTestCases.APIViewTestCase): +class FrontPortTemplateTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = FrontPortTemplate brief_fields = ['display', 'id', 'name', 'url'] bulk_update_data = { @@ -717,7 +717,7 @@ class FrontPortTemplateTest(APIViewTestCases.APIViewTestCase): ] -class RearPortTemplateTest(APIViewTestCases.APIViewTestCase): +class RearPortTemplateTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = RearPortTemplate brief_fields = ['display', 'id', 'name', 'url'] bulk_update_data = { @@ -757,7 +757,7 @@ class RearPortTemplateTest(APIViewTestCases.APIViewTestCase): ] -class DeviceBayTemplateTest(APIViewTestCases.APIViewTestCase): +class DeviceBayTemplateTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = DeviceBayTemplate brief_fields = ['display', 'id', 'name', 'url'] bulk_update_data = { @@ -797,7 +797,7 @@ class DeviceBayTemplateTest(APIViewTestCases.APIViewTestCase): ] -class DeviceRoleTest(APIViewTestCases.APIViewTestCase): +class DeviceRoleTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = DeviceRole brief_fields = ['device_count', 'display', 'id', 'name', 'slug', 'url', 'virtualmachine_count'] create_data = [ @@ -832,7 +832,7 @@ class DeviceRoleTest(APIViewTestCases.APIViewTestCase): DeviceRole.objects.bulk_create(device_roles) -class PlatformTest(APIViewTestCases.APIViewTestCase): +class PlatformTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = Platform brief_fields = ['device_count', 'display', 'id', 'name', 'slug', 'url', 'virtualmachine_count'] create_data = [ @@ -864,7 +864,7 @@ class PlatformTest(APIViewTestCases.APIViewTestCase): Platform.objects.bulk_create(platforms) -class DeviceTest(APIViewTestCases.APIViewTestCase): +class DeviceTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = Device brief_fields = ['display', 'id', 'name', 'url'] bulk_update_data = { @@ -1219,7 +1219,7 @@ class InterfaceTest(Mixins.ComponentTraceMixin, APIViewTestCases.APIViewTestCase ] -class FrontPortTest(APIViewTestCases.APIViewTestCase): +class FrontPortTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = FrontPort brief_fields = ['_occupied', 'cable', 'device', 'display', 'id', 'name', 'url'] bulk_update_data = { @@ -1277,7 +1277,7 @@ class FrontPortTest(APIViewTestCases.APIViewTestCase): ] -class RearPortTest(APIViewTestCases.APIViewTestCase): +class RearPortTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = RearPort brief_fields = ['_occupied', 'cable', 'device', 'display', 'id', 'name', 'url'] bulk_update_data = { @@ -1319,7 +1319,7 @@ class RearPortTest(APIViewTestCases.APIViewTestCase): ] -class DeviceBayTest(APIViewTestCases.APIViewTestCase): +class DeviceBayTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = DeviceBay brief_fields = ['device', 'display', 'id', 'name', 'url'] bulk_update_data = { @@ -1382,7 +1382,7 @@ class DeviceBayTest(APIViewTestCases.APIViewTestCase): ] -class InventoryItemTest(APIViewTestCases.APIViewTestCase): +class InventoryItemTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = InventoryItem brief_fields = ['_depth', 'device', 'display', 'id', 'name', 'url'] bulk_update_data = { @@ -1420,7 +1420,7 @@ class InventoryItemTest(APIViewTestCases.APIViewTestCase): ] -class CableTest(APIViewTestCases.APIViewTestCase): +class CableTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = Cable brief_fields = ['display', 'id', 'label', 'url'] bulk_update_data = { @@ -1525,10 +1525,12 @@ class ConnectedDeviceTest(APITestCase): self.assertEqual(response.data['name'], self.device1.name) -class VirtualChassisTest(APIViewTestCases.APIViewTestCase): +class VirtualChassisTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = VirtualChassis brief_fields = ['id', 'master', 'member_count', 'name', 'url'] + graphql_base_name_plural = 'virtual_chassis_list' + @classmethod def setUpTestData(cls): site = Site.objects.create(name='Test Site', slug='test-site') @@ -1605,7 +1607,7 @@ class VirtualChassisTest(APIViewTestCases.APIViewTestCase): } -class PowerPanelTest(APIViewTestCases.APIViewTestCase): +class PowerPanelTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = PowerPanel brief_fields = ['display', 'id', 'name', 'powerfeed_count', 'url'] @@ -1654,7 +1656,7 @@ class PowerPanelTest(APIViewTestCases.APIViewTestCase): } -class PowerFeedTest(APIViewTestCases.APIViewTestCase): +class PowerFeedTest(APIViewTestCases.GraphQLTestCase, APIViewTestCases.APIViewTestCase): model = PowerFeed brief_fields = ['_occupied', 'cable', 'display', 'id', 'name', 'url'] bulk_update_data = { diff --git a/netbox/netbox/graphql/schema.py b/netbox/netbox/graphql/schema.py index da16ea58a..136477245 100644 --- a/netbox/netbox/graphql/schema.py +++ b/netbox/netbox/graphql/schema.py @@ -1,6 +1,7 @@ import graphene from circuits.graphql.schema import CircuitsQuery +from dcim.graphql.schema import DCIMQuery from extras.graphql.schema import ExtrasQuery from ipam.graphql.schema import IPAMQuery from tenancy.graphql.schema import TenancyQuery @@ -9,6 +10,7 @@ from virtualization.graphql.schema import VirtualizationQuery class Query( CircuitsQuery, + DCIMQuery, ExtrasQuery, IPAMQuery, TenancyQuery,