diff --git a/netbox/circuits/api/serializers.py b/netbox/circuits/api/serializers.py index 03d282eaa..b5220597c 100644 --- a/netbox/circuits/api/serializers.py +++ b/netbox/circuits/api/serializers.py @@ -48,11 +48,12 @@ class ProviderSerializer(NetBoxModelSerializer): class ProviderAccountSerializer(NetBoxModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='circuits-api:provideraccount-detail') + provider = NestedProviderSerializer() class Meta: model = ProviderAccount fields = [ - 'id', 'url', 'display', 'name', 'account', 'description', 'comments', 'tags', 'custom_fields', + 'id', 'url', 'display', 'provider', 'name', 'account', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', ] diff --git a/netbox/circuits/forms/model_forms.py b/netbox/circuits/forms/model_forms.py index 9cb9eb305..fb776d0cc 100644 --- a/netbox/circuits/forms/model_forms.py +++ b/netbox/circuits/forms/model_forms.py @@ -49,7 +49,7 @@ class ProviderAccountForm(NetBoxModelForm): class Meta: model = ProviderAccount fields = [ - 'name', 'account', 'provider', 'description', 'comments', 'tags', + 'provider', 'name', 'account', 'description', 'comments', 'tags', ] diff --git a/netbox/circuits/graphql/schema.py b/netbox/circuits/graphql/schema.py index f65874239..314e12866 100644 --- a/netbox/circuits/graphql/schema.py +++ b/netbox/circuits/graphql/schema.py @@ -17,5 +17,8 @@ class CircuitsQuery(graphene.ObjectType): provider = ObjectField(ProviderType) provider_list = ObjectListField(ProviderType) + provider_account = ObjectField(ProviderAccountType) + provider_account_list = ObjectListField(ProviderAccountType) + provider_network = ObjectField(ProviderNetworkType) provider_network_list = ObjectListField(ProviderNetworkType) diff --git a/netbox/circuits/graphql/types.py b/netbox/circuits/graphql/types.py index 5582de798..baa135e00 100644 --- a/netbox/circuits/graphql/types.py +++ b/netbox/circuits/graphql/types.py @@ -10,6 +10,7 @@ __all__ = ( 'CircuitType', 'CircuitTypeType', 'ProviderType', + 'ProviderAccountType', 'ProviderNetworkType', ) @@ -45,6 +46,14 @@ class ProviderType(NetBoxObjectType, ContactsMixin): filterset_class = filtersets.ProviderFilterSet +class ProviderAccountType(NetBoxObjectType): + + class Meta: + model = models.ProviderAccount + fields = '__all__' + filterset_class = filtersets.ProviderAccountFilterSet + + class ProviderNetworkType(NetBoxObjectType): class Meta: diff --git a/netbox/circuits/tests/test_api.py b/netbox/circuits/tests/test_api.py index c9d2cfc40..ce6d84fb7 100644 --- a/netbox/circuits/tests/test_api.py +++ b/netbox/circuits/tests/test_api.py @@ -197,6 +197,46 @@ class CircuitTerminationTest(APIViewTestCases.APIViewTestCase): } +class ProviderAccountTest(APIViewTestCases.APIViewTestCase): + model = ProviderAccount + brief_fields = ['display', 'id', 'name', 'url'] + + @classmethod + def setUpTestData(cls): + providers = ( + Provider(name='Provider 1', slug='provider-1'), + Provider(name='Provider 2', slug='provider-2'), + ) + Provider.objects.bulk_create(providers) + + provider_accounts = ( + ProviderNetwork(name='Provider Account 1', provider=providers[0]), + ProviderNetwork(name='Provider Account 2', provider=providers[0]), + ProviderNetwork(name='Provider Account 3', provider=providers[0]), + ) + ProviderNetwork.objects.bulk_create(provider_accounts) + + cls.create_data = [ + { + 'name': 'Provider Account 4', + 'provider': providers[0].pk, + }, + { + 'name': 'Provider Account 5', + 'provider': providers[0].pk, + }, + { + 'name': 'Provider Account 6', + 'provider': providers[0].pk, + }, + ] + + cls.bulk_update_data = { + 'provider': providers[1].pk, + 'description': 'New description', + } + + class ProviderNetworkTest(APIViewTestCases.APIViewTestCase): model = ProviderNetwork brief_fields = ['display', 'id', 'name', 'url'] diff --git a/netbox/circuits/tests/test_filtersets.py b/netbox/circuits/tests/test_filtersets.py index 897c87c05..9a0ea5ffb 100644 --- a/netbox/circuits/tests/test_filtersets.py +++ b/netbox/circuits/tests/test_filtersets.py @@ -445,3 +445,40 @@ class ProviderNetworkTestCase(TestCase, ChangeLoggedFilterSetTests): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'provider': [providers[0].slug, providers[1].slug]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + +class ProviderAccountTestCase(TestCase, ChangeLoggedFilterSetTests): + queryset = ProviderAccount.objects.all() + filterset = ProviderAccountFilterSet + + @classmethod + def setUpTestData(cls): + + providers = ( + Provider(name='Provider 1', slug='provider-1'), + Provider(name='Provider 2', slug='provider-2'), + Provider(name='Provider 3', slug='provider-3'), + ) + Provider.objects.bulk_create(providers) + + provider_accounts = ( + ProviderNetwork(name='Provider Account 1', provider=providers[0], description='foobar1'), + ProviderNetwork(name='Provider Account 2', provider=providers[1], description='foobar2'), + ProviderNetwork(name='Provider Account 3', provider=providers[2]), + ) + ProviderNetwork.objects.bulk_create(provider_accounts) + + def test_name(self): + params = {'name': ['Provider Account 1', 'Provider Account 2']} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + def test_description(self): + params = {'description': ['foobar1', 'foobar2']} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + def test_provider(self): + providers = Provider.objects.all()[:2] + params = {'provider_id': [providers[0].pk, providers[1].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'provider': [providers[0].slug, providers[1].slug]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) diff --git a/netbox/circuits/tests/test_views.py b/netbox/circuits/tests/test_views.py index 231d6a43c..803b948b7 100644 --- a/netbox/circuits/tests/test_views.py +++ b/netbox/circuits/tests/test_views.py @@ -179,6 +179,57 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase): } +class ProviderAccountTestCase(ViewTestCases.PrimaryObjectViewTestCase): + model = ProviderAccount + + @classmethod + def setUpTestData(cls): + + providers = ( + Provider(name='Provider 1', slug='provider-1'), + Provider(name='Provider 2', slug='provider-2'), + ) + Provider.objects.bulk_create(providers) + + provider_accounts = ( + ProviderNetwork(name='Provider Account 1', provider=providers[0]), + ProviderNetwork(name='Provider Account 2', provider=providers[0]), + ProviderNetwork(name='Provider Account 3', provider=providers[0]), + ) + + ProviderNetwork.objects.bulk_create(provider_accounts) + + tags = create_tags('Alpha', 'Bravo', 'Charlie') + + cls.form_data = { + 'name': 'Provider Account X', + 'provider': providers[1].pk, + 'description': 'A new provider network', + 'comments': 'Longer description goes here', + 'tags': [t.pk for t in tags], + } + + cls.csv_data = ( + "name,provider,description", + "Provider Account 4,Provider 1,Foo", + "Provider Account 5,Provider 1,Bar", + "Provider Account 6,Provider 1,Baz", + ) + + cls.csv_update_data = ( + "id,name,description", + f"{provider_accounts[0].pk},Provider Network 7,New description7", + f"{provider_accounts[1].pk},Provider Network 8,New description8", + f"{provider_accounts[2].pk},Provider Network 9,New description9", + ) + + cls.bulk_edit_data = { + 'provider': providers[1].pk, + 'description': 'New description', + 'comments': 'New comments', + } + + class ProviderNetworkTestCase(ViewTestCases.PrimaryObjectViewTestCase): model = ProviderNetwork