diff --git a/docs/features/circuits.md b/docs/features/circuits.md index f5bbe95f4..c8eda141a 100644 --- a/docs/features/circuits.md +++ b/docs/features/circuits.md @@ -6,7 +6,7 @@ NetBox is ideal for managing your network's transit and peering providers and ci flowchart TD ASN --> Provider Provider --> ProviderAccount --> Circuit - Provider --> ProviderNetwork + Provider --> ProviderNetwork & Circuit CircuitType --> Circuit click ASN "../../models/circuits/asn/" diff --git a/netbox/circuits/api/serializers.py b/netbox/circuits/api/serializers.py index fefe6c19d..1ec8913c1 100644 --- a/netbox/circuits/api/serializers.py +++ b/netbox/circuits/api/serializers.py @@ -105,6 +105,7 @@ class CircuitCircuitTerminationSerializer(WritableNestedSerializer): class CircuitSerializer(NetBoxModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail') + provider = NestedProviderSerializer() provider_account = NestedProviderAccountSerializer() status = ChoiceField(choices=CircuitStatusChoices, required=False) type = NestedCircuitTypeSerializer() @@ -115,9 +116,9 @@ class CircuitSerializer(NetBoxModelSerializer): class Meta: model = Circuit fields = [ - 'id', 'url', 'display', 'cid', 'provider_account', 'type', 'status', 'tenant', 'install_date', 'termination_date', - 'commit_rate', 'description', 'termination_a', 'termination_z', 'comments', 'tags', 'custom_fields', - 'created', 'last_updated', + 'id', 'url', 'display', 'cid', 'provider', 'provider_account', 'type', 'status', 'tenant', 'install_date', + 'termination_date', 'commit_rate', 'description', 'termination_a', 'termination_z', 'comments', 'tags', + 'custom_fields', 'created', 'last_updated', ] diff --git a/netbox/circuits/filtersets.py b/netbox/circuits/filtersets.py index 6668cc647..eea1438f3 100644 --- a/netbox/circuits/filtersets.py +++ b/netbox/circuits/filtersets.py @@ -142,12 +142,11 @@ class CircuitTypeFilterSet(OrganizationalModelFilterSet): class CircuitFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet): provider_id = django_filters.ModelMultipleChoiceFilter( - field_name='provider_account__provider', queryset=Provider.objects.all(), label=_('Provider (ID)'), ) provider = django_filters.ModelMultipleChoiceFilter( - field_name='provider_account__provider__slug', + field_name='provider__slug', queryset=Provider.objects.all(), to_field_name='slug', label=_('Provider (slug)'), diff --git a/netbox/circuits/forms/bulk_edit.py b/netbox/circuits/forms/bulk_edit.py index c199bf989..03e042e89 100644 --- a/netbox/circuits/forms/bulk_edit.py +++ b/netbox/circuits/forms/bulk_edit.py @@ -153,7 +153,7 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm): model = Circuit fieldsets = ( ('Circuit', ('provider', 'type', 'status', 'description')), - ('Service Parameters', ('install_date', 'termination_date', 'commit_rate')), + ('Service Parameters', ('provider_account', 'install_date', 'termination_date', 'commit_rate')), ('Tenancy', ('tenant',)), ) nullable_fields = ( diff --git a/netbox/circuits/forms/bulk_import.py b/netbox/circuits/forms/bulk_import.py index 7b7de2277..60c9be2e6 100644 --- a/netbox/circuits/forms/bulk_import.py +++ b/netbox/circuits/forms/bulk_import.py @@ -65,6 +65,11 @@ class CircuitTypeImportForm(NetBoxModelImportForm): class CircuitImportForm(NetBoxModelImportForm): + provider = CSVModelChoiceField( + queryset=Provider.objects.all(), + to_field_name='name', + help_text=_('Assigned provider') + ) provider_account = CSVModelChoiceField( queryset=ProviderAccount.objects.all(), to_field_name='name', @@ -89,8 +94,8 @@ class CircuitImportForm(NetBoxModelImportForm): class Meta: model = Circuit fields = [ - 'cid', 'provider_account', 'type', 'status', 'tenant', 'install_date', 'termination_date', 'commit_rate', - 'description', 'comments', 'tags' + 'cid', 'provider', 'provider_account', 'type', 'status', 'tenant', 'install_date', 'termination_date', + 'commit_rate', 'description', 'comments', 'tags' ] diff --git a/netbox/circuits/forms/model_forms.py b/netbox/circuits/forms/model_forms.py index 2c26f550b..d31ac98d6 100644 --- a/netbox/circuits/forms/model_forms.py +++ b/netbox/circuits/forms/model_forms.py @@ -87,15 +87,20 @@ class CircuitTypeForm(NetBoxModelForm): class CircuitForm(TenancyForm, NetBoxModelForm): + provider = DynamicModelChoiceField( + queryset=Provider.objects.all(), + selector=True + ) provider_account = DynamicModelChoiceField( queryset=ProviderAccount.objects.all(), initial_params={ 'circuits': '$circuit' }, query_params={ - 'provider': '$provider', + 'provider_id': '$provider', }, - selector=True + selector=True, + required=False ) type = DynamicModelChoiceField( queryset=CircuitType.objects.all() @@ -103,7 +108,7 @@ class CircuitForm(TenancyForm, NetBoxModelForm): comments = CommentField() fieldsets = ( - ('Circuit', ('provider_account', 'cid', 'type', 'status', 'description', 'tags')), + ('Circuit', ('provider', 'provider_account', 'cid', 'type', 'status', 'description', 'tags')), ('Service Parameters', ('install_date', 'termination_date', 'commit_rate')), ('Tenancy', ('tenant_group', 'tenant')), ) @@ -111,7 +116,7 @@ class CircuitForm(TenancyForm, NetBoxModelForm): class Meta: model = Circuit fields = [ - 'cid', 'type', 'provider_account', 'status', 'install_date', 'termination_date', 'commit_rate', + 'cid', 'type', 'provider', 'provider_account', 'status', 'install_date', 'termination_date', 'commit_rate', 'description', 'tenant_group', 'tenant', 'comments', 'tags', ] widgets = { diff --git a/netbox/circuits/migrations/0042_provideraccount.py b/netbox/circuits/migrations/0042_provideraccount.py index 00e26510b..fa67474ec 100644 --- a/netbox/circuits/migrations/0042_provideraccount.py +++ b/netbox/circuits/migrations/0042_provideraccount.py @@ -14,9 +14,9 @@ def create_provideraccounts_from_providers(apps, schema_editor): ProviderAccount = apps.get_model('circuits', 'ProviderAccount') for provider in Provider.objects.all(): - if provider.account is not None: + if provider.account: provideraccount = ProviderAccount.objects.create( - name=f'{provider.name} {provider.account}' if provider.account else f'{provider.name}', + name=f'{provider.name} {provider.account}', account=provider.account, provider=provider, ) @@ -34,22 +34,6 @@ def revert_provideraccounts_from_providers(apps, schema_editor): provideraccount.provider.save() -def migrate_circuits_to_provideraccount(apps, schema_editor): - Circuit = apps.get_model('circuits', 'Circuit') - circuits = Circuit.objects.all() - for circuit in circuits: - circuit.provider_account = circuit.provider.accounts.order_by('pk').first() - circuit.save() - - -def migrate_circuits_from_provideraccount(apps, schema_editor): - Circuit = apps.get_model('circuits', 'Circuit') - circuits = Circuit.objects.all().order_by('pk') - for circuit in circuits: - circuit.provider = circuit.provider_account.provider - circuit.save() - - class Migration(migrations.Migration): dependencies = [ @@ -97,33 +81,12 @@ class Migration(migrations.Migration): field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.provideraccount', null=True, blank=True), preserve_default=False, ), - migrations.AlterField( - model_name='circuit', - name='provider', - field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, related_name='circuits', to='circuits.provider', null=True, blank=True), - ), - migrations.RunPython( - migrate_circuits_to_provideraccount, migrate_circuits_from_provideraccount - ), - migrations.AlterField( - model_name='circuit', - name='provider_account', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.provideraccount'), - ), - migrations.RemoveConstraint( - model_name='circuit', - name='circuits_circuit_unique_provider_cid', - ), migrations.AlterModelOptions( name='circuit', - options={'ordering': ['provider_account', 'cid']}, + options={'ordering': ['provider', 'provider_account', 'cid']}, ), migrations.AddConstraint( model_name='circuit', - constraint=models.UniqueConstraint(fields=('provider_account', 'cid'), name='circuits_circuit_unique_provider_cid'), - ), - migrations.RemoveField( - model_name='circuit', - name='provider', + constraint=models.UniqueConstraint(fields=('provider_account', 'cid'), name='circuits_circuit_unique_provideraccount_cid'), ), ] diff --git a/netbox/circuits/models/circuits.py b/netbox/circuits/models/circuits.py index 56385b186..5e5a16ab9 100644 --- a/netbox/circuits/models/circuits.py +++ b/netbox/circuits/models/circuits.py @@ -37,10 +37,17 @@ class Circuit(PrimaryModel): verbose_name='Circuit ID', help_text=_("Unique circuit ID") ) + provider = models.ForeignKey( + to='circuits.Provider', + on_delete=models.PROTECT, + related_name='circuits' + ) provider_account = models.ForeignKey( to='circuits.ProviderAccount', on_delete=models.PROTECT, - related_name='circuits' + related_name='circuits', + blank=True, + null=True ) type = models.ForeignKey( to='CircuitType', @@ -103,20 +110,26 @@ class Circuit(PrimaryModel): ) clone_fields = ( - 'provider_account', 'type', 'status', 'tenant', 'install_date', 'termination_date', 'commit_rate', 'description', + 'provider', 'provider_account', 'type', 'status', 'tenant', 'install_date', 'termination_date', 'commit_rate', + 'description', ) prerequisite_models = ( 'circuits.CircuitType', + 'circuits.Provider', 'circuits.ProviderAccount', ) class Meta: - ordering = ['provider_account', 'cid'] + ordering = ['provider', 'provider_account', 'cid'] constraints = ( models.UniqueConstraint( - fields=('provider_account', 'cid'), + fields=('provider', 'cid'), name='%(app_label)s_%(class)s_unique_provider_cid' ), + models.UniqueConstraint( + fields=('provider_account', 'cid'), + name='%(app_label)s_%(class)s_unique_provideraccount_cid' + ), ) def __str__(self): @@ -128,6 +141,11 @@ class Circuit(PrimaryModel): def get_status_color(self): return CircuitStatusChoices.colors.get(self.status) + def clean(self): + super().clean() + if self.provider_account and self.provider != self.provider_account.provider: + raise ValidationError("Provider must match ProviderAccount's provider") + class CircuitTermination( CustomFieldsMixin, diff --git a/netbox/circuits/tables/circuits.py b/netbox/circuits/tables/circuits.py index 94dc73b4a..85ee6b8a9 100644 --- a/netbox/circuits/tables/circuits.py +++ b/netbox/circuits/tables/circuits.py @@ -50,7 +50,6 @@ class CircuitTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable): verbose_name='Circuit ID' ) provider = tables.Column( - accessor=Accessor('provider_account__provider'), linkify=True ) provider_account = tables.Column( @@ -74,9 +73,9 @@ class CircuitTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable): class Meta(NetBoxTable.Meta): model = Circuit fields = ( - 'pk', 'id', 'cid', 'provider', 'provider_account', 'type', 'status', 'tenant', 'tenant_group', 'termination_a', 'termination_z', - 'install_date', 'termination_date', 'commit_rate', 'description', 'comments', 'contacts', 'tags', 'created', - 'last_updated', + 'pk', 'id', 'cid', 'provider', 'provider_account', 'type', 'status', 'tenant', 'tenant_group', + 'termination_a', 'termination_z', 'install_date', 'termination_date', 'commit_rate', 'description', + 'comments', 'contacts', 'tags', 'created', 'last_updated', ) default_columns = ( 'pk', 'cid', 'provider', 'type', 'status', 'tenant', 'termination_a', 'termination_z', 'description', diff --git a/netbox/circuits/tests/test_api.py b/netbox/circuits/tests/test_api.py index 722055111..75907c292 100644 --- a/netbox/circuits/tests/test_api.py +++ b/netbox/circuits/tests/test_api.py @@ -119,25 +119,28 @@ class CircuitTest(APIViewTestCases.APIViewTestCase): CircuitType.objects.bulk_create(circuit_types) circuits = ( - Circuit(cid='Circuit 1', provider_account=provider_accounts[0], type=circuit_types[0]), - Circuit(cid='Circuit 2', provider_account=provider_accounts[0], type=circuit_types[0]), - Circuit(cid='Circuit 3', provider_account=provider_accounts[0], type=circuit_types[0]), + Circuit(cid='Circuit 1', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0]), + Circuit(cid='Circuit 2', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0]), + Circuit(cid='Circuit 3', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0]), ) Circuit.objects.bulk_create(circuits) cls.create_data = [ { 'cid': 'Circuit 4', + 'provider': providers[1].pk, 'provider_account': provider_accounts[1].pk, 'type': circuit_types[1].pk, }, { 'cid': 'Circuit 5', + 'provider': providers[1].pk, 'provider_account': provider_accounts[1].pk, 'type': circuit_types[1].pk, }, { 'cid': 'Circuit 6', + 'provider': providers[1].pk, 'provider_account': provider_accounts[1].pk, 'type': circuit_types[1].pk, }, @@ -174,9 +177,9 @@ class CircuitTerminationTest(APIViewTestCases.APIViewTestCase): ProviderNetwork.objects.bulk_create(provider_networks) circuits = ( - Circuit(cid='Circuit 1', provider_account=provider_account, type=circuit_type), - Circuit(cid='Circuit 2', provider_account=provider_account, type=circuit_type), - Circuit(cid='Circuit 3', provider_account=provider_account, type=circuit_type), + Circuit(cid='Circuit 1', provider=provider, provider_account=provider_account, type=circuit_type), + Circuit(cid='Circuit 2', provider=provider, provider_account=provider_account, type=circuit_type), + Circuit(cid='Circuit 3', provider=provider, provider_account=provider_account, type=circuit_type), ) Circuit.objects.bulk_create(circuits) diff --git a/netbox/circuits/tests/test_filtersets.py b/netbox/circuits/tests/test_filtersets.py index 0cb898a98..88a37472c 100644 --- a/netbox/circuits/tests/test_filtersets.py +++ b/netbox/circuits/tests/test_filtersets.py @@ -73,8 +73,8 @@ class ProviderTestCase(TestCase, ChangeLoggedFilterSetTests): CircuitType.objects.bulk_create(circuit_types) circuits = ( - Circuit(provider_account=provider_accounts[0], type=circuit_types[0], cid='Test Circuit 1'), - Circuit(provider_account=provider_accounts[1], type=circuit_types[1], cid='Test Circuit 1'), + Circuit(provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0], cid='Test Circuit 1'), + Circuit(provider=providers[1], provider_account=provider_accounts[1], type=circuit_types[1], cid='Test Circuit 1'), ) Circuit.objects.bulk_create(circuits) @@ -215,12 +215,12 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests): ProviderNetwork.objects.bulk_create(provider_networks) circuits = ( - Circuit(provider_account=provider_accounts[0], tenant=tenants[0], type=circuit_types[0], cid='Test Circuit 1', install_date='2020-01-01', termination_date='2021-01-01', commit_rate=1000, status=CircuitStatusChoices.STATUS_ACTIVE, description='foobar1'), - Circuit(provider_account=provider_accounts[0], tenant=tenants[0], type=circuit_types[0], cid='Test Circuit 2', install_date='2020-01-02', termination_date='2021-01-02', commit_rate=2000, status=CircuitStatusChoices.STATUS_ACTIVE, description='foobar2'), - Circuit(provider_account=provider_accounts[0], tenant=tenants[1], type=circuit_types[0], cid='Test Circuit 3', install_date='2020-01-03', termination_date='2021-01-03', commit_rate=3000, status=CircuitStatusChoices.STATUS_PLANNED), - Circuit(provider_account=provider_accounts[1], tenant=tenants[1], type=circuit_types[1], cid='Test Circuit 4', install_date='2020-01-04', termination_date='2021-01-04', commit_rate=4000, status=CircuitStatusChoices.STATUS_PLANNED), - Circuit(provider_account=provider_accounts[1], tenant=tenants[2], type=circuit_types[1], cid='Test Circuit 5', install_date='2020-01-05', termination_date='2021-01-05', commit_rate=5000, status=CircuitStatusChoices.STATUS_OFFLINE), - Circuit(provider_account=provider_accounts[1], tenant=tenants[2], type=circuit_types[1], cid='Test Circuit 6', install_date='2020-01-06', termination_date='2021-01-06', commit_rate=6000, status=CircuitStatusChoices.STATUS_OFFLINE), + Circuit(provider=providers[0], provider_account=provider_accounts[0], tenant=tenants[0], type=circuit_types[0], cid='Test Circuit 1', install_date='2020-01-01', termination_date='2021-01-01', commit_rate=1000, status=CircuitStatusChoices.STATUS_ACTIVE, description='foobar1'), + Circuit(provider=providers[0], provider_account=provider_accounts[0], tenant=tenants[0], type=circuit_types[0], cid='Test Circuit 2', install_date='2020-01-02', termination_date='2021-01-02', commit_rate=2000, status=CircuitStatusChoices.STATUS_ACTIVE, description='foobar2'), + Circuit(provider=providers[0], provider_account=provider_accounts[0], tenant=tenants[1], type=circuit_types[0], cid='Test Circuit 3', install_date='2020-01-03', termination_date='2021-01-03', commit_rate=3000, status=CircuitStatusChoices.STATUS_PLANNED), + Circuit(provider=providers[1], provider_account=provider_accounts[1], tenant=tenants[1], type=circuit_types[1], cid='Test Circuit 4', install_date='2020-01-04', termination_date='2021-01-04', commit_rate=4000, status=CircuitStatusChoices.STATUS_PLANNED), + Circuit(provider=providers[1], provider_account=provider_accounts[1], tenant=tenants[2], type=circuit_types[1], cid='Test Circuit 5', install_date='2020-01-05', termination_date='2021-01-05', commit_rate=5000, status=CircuitStatusChoices.STATUS_OFFLINE), + Circuit(provider=providers[1], provider_account=provider_accounts[1], tenant=tenants[2], type=circuit_types[1], cid='Test Circuit 6', install_date='2020-01-06', termination_date='2021-01-06', commit_rate=6000, status=CircuitStatusChoices.STATUS_OFFLINE), ) Circuit.objects.bulk_create(circuits) @@ -355,13 +355,13 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests): ProviderNetwork.objects.bulk_create(provider_networks) circuits = ( - Circuit(provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 1'), - Circuit(provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 2'), - Circuit(provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 3'), - Circuit(provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 4'), - Circuit(provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 5'), - Circuit(provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 6'), - Circuit(provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 7'), + Circuit(provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 1'), + Circuit(provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 2'), + Circuit(provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 3'), + Circuit(provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 4'), + Circuit(provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 5'), + Circuit(provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 6'), + Circuit(provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0], cid='Circuit 7'), ) Circuit.objects.bulk_create(circuits) diff --git a/netbox/circuits/tests/test_views.py b/netbox/circuits/tests/test_views.py index 12af6f311..deb2a7b6b 100644 --- a/netbox/circuits/tests/test_views.py +++ b/netbox/circuits/tests/test_views.py @@ -135,9 +135,9 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase): CircuitType.objects.bulk_create(circuittypes) circuits = ( - Circuit(cid='Circuit 1', provider_account=provider_accounts[0], type=circuittypes[0]), - Circuit(cid='Circuit 2', provider_account=provider_accounts[0], type=circuittypes[0]), - Circuit(cid='Circuit 3', provider_account=provider_accounts[0], type=circuittypes[0]), + Circuit(cid='Circuit 1', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0]), + Circuit(cid='Circuit 2', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0]), + Circuit(cid='Circuit 3', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0]), ) Circuit.objects.bulk_create(circuits) @@ -146,6 +146,7 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase): cls.form_data = { 'cid': 'Circuit X', + 'provider': providers[1].pk, 'provider_account': provider_accounts[1].pk, 'type': circuittypes[1].pk, 'status': CircuitStatusChoices.STATUS_DECOMMISSIONED, @@ -159,10 +160,10 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase): } cls.csv_data = ( - "cid,provider_account,type,status", - "Circuit 4,Provider Account 1,Circuit Type 1,active", - "Circuit 5,Provider Account 1,Circuit Type 1,active", - "Circuit 6,Provider Account 1,Circuit Type 1,active", + "cid,provider,provider_account,type,status", + "Circuit 4,Provider 1,Provider Account 1,Circuit Type 1,active", + "Circuit 5,Provider 1,Provider Account 1,Circuit Type 1,active", + "Circuit 6,Provider 1,Provider Account 1,Circuit Type 1,active", ) cls.csv_update_data = ( @@ -173,6 +174,7 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase): ) cls.bulk_edit_data = { + 'provider': providers[1].pk, 'provider_account': provider_accounts[1].pk, 'type': circuittypes[1].pk, 'status': CircuitStatusChoices.STATUS_DECOMMISSIONED, @@ -306,9 +308,9 @@ class CircuitTerminationTestCase( account = ProviderAccount.objects.create(name='Provider Account 1', provider=provider, account='1234') circuits = ( - Circuit(cid='Circuit 1', provider_account=account, type=circuittype), - Circuit(cid='Circuit 2', provider_account=account, type=circuittype), - Circuit(cid='Circuit 3', provider_account=account, type=circuittype), + Circuit(cid='Circuit 1', provider=provider, provider_account=account, type=circuittype), + Circuit(cid='Circuit 2', provider=provider, provider_account=account, type=circuittype), + Circuit(cid='Circuit 3', provider=provider, provider_account=account, type=circuittype), ) Circuit.objects.bulk_create(circuits) diff --git a/netbox/circuits/views.py b/netbox/circuits/views.py index 6fe79d716..fc9540d16 100644 --- a/netbox/circuits/views.py +++ b/netbox/circuits/views.py @@ -18,7 +18,7 @@ from .models import * class ProviderListView(generic.ObjectListView): queryset = Provider.objects.annotate( - count_circuits=count_related(Circuit, 'provider_account__provider') + count_circuits=count_related(Circuit, 'provider') ) filterset = filtersets.ProviderFilterSet filterset_form = forms.ProviderFilterForm @@ -32,7 +32,7 @@ class ProviderView(generic.ObjectView): def get_extra_context(self, request, instance): related_models = ( (ProviderAccount.objects.restrict(request.user, 'view').filter(provider=instance), 'provider_id'), - (Circuit.objects.restrict(request.user, 'view').filter(provider_account__provider=instance), 'provider_id'), + (Circuit.objects.restrict(request.user, 'view').filter(provider=instance), 'provider_id'), ) return { @@ -58,7 +58,7 @@ class ProviderBulkImportView(generic.BulkImportView): class ProviderBulkEditView(generic.BulkEditView): queryset = Provider.objects.annotate( - count_circuits=count_related(Circuit, 'provider_account__provider') + count_circuits=count_related(Circuit, 'provider') ) filterset = filtersets.ProviderFilterSet table = tables.ProviderTable @@ -67,7 +67,7 @@ class ProviderBulkEditView(generic.BulkEditView): class ProviderBulkDeleteView(generic.BulkDeleteView): queryset = Provider.objects.annotate( - count_circuits=count_related(Circuit, 'provider_account__provider') + count_circuits=count_related(Circuit, 'provider') ) filterset = filtersets.ProviderFilterSet table = tables.ProviderTable diff --git a/netbox/dcim/tests/test_cablepaths.py b/netbox/dcim/tests/test_cablepaths.py index c7b435a81..c8e99e092 100644 --- a/netbox/dcim/tests/test_cablepaths.py +++ b/netbox/dcim/tests/test_cablepaths.py @@ -32,7 +32,7 @@ class CablePathTestCase(TestCase): provider = Provider.objects.create(name='Provider', slug='provider') provider_account = ProviderAccount.objects.create(name='Account', account='AAAA1111', provider=provider) circuit_type = CircuitType.objects.create(name='Circuit Type', slug='circuit-type') - cls.circuit = Circuit.objects.create(provider_account=provider_account, type=circuit_type, cid='Circuit 1') + cls.circuit = Circuit.objects.create(provider=provider, provider_account=provider_account, type=circuit_type, cid='Circuit 1') def assertPathExists(self, nodes, **kwargs): """ diff --git a/netbox/dcim/tests/test_models.py b/netbox/dcim/tests/test_models.py index d911b1404..7718ce285 100644 --- a/netbox/dcim/tests/test_models.py +++ b/netbox/dcim/tests/test_models.py @@ -507,8 +507,8 @@ class CableTestCase(TestCase): provider_account = ProviderAccount.objects.create(name='Provider Account 1', account='A1', provider=provider) provider_network = ProviderNetwork.objects.create(name='Provider Network 1', provider=provider) circuittype = CircuitType.objects.create(name='Circuit Type 1', slug='circuit-type-1') - circuit1 = Circuit.objects.create(provider_account=provider_account, type=circuittype, cid='1') - circuit2 = Circuit.objects.create(provider_account=provider_account, type=circuittype, cid='2') + circuit1 = Circuit.objects.create(provider=provider, provider_account=provider_account, type=circuittype, cid='1') + circuit2 = Circuit.objects.create(provider=provider, provider_account=provider_account, type=circuittype, cid='2') circuittermination1 = CircuitTermination.objects.create(circuit=circuit1, site=site, term_side='A') circuittermination2 = CircuitTermination.objects.create(circuit=circuit1, site=site, term_side='Z') circuittermination3 = CircuitTermination.objects.create(circuit=circuit2, provider_network=provider_network, term_side='A') diff --git a/netbox/netbox/tests/test_staging.py b/netbox/netbox/tests/test_staging.py index f6b6d62ae..4a0ea3f9b 100644 --- a/netbox/netbox/tests/test_staging.py +++ b/netbox/netbox/tests/test_staging.py @@ -38,15 +38,15 @@ class StagingTestCase(TransactionTestCase): circuit_type = CircuitType.objects.create(name='Circuit Type 1', slug='circuit-type-1') Circuit.objects.bulk_create(( - Circuit(provider_account=provider_accounts[0], cid='Circuit A1', type=circuit_type), - Circuit(provider_account=provider_accounts[0], cid='Circuit A2', type=circuit_type), - Circuit(provider_account=provider_accounts[0], cid='Circuit A3', type=circuit_type), - Circuit(provider_account=provider_accounts[1], cid='Circuit B1', type=circuit_type), - Circuit(provider_account=provider_accounts[1], cid='Circuit B2', type=circuit_type), - Circuit(provider_account=provider_accounts[1], cid='Circuit B3', type=circuit_type), - Circuit(provider_account=provider_accounts[2], cid='Circuit C1', type=circuit_type), - Circuit(provider_account=provider_accounts[2], cid='Circuit C2', type=circuit_type), - Circuit(provider_account=provider_accounts[2], cid='Circuit C3', type=circuit_type), + Circuit(provider=providers[0], provider_account=provider_accounts[0], cid='Circuit A1', type=circuit_type), + Circuit(provider=providers[0], provider_account=provider_accounts[0], cid='Circuit A2', type=circuit_type), + Circuit(provider=providers[0], provider_account=provider_accounts[0], cid='Circuit A3', type=circuit_type), + Circuit(provider=providers[1], provider_account=provider_accounts[1], cid='Circuit B1', type=circuit_type), + Circuit(provider=providers[1], provider_account=provider_accounts[1], cid='Circuit B2', type=circuit_type), + Circuit(provider=providers[1], provider_account=provider_accounts[1], cid='Circuit B3', type=circuit_type), + Circuit(provider=providers[2], provider_account=provider_accounts[2], cid='Circuit C1', type=circuit_type), + Circuit(provider=providers[2], provider_account=provider_accounts[2], cid='Circuit C2', type=circuit_type), + Circuit(provider=providers[2], provider_account=provider_accounts[2], cid='Circuit C3', type=circuit_type), )) def test_object_creation(self): @@ -58,7 +58,7 @@ class StagingTestCase(TransactionTestCase): provider = Provider.objects.create(name='Provider D', slug='provider-d') provider.asns.set(asns) provider_account = ProviderAccount.objects.create(name='Account D', provider=provider, account='DDDD') - circuit = Circuit.objects.create(provider_account=provider_account, cid='Circuit D1', type=CircuitType.objects.first()) + circuit = Circuit.objects.create(provider=provider, provider_account=provider_account, cid='Circuit D1', type=CircuitType.objects.first()) circuit.tags.set(tags) # Sanity-checking diff --git a/netbox/templates/circuits/circuit.html b/netbox/templates/circuits/circuit.html index b7b3f81c5..e9809efc5 100644 --- a/netbox/templates/circuits/circuit.html +++ b/netbox/templates/circuits/circuit.html @@ -16,7 +16,7 @@ - + diff --git a/netbox/templates/circuits/circuittermination_edit.html b/netbox/templates/circuits/circuittermination_edit.html index 2fac2a35b..e50f21786 100644 --- a/netbox/templates/circuits/circuittermination_edit.html +++ b/netbox/templates/circuits/circuittermination_edit.html @@ -7,6 +7,7 @@
Circuit Termination
+ {% render_field form.provider %} {% render_field form.provider_account %} {% render_field form.circuit %} {% render_field form.term_side %}
Provider{{ object.provider_account.provider|linkify }}{{ object.provider|linkify }}
Provider Account