#9047 - Re-introduce provider FK to Circuit model

This commit is contained in:
Daniel Sheppard 2023-03-27 12:53:28 -05:00
parent c91d8bdbed
commit c4e031ed84
18 changed files with 107 additions and 111 deletions

View File

@ -6,7 +6,7 @@ NetBox is ideal for managing your network's transit and peering providers and ci
flowchart TD flowchart TD
ASN --> Provider ASN --> Provider
Provider --> ProviderAccount --> Circuit Provider --> ProviderAccount --> Circuit
Provider --> ProviderNetwork Provider --> ProviderNetwork & Circuit
CircuitType --> Circuit CircuitType --> Circuit
click ASN "../../models/circuits/asn/" click ASN "../../models/circuits/asn/"

View File

@ -105,6 +105,7 @@ class CircuitCircuitTerminationSerializer(WritableNestedSerializer):
class CircuitSerializer(NetBoxModelSerializer): class CircuitSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail') url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail')
provider = NestedProviderSerializer()
provider_account = NestedProviderAccountSerializer() provider_account = NestedProviderAccountSerializer()
status = ChoiceField(choices=CircuitStatusChoices, required=False) status = ChoiceField(choices=CircuitStatusChoices, required=False)
type = NestedCircuitTypeSerializer() type = NestedCircuitTypeSerializer()
@ -115,9 +116,9 @@ class CircuitSerializer(NetBoxModelSerializer):
class Meta: class Meta:
model = Circuit model = Circuit
fields = [ fields = [
'id', 'url', 'display', 'cid', 'provider_account', 'type', 'status', 'tenant', 'install_date', 'termination_date', 'id', 'url', 'display', 'cid', 'provider', 'provider_account', 'type', 'status', 'tenant', 'install_date',
'commit_rate', 'description', 'termination_a', 'termination_z', 'comments', 'tags', 'custom_fields', 'termination_date', 'commit_rate', 'description', 'termination_a', 'termination_z', 'comments', 'tags',
'created', 'last_updated', 'custom_fields', 'created', 'last_updated',
] ]

View File

@ -142,12 +142,11 @@ class CircuitTypeFilterSet(OrganizationalModelFilterSet):
class CircuitFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet): class CircuitFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
provider_id = django_filters.ModelMultipleChoiceFilter( provider_id = django_filters.ModelMultipleChoiceFilter(
field_name='provider_account__provider',
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
label=_('Provider (ID)'), label=_('Provider (ID)'),
) )
provider = django_filters.ModelMultipleChoiceFilter( provider = django_filters.ModelMultipleChoiceFilter(
field_name='provider_account__provider__slug', field_name='provider__slug',
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
to_field_name='slug', to_field_name='slug',
label=_('Provider (slug)'), label=_('Provider (slug)'),

View File

@ -153,7 +153,7 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm):
model = Circuit model = Circuit
fieldsets = ( fieldsets = (
('Circuit', ('provider', 'type', 'status', 'description')), ('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',)), ('Tenancy', ('tenant',)),
) )
nullable_fields = ( nullable_fields = (

View File

@ -65,6 +65,11 @@ class CircuitTypeImportForm(NetBoxModelImportForm):
class CircuitImportForm(NetBoxModelImportForm): class CircuitImportForm(NetBoxModelImportForm):
provider = CSVModelChoiceField(
queryset=Provider.objects.all(),
to_field_name='name',
help_text=_('Assigned provider')
)
provider_account = CSVModelChoiceField( provider_account = CSVModelChoiceField(
queryset=ProviderAccount.objects.all(), queryset=ProviderAccount.objects.all(),
to_field_name='name', to_field_name='name',
@ -89,8 +94,8 @@ class CircuitImportForm(NetBoxModelImportForm):
class Meta: class Meta:
model = Circuit model = Circuit
fields = [ fields = [
'cid', 'provider_account', 'type', 'status', 'tenant', 'install_date', 'termination_date', 'commit_rate', 'cid', 'provider', 'provider_account', 'type', 'status', 'tenant', 'install_date', 'termination_date',
'description', 'comments', 'tags' 'commit_rate', 'description', 'comments', 'tags'
] ]

View File

@ -87,15 +87,20 @@ class CircuitTypeForm(NetBoxModelForm):
class CircuitForm(TenancyForm, NetBoxModelForm): class CircuitForm(TenancyForm, NetBoxModelForm):
provider = DynamicModelChoiceField(
queryset=Provider.objects.all(),
selector=True
)
provider_account = DynamicModelChoiceField( provider_account = DynamicModelChoiceField(
queryset=ProviderAccount.objects.all(), queryset=ProviderAccount.objects.all(),
initial_params={ initial_params={
'circuits': '$circuit' 'circuits': '$circuit'
}, },
query_params={ query_params={
'provider': '$provider', 'provider_id': '$provider',
}, },
selector=True selector=True,
required=False
) )
type = DynamicModelChoiceField( type = DynamicModelChoiceField(
queryset=CircuitType.objects.all() queryset=CircuitType.objects.all()
@ -103,7 +108,7 @@ class CircuitForm(TenancyForm, NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( 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')), ('Service Parameters', ('install_date', 'termination_date', 'commit_rate')),
('Tenancy', ('tenant_group', 'tenant')), ('Tenancy', ('tenant_group', 'tenant')),
) )
@ -111,7 +116,7 @@ class CircuitForm(TenancyForm, NetBoxModelForm):
class Meta: class Meta:
model = Circuit model = Circuit
fields = [ 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', 'description', 'tenant_group', 'tenant', 'comments', 'tags',
] ]
widgets = { widgets = {

View File

@ -14,9 +14,9 @@ def create_provideraccounts_from_providers(apps, schema_editor):
ProviderAccount = apps.get_model('circuits', 'ProviderAccount') ProviderAccount = apps.get_model('circuits', 'ProviderAccount')
for provider in Provider.objects.all(): for provider in Provider.objects.all():
if provider.account is not None: if provider.account:
provideraccount = ProviderAccount.objects.create( 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, account=provider.account,
provider=provider, provider=provider,
) )
@ -34,22 +34,6 @@ def revert_provideraccounts_from_providers(apps, schema_editor):
provideraccount.provider.save() 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): class Migration(migrations.Migration):
dependencies = [ 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), field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.provideraccount', null=True, blank=True),
preserve_default=False, 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( migrations.AlterModelOptions(
name='circuit', name='circuit',
options={'ordering': ['provider_account', 'cid']}, options={'ordering': ['provider', 'provider_account', 'cid']},
), ),
migrations.AddConstraint( migrations.AddConstraint(
model_name='circuit', model_name='circuit',
constraint=models.UniqueConstraint(fields=('provider_account', 'cid'), name='circuits_circuit_unique_provider_cid'), constraint=models.UniqueConstraint(fields=('provider_account', 'cid'), name='circuits_circuit_unique_provideraccount_cid'),
),
migrations.RemoveField(
model_name='circuit',
name='provider',
), ),
] ]

View File

@ -37,10 +37,17 @@ class Circuit(PrimaryModel):
verbose_name='Circuit ID', verbose_name='Circuit ID',
help_text=_("Unique circuit ID") help_text=_("Unique circuit ID")
) )
provider = models.ForeignKey(
to='circuits.Provider',
on_delete=models.PROTECT,
related_name='circuits'
)
provider_account = models.ForeignKey( provider_account = models.ForeignKey(
to='circuits.ProviderAccount', to='circuits.ProviderAccount',
on_delete=models.PROTECT, on_delete=models.PROTECT,
related_name='circuits' related_name='circuits',
blank=True,
null=True
) )
type = models.ForeignKey( type = models.ForeignKey(
to='CircuitType', to='CircuitType',
@ -103,20 +110,26 @@ class Circuit(PrimaryModel):
) )
clone_fields = ( 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 = ( prerequisite_models = (
'circuits.CircuitType', 'circuits.CircuitType',
'circuits.Provider',
'circuits.ProviderAccount', 'circuits.ProviderAccount',
) )
class Meta: class Meta:
ordering = ['provider_account', 'cid'] ordering = ['provider', 'provider_account', 'cid']
constraints = ( constraints = (
models.UniqueConstraint( models.UniqueConstraint(
fields=('provider_account', 'cid'), fields=('provider', 'cid'),
name='%(app_label)s_%(class)s_unique_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): def __str__(self):
@ -128,6 +141,11 @@ class Circuit(PrimaryModel):
def get_status_color(self): def get_status_color(self):
return CircuitStatusChoices.colors.get(self.status) 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( class CircuitTermination(
CustomFieldsMixin, CustomFieldsMixin,

View File

@ -50,7 +50,6 @@ class CircuitTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
verbose_name='Circuit ID' verbose_name='Circuit ID'
) )
provider = tables.Column( provider = tables.Column(
accessor=Accessor('provider_account__provider'),
linkify=True linkify=True
) )
provider_account = tables.Column( provider_account = tables.Column(
@ -74,9 +73,9 @@ class CircuitTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Circuit model = Circuit
fields = ( fields = (
'pk', 'id', 'cid', 'provider', 'provider_account', 'type', 'status', 'tenant', 'tenant_group', 'termination_a', 'termination_z', 'pk', 'id', 'cid', 'provider', 'provider_account', 'type', 'status', 'tenant', 'tenant_group',
'install_date', 'termination_date', 'commit_rate', 'description', 'comments', 'contacts', 'tags', 'created', 'termination_a', 'termination_z', 'install_date', 'termination_date', 'commit_rate', 'description',
'last_updated', 'comments', 'contacts', 'tags', 'created', 'last_updated',
) )
default_columns = ( default_columns = (
'pk', 'cid', 'provider', 'type', 'status', 'tenant', 'termination_a', 'termination_z', 'description', 'pk', 'cid', 'provider', 'type', 'status', 'tenant', 'termination_a', 'termination_z', 'description',

View File

@ -119,25 +119,28 @@ class CircuitTest(APIViewTestCases.APIViewTestCase):
CircuitType.objects.bulk_create(circuit_types) CircuitType.objects.bulk_create(circuit_types)
circuits = ( circuits = (
Circuit(cid='Circuit 1', 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_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_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) Circuit.objects.bulk_create(circuits)
cls.create_data = [ cls.create_data = [
{ {
'cid': 'Circuit 4', 'cid': 'Circuit 4',
'provider': providers[1].pk,
'provider_account': provider_accounts[1].pk, 'provider_account': provider_accounts[1].pk,
'type': circuit_types[1].pk, 'type': circuit_types[1].pk,
}, },
{ {
'cid': 'Circuit 5', 'cid': 'Circuit 5',
'provider': providers[1].pk,
'provider_account': provider_accounts[1].pk, 'provider_account': provider_accounts[1].pk,
'type': circuit_types[1].pk, 'type': circuit_types[1].pk,
}, },
{ {
'cid': 'Circuit 6', 'cid': 'Circuit 6',
'provider': providers[1].pk,
'provider_account': provider_accounts[1].pk, 'provider_account': provider_accounts[1].pk,
'type': circuit_types[1].pk, 'type': circuit_types[1].pk,
}, },
@ -174,9 +177,9 @@ class CircuitTerminationTest(APIViewTestCases.APIViewTestCase):
ProviderNetwork.objects.bulk_create(provider_networks) ProviderNetwork.objects.bulk_create(provider_networks)
circuits = ( circuits = (
Circuit(cid='Circuit 1', 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_account=provider_account, type=circuit_type), Circuit(cid='Circuit 2', provider=provider, provider_account=provider_account, type=circuit_type),
Circuit(cid='Circuit 3', 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) Circuit.objects.bulk_create(circuits)

View File

@ -73,8 +73,8 @@ class ProviderTestCase(TestCase, ChangeLoggedFilterSetTests):
CircuitType.objects.bulk_create(circuit_types) CircuitType.objects.bulk_create(circuit_types)
circuits = ( circuits = (
Circuit(provider_account=provider_accounts[0], type=circuit_types[0], cid='Test Circuit 1'), Circuit(provider=providers[0], 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[1], provider_account=provider_accounts[1], type=circuit_types[1], cid='Test Circuit 1'),
) )
Circuit.objects.bulk_create(circuits) Circuit.objects.bulk_create(circuits)
@ -215,12 +215,12 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
ProviderNetwork.objects.bulk_create(provider_networks) ProviderNetwork.objects.bulk_create(provider_networks)
circuits = ( 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=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_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[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=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_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[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=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_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[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) Circuit.objects.bulk_create(circuits)
@ -355,13 +355,13 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests):
ProviderNetwork.objects.bulk_create(provider_networks) ProviderNetwork.objects.bulk_create(provider_networks)
circuits = ( circuits = (
Circuit(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 1'),
Circuit(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 2'),
Circuit(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 3'),
Circuit(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 4'),
Circuit(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 5'),
Circuit(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 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 7'),
) )
Circuit.objects.bulk_create(circuits) Circuit.objects.bulk_create(circuits)

View File

@ -135,9 +135,9 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
CircuitType.objects.bulk_create(circuittypes) CircuitType.objects.bulk_create(circuittypes)
circuits = ( circuits = (
Circuit(cid='Circuit 1', 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_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_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) Circuit.objects.bulk_create(circuits)
@ -146,6 +146,7 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
cls.form_data = { cls.form_data = {
'cid': 'Circuit X', 'cid': 'Circuit X',
'provider': providers[1].pk,
'provider_account': provider_accounts[1].pk, 'provider_account': provider_accounts[1].pk,
'type': circuittypes[1].pk, 'type': circuittypes[1].pk,
'status': CircuitStatusChoices.STATUS_DECOMMISSIONED, 'status': CircuitStatusChoices.STATUS_DECOMMISSIONED,
@ -159,10 +160,10 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
} }
cls.csv_data = ( cls.csv_data = (
"cid,provider_account,type,status", "cid,provider,provider_account,type,status",
"Circuit 4,Provider Account 1,Circuit Type 1,active", "Circuit 4,Provider 1,Provider Account 1,Circuit Type 1,active",
"Circuit 5,Provider Account 1,Circuit Type 1,active", "Circuit 5,Provider 1,Provider Account 1,Circuit Type 1,active",
"Circuit 6,Provider Account 1,Circuit Type 1,active", "Circuit 6,Provider 1,Provider Account 1,Circuit Type 1,active",
) )
cls.csv_update_data = ( cls.csv_update_data = (
@ -173,6 +174,7 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
) )
cls.bulk_edit_data = { cls.bulk_edit_data = {
'provider': providers[1].pk,
'provider_account': provider_accounts[1].pk, 'provider_account': provider_accounts[1].pk,
'type': circuittypes[1].pk, 'type': circuittypes[1].pk,
'status': CircuitStatusChoices.STATUS_DECOMMISSIONED, 'status': CircuitStatusChoices.STATUS_DECOMMISSIONED,
@ -306,9 +308,9 @@ class CircuitTerminationTestCase(
account = ProviderAccount.objects.create(name='Provider Account 1', provider=provider, account='1234') account = ProviderAccount.objects.create(name='Provider Account 1', provider=provider, account='1234')
circuits = ( circuits = (
Circuit(cid='Circuit 1', provider_account=account, type=circuittype), Circuit(cid='Circuit 1', provider=provider, provider_account=account, type=circuittype),
Circuit(cid='Circuit 2', provider_account=account, type=circuittype), Circuit(cid='Circuit 2', provider=provider, provider_account=account, type=circuittype),
Circuit(cid='Circuit 3', provider_account=account, type=circuittype), Circuit(cid='Circuit 3', provider=provider, provider_account=account, type=circuittype),
) )
Circuit.objects.bulk_create(circuits) Circuit.objects.bulk_create(circuits)

View File

@ -18,7 +18,7 @@ from .models import *
class ProviderListView(generic.ObjectListView): class ProviderListView(generic.ObjectListView):
queryset = Provider.objects.annotate( queryset = Provider.objects.annotate(
count_circuits=count_related(Circuit, 'provider_account__provider') count_circuits=count_related(Circuit, 'provider')
) )
filterset = filtersets.ProviderFilterSet filterset = filtersets.ProviderFilterSet
filterset_form = forms.ProviderFilterForm filterset_form = forms.ProviderFilterForm
@ -32,7 +32,7 @@ class ProviderView(generic.ObjectView):
def get_extra_context(self, request, instance): def get_extra_context(self, request, instance):
related_models = ( related_models = (
(ProviderAccount.objects.restrict(request.user, 'view').filter(provider=instance), 'provider_id'), (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 { return {
@ -58,7 +58,7 @@ class ProviderBulkImportView(generic.BulkImportView):
class ProviderBulkEditView(generic.BulkEditView): class ProviderBulkEditView(generic.BulkEditView):
queryset = Provider.objects.annotate( queryset = Provider.objects.annotate(
count_circuits=count_related(Circuit, 'provider_account__provider') count_circuits=count_related(Circuit, 'provider')
) )
filterset = filtersets.ProviderFilterSet filterset = filtersets.ProviderFilterSet
table = tables.ProviderTable table = tables.ProviderTable
@ -67,7 +67,7 @@ class ProviderBulkEditView(generic.BulkEditView):
class ProviderBulkDeleteView(generic.BulkDeleteView): class ProviderBulkDeleteView(generic.BulkDeleteView):
queryset = Provider.objects.annotate( queryset = Provider.objects.annotate(
count_circuits=count_related(Circuit, 'provider_account__provider') count_circuits=count_related(Circuit, 'provider')
) )
filterset = filtersets.ProviderFilterSet filterset = filtersets.ProviderFilterSet
table = tables.ProviderTable table = tables.ProviderTable

View File

@ -32,7 +32,7 @@ class CablePathTestCase(TestCase):
provider = Provider.objects.create(name='Provider', slug='provider') provider = Provider.objects.create(name='Provider', slug='provider')
provider_account = ProviderAccount.objects.create(name='Account', account='AAAA1111', provider=provider) provider_account = ProviderAccount.objects.create(name='Account', account='AAAA1111', provider=provider)
circuit_type = CircuitType.objects.create(name='Circuit Type', slug='circuit-type') 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): def assertPathExists(self, nodes, **kwargs):
""" """

View File

@ -507,8 +507,8 @@ class CableTestCase(TestCase):
provider_account = ProviderAccount.objects.create(name='Provider Account 1', account='A1', provider=provider) provider_account = ProviderAccount.objects.create(name='Provider Account 1', account='A1', provider=provider)
provider_network = ProviderNetwork.objects.create(name='Provider Network 1', 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') circuittype = CircuitType.objects.create(name='Circuit Type 1', slug='circuit-type-1')
circuit1 = Circuit.objects.create(provider_account=provider_account, type=circuittype, cid='1') circuit1 = Circuit.objects.create(provider=provider, provider_account=provider_account, type=circuittype, cid='1')
circuit2 = Circuit.objects.create(provider_account=provider_account, type=circuittype, cid='2') 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') circuittermination1 = CircuitTermination.objects.create(circuit=circuit1, site=site, term_side='A')
circuittermination2 = CircuitTermination.objects.create(circuit=circuit1, site=site, term_side='Z') circuittermination2 = CircuitTermination.objects.create(circuit=circuit1, site=site, term_side='Z')
circuittermination3 = CircuitTermination.objects.create(circuit=circuit2, provider_network=provider_network, term_side='A') circuittermination3 = CircuitTermination.objects.create(circuit=circuit2, provider_network=provider_network, term_side='A')

View File

@ -38,15 +38,15 @@ class StagingTestCase(TransactionTestCase):
circuit_type = CircuitType.objects.create(name='Circuit Type 1', slug='circuit-type-1') circuit_type = CircuitType.objects.create(name='Circuit Type 1', slug='circuit-type-1')
Circuit.objects.bulk_create(( Circuit.objects.bulk_create((
Circuit(provider_account=provider_accounts[0], cid='Circuit A1', type=circuit_type), Circuit(provider=providers[0], 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=providers[0], 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=providers[0], 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=providers[1], 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=providers[1], 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=providers[1], 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=providers[2], 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=providers[2], 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[2], provider_account=provider_accounts[2], cid='Circuit C3', type=circuit_type),
)) ))
def test_object_creation(self): def test_object_creation(self):
@ -58,7 +58,7 @@ class StagingTestCase(TransactionTestCase):
provider = Provider.objects.create(name='Provider D', slug='provider-d') provider = Provider.objects.create(name='Provider D', slug='provider-d')
provider.asns.set(asns) provider.asns.set(asns)
provider_account = ProviderAccount.objects.create(name='Account D', provider=provider, account='DDDD') 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) circuit.tags.set(tags)
# Sanity-checking # Sanity-checking

View File

@ -16,7 +16,7 @@
<table class="table table-hover attr-table"> <table class="table table-hover attr-table">
<tr> <tr>
<th scope="row">Provider</th> <th scope="row">Provider</th>
<td>{{ object.provider_account.provider|linkify }}</td> <td>{{ object.provider|linkify }}</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Provider Account</th> <th scope="row">Provider Account</th>

View File

@ -7,6 +7,7 @@
<div class="row mb-2"> <div class="row mb-2">
<h5 class="offset-sm-3">Circuit Termination</h5> <h5 class="offset-sm-3">Circuit Termination</h5>
</div> </div>
{% render_field form.provider %}
{% render_field form.provider_account %} {% render_field form.provider_account %}
{% render_field form.circuit %} {% render_field form.circuit %}
{% render_field form.term_side %} {% render_field form.term_side %}