mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-26 17:26:10 -06:00
#9047 - Link Circuits to Provider Account instead of Provider
This commit is contained in:
parent
22fdd6160c
commit
1a6bd726eb
@ -105,7 +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()
|
||||
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
||||
@ -115,7 +115,7 @@ class CircuitSerializer(NetBoxModelSerializer):
|
||||
class Meta:
|
||||
model = Circuit
|
||||
fields = [
|
||||
'id', 'url', 'display', 'cid', 'provider', 'type', 'status', 'tenant', 'install_date', 'termination_date',
|
||||
'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',
|
||||
]
|
||||
|
@ -22,7 +22,7 @@ class CircuitsRootView(APIRootView):
|
||||
|
||||
class ProviderViewSet(NetBoxModelViewSet):
|
||||
queryset = Provider.objects.prefetch_related('asns', 'tags').annotate(
|
||||
circuit_count=count_related(Circuit, 'provider')
|
||||
circuit_count=count_related(Circuit, 'provider_account__provider')
|
||||
)
|
||||
serializer_class = serializers.ProviderSerializer
|
||||
filterset_class = filtersets.ProviderFilterSet
|
||||
@ -46,7 +46,7 @@ class CircuitTypeViewSet(NetBoxModelViewSet):
|
||||
|
||||
class CircuitViewSet(NetBoxModelViewSet):
|
||||
queryset = Circuit.objects.prefetch_related(
|
||||
'type', 'tenant', 'provider', 'termination_a', 'termination_z'
|
||||
'type', 'tenant', 'provider_account', 'provider_account__provider', 'termination_a', 'termination_z'
|
||||
).prefetch_related('tags')
|
||||
serializer_class = serializers.CircuitSerializer
|
||||
filterset_class = filtersets.CircuitFilterSet
|
||||
|
@ -24,37 +24,37 @@ __all__ = (
|
||||
class ProviderFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
|
||||
region_id = TreeNodeMultipleChoiceFilter(
|
||||
queryset=Region.objects.all(),
|
||||
field_name='circuits__terminations__site__region',
|
||||
field_name='accounts__circuits__terminations__site__region',
|
||||
lookup_expr='in',
|
||||
label=_('Region (ID)'),
|
||||
)
|
||||
region = TreeNodeMultipleChoiceFilter(
|
||||
queryset=Region.objects.all(),
|
||||
field_name='circuits__terminations__site__region',
|
||||
field_name='accounts__circuits__terminations__site__region',
|
||||
lookup_expr='in',
|
||||
to_field_name='slug',
|
||||
label=_('Region (slug)'),
|
||||
)
|
||||
site_group_id = TreeNodeMultipleChoiceFilter(
|
||||
queryset=SiteGroup.objects.all(),
|
||||
field_name='circuits__terminations__site__group',
|
||||
field_name='accounts__circuits__terminations__site__group',
|
||||
lookup_expr='in',
|
||||
label=_('Site group (ID)'),
|
||||
)
|
||||
site_group = TreeNodeMultipleChoiceFilter(
|
||||
queryset=SiteGroup.objects.all(),
|
||||
field_name='circuits__terminations__site__group',
|
||||
field_name='accounts__circuits__terminations__site__group',
|
||||
lookup_expr='in',
|
||||
to_field_name='slug',
|
||||
label=_('Site group (slug)'),
|
||||
)
|
||||
site_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='circuits__terminations__site',
|
||||
field_name='accounts__circuits__terminations__site',
|
||||
queryset=Site.objects.all(),
|
||||
label=_('Site'),
|
||||
)
|
||||
site = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='circuits__terminations__site__slug',
|
||||
field_name='accounts__circuits__terminations__site__slug',
|
||||
queryset=Site.objects.all(),
|
||||
to_field_name='slug',
|
||||
label=_('Site (slug)'),
|
||||
@ -142,15 +142,21 @@ 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__slug',
|
||||
field_name='provider_account__provider__slug',
|
||||
queryset=Provider.objects.all(),
|
||||
to_field_name='slug',
|
||||
label=_('Provider (slug)'),
|
||||
)
|
||||
provider_account_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='provider_account',
|
||||
queryset=ProviderAccount.objects.all(),
|
||||
label=_('ProviderAccount (ID)'),
|
||||
)
|
||||
provider_network_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='terminations__provider_network',
|
||||
queryset=ProviderNetwork.objects.all(),
|
||||
|
@ -118,6 +118,13 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm):
|
||||
queryset=Provider.objects.all(),
|
||||
required=False
|
||||
)
|
||||
provider_account = DynamicModelChoiceField(
|
||||
queryset=ProviderAccount.objects.all(),
|
||||
required=False,
|
||||
query_params={
|
||||
'provider': '$provider'
|
||||
}
|
||||
)
|
||||
status = forms.ChoiceField(
|
||||
choices=add_blank_choice(CircuitStatusChoices),
|
||||
required=False,
|
||||
|
@ -68,10 +68,10 @@ class CircuitTypeImportForm(NetBoxModelImportForm):
|
||||
|
||||
|
||||
class CircuitImportForm(NetBoxModelImportForm):
|
||||
provider = CSVModelChoiceField(
|
||||
queryset=Provider.objects.all(),
|
||||
provider_account = CSVModelChoiceField(
|
||||
queryset=ProviderAccount.objects.all(),
|
||||
to_field_name='name',
|
||||
help_text=_('Assigned provider')
|
||||
help_text=_('Assigned provider account')
|
||||
)
|
||||
type = CSVModelChoiceField(
|
||||
queryset=CircuitType.objects.all(),
|
||||
@ -92,7 +92,7 @@ class CircuitImportForm(NetBoxModelImportForm):
|
||||
class Meta:
|
||||
model = Circuit
|
||||
fields = [
|
||||
'cid', 'provider', 'type', 'status', 'tenant', 'install_date', 'termination_date', 'commit_rate',
|
||||
'cid', 'provider_account', 'type', 'status', 'tenant', 'install_date', 'termination_date', 'commit_rate',
|
||||
'description', 'comments', 'tags'
|
||||
]
|
||||
|
||||
|
@ -118,6 +118,14 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
|
||||
required=False,
|
||||
label=_('Provider')
|
||||
)
|
||||
provider_account_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Provider.objects.all(),
|
||||
required=False,
|
||||
query_params={
|
||||
'provider_id': '$provider_id'
|
||||
},
|
||||
label=_('Provider')
|
||||
)
|
||||
provider_network_id = DynamicModelMultipleChoiceField(
|
||||
queryset=ProviderNetwork.objects.all(),
|
||||
required=False,
|
||||
|
@ -44,6 +44,9 @@ class ProviderForm(NetBoxModelForm):
|
||||
|
||||
|
||||
class ProviderAccountForm(NetBoxModelForm):
|
||||
provider = DynamicModelChoiceField(
|
||||
queryset=Provider.objects.all()
|
||||
)
|
||||
comments = CommentField()
|
||||
|
||||
class Meta:
|
||||
@ -88,7 +91,20 @@ class CircuitTypeForm(NetBoxModelForm):
|
||||
|
||||
class CircuitForm(TenancyForm, NetBoxModelForm):
|
||||
provider = DynamicModelChoiceField(
|
||||
queryset=Provider.objects.all()
|
||||
required=False,
|
||||
queryset=Provider.objects.all(),
|
||||
initial_params={
|
||||
'accounts': '$provider_account'
|
||||
},
|
||||
)
|
||||
provider_account = DynamicModelChoiceField(
|
||||
queryset=ProviderAccount.objects.all(),
|
||||
initial_params={
|
||||
'circuits': '$circuit'
|
||||
},
|
||||
query_params={
|
||||
'provider': '$provider',
|
||||
}
|
||||
)
|
||||
type = DynamicModelChoiceField(
|
||||
queryset=CircuitType.objects.all()
|
||||
@ -96,7 +112,7 @@ class CircuitForm(TenancyForm, NetBoxModelForm):
|
||||
comments = CommentField()
|
||||
|
||||
fieldsets = (
|
||||
('Circuit', ('provider', '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')),
|
||||
)
|
||||
@ -104,8 +120,8 @@ class CircuitForm(TenancyForm, NetBoxModelForm):
|
||||
class Meta:
|
||||
model = Circuit
|
||||
fields = [
|
||||
'cid', 'type', 'provider', 'status', 'install_date', 'termination_date', 'commit_rate', 'description',
|
||||
'tenant_group', 'tenant', 'comments', 'tags',
|
||||
'cid', 'type', 'provider', 'provider_account', 'status', 'install_date', 'termination_date', 'commit_rate',
|
||||
'description', 'tenant_group', 'tenant', 'comments', 'tags',
|
||||
]
|
||||
help_texts = {
|
||||
'cid': _("Unique circuit ID"),
|
||||
@ -123,8 +139,18 @@ class CircuitTerminationForm(NetBoxModelForm):
|
||||
provider = DynamicModelChoiceField(
|
||||
queryset=Provider.objects.all(),
|
||||
required=False,
|
||||
initial_params={
|
||||
'accounts': '$provider_account'
|
||||
}
|
||||
)
|
||||
provider_account = DynamicModelChoiceField(
|
||||
queryset=ProviderAccount.objects.all(),
|
||||
required=False,
|
||||
initial_params={
|
||||
'circuits': '$circuit'
|
||||
},
|
||||
query_params={
|
||||
'provider': '$provider',
|
||||
}
|
||||
)
|
||||
circuit = DynamicModelChoiceField(
|
||||
@ -174,9 +200,9 @@ class CircuitTerminationForm(NetBoxModelForm):
|
||||
class Meta:
|
||||
model = CircuitTermination
|
||||
fields = [
|
||||
'provider', 'circuit', 'term_side', 'region', 'site_group', 'site', 'provider_network_provider',
|
||||
'provider_network', 'mark_connected', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info',
|
||||
'description', 'tags',
|
||||
'provider', 'provider_account', 'circuit', 'term_side', 'region', 'site_group', 'site',
|
||||
'provider_network_provider', 'provider_network', 'mark_connected', 'port_speed', 'upstream_speed',
|
||||
'xconnect_id', 'pp_info', 'description', 'tags',
|
||||
]
|
||||
help_texts = {
|
||||
'port_speed': _("Physical circuit speed"),
|
||||
|
@ -34,6 +34,22 @@ 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 = [
|
||||
@ -75,4 +91,39 @@ class Migration(migrations.Migration):
|
||||
model_name='provider',
|
||||
name='account',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='circuit',
|
||||
name='provider_account',
|
||||
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']},
|
||||
),
|
||||
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',
|
||||
),
|
||||
]
|
||||
|
@ -38,8 +38,8 @@ class Circuit(PrimaryModel):
|
||||
max_length=100,
|
||||
verbose_name='Circuit ID'
|
||||
)
|
||||
provider = models.ForeignKey(
|
||||
to='circuits.Provider',
|
||||
provider_account = models.ForeignKey(
|
||||
to='circuits.ProviderAccount',
|
||||
on_delete=models.PROTECT,
|
||||
related_name='circuits'
|
||||
)
|
||||
@ -102,18 +102,18 @@ class Circuit(PrimaryModel):
|
||||
)
|
||||
|
||||
clone_fields = (
|
||||
'provider', 'type', 'status', 'tenant', 'install_date', 'termination_date', 'commit_rate', 'description',
|
||||
'provider_account', 'type', 'status', 'tenant', 'install_date', 'termination_date', 'commit_rate', 'description',
|
||||
)
|
||||
prerequisite_models = (
|
||||
'circuits.CircuitType',
|
||||
'circuits.Provider',
|
||||
'circuits.ProviderAccount',
|
||||
)
|
||||
|
||||
class Meta:
|
||||
ordering = ['provider', 'cid']
|
||||
ordering = ['provider_account', 'cid']
|
||||
constraints = (
|
||||
models.UniqueConstraint(
|
||||
fields=('provider', 'cid'),
|
||||
fields=('provider_account', 'cid'),
|
||||
name='%(app_label)s_%(class)s_unique_provider_cid'
|
||||
),
|
||||
)
|
||||
|
@ -90,6 +90,7 @@ class ProviderAccount(PrimaryModel):
|
||||
def __str__(self):
|
||||
if self.name:
|
||||
return f'{self.account} ({self.name})'
|
||||
return f'{self.account}'
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('circuits:provideraccount', args=[self.pk])
|
||||
|
@ -1,4 +1,6 @@
|
||||
import django_tables2 as tables
|
||||
from django_tables2.utils import Accessor
|
||||
|
||||
from circuits.models import *
|
||||
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
|
||||
|
||||
@ -48,6 +50,10 @@ class CircuitTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||
verbose_name='Circuit ID'
|
||||
)
|
||||
provider = tables.Column(
|
||||
accessor=Accessor('provider_account__provider'),
|
||||
linkify=True
|
||||
)
|
||||
provider_account = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
status = columns.ChoiceFieldColumn()
|
||||
@ -68,7 +74,7 @@ class CircuitTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = Circuit
|
||||
fields = (
|
||||
'pk', 'id', 'cid', 'provider', 'type', 'status', 'tenant', 'tenant_group', 'termination_a', 'termination_z',
|
||||
'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',
|
||||
)
|
||||
|
@ -57,10 +57,10 @@ class ProviderTable(ContactsColumnMixin, NetBoxTable):
|
||||
|
||||
|
||||
class ProviderAccountTable(ContactsColumnMixin, NetBoxTable):
|
||||
name = tables.Column(
|
||||
account = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
account = tables.Column()
|
||||
name = tables.Column()
|
||||
provider = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
@ -72,9 +72,9 @@ class ProviderAccountTable(ContactsColumnMixin, NetBoxTable):
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = ProviderAccount
|
||||
fields = (
|
||||
'pk', 'id', 'account', 'name', 'provider', 'comments', 'contacts', 'tags', 'created', 'last_updated',
|
||||
'pk', 'id', 'account', 'name', 'provider', 'circuit_count', 'comments', 'contacts', 'tags', 'created', 'last_updated',
|
||||
)
|
||||
default_columns = ('pk', 'account', 'name', 'provider')
|
||||
default_columns = ('pk', 'account', 'name', 'provider', 'circuit_count')
|
||||
|
||||
|
||||
class ProviderNetworkTable(NetBoxTable):
|
||||
|
@ -106,6 +106,12 @@ class CircuitTest(APIViewTestCases.APIViewTestCase):
|
||||
)
|
||||
Provider.objects.bulk_create(providers)
|
||||
|
||||
provider_accounts = (
|
||||
ProviderAccount(name='Provider Account 1', provider=providers[0], account='1234'),
|
||||
ProviderAccount(name='Provider Account 2', provider=providers[1], account='2345'),
|
||||
)
|
||||
ProviderAccount.objects.bulk_create(provider_accounts)
|
||||
|
||||
circuit_types = (
|
||||
CircuitType(name='Circuit Type 1', slug='circuit-type-1'),
|
||||
CircuitType(name='Circuit Type 2', slug='circuit-type-2'),
|
||||
@ -113,26 +119,26 @@ class CircuitTest(APIViewTestCases.APIViewTestCase):
|
||||
CircuitType.objects.bulk_create(circuit_types)
|
||||
|
||||
circuits = (
|
||||
Circuit(cid='Circuit 1', provider=providers[0], type=circuit_types[0]),
|
||||
Circuit(cid='Circuit 2', provider=providers[0], type=circuit_types[0]),
|
||||
Circuit(cid='Circuit 3', provider=providers[0], type=circuit_types[0]),
|
||||
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.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,
|
||||
},
|
||||
]
|
||||
@ -149,6 +155,11 @@ class CircuitTerminationTest(APIViewTestCases.APIViewTestCase):
|
||||
|
||||
provider = Provider.objects.create(name='Provider 1', slug='provider-1')
|
||||
circuit_type = CircuitType.objects.create(name='Circuit Type 1', slug='circuit-type-1')
|
||||
provider_account = ProviderAccount.objects.create(
|
||||
name='Provider Account 2',
|
||||
provider=provider,
|
||||
account='2345'
|
||||
)
|
||||
|
||||
sites = (
|
||||
Site(name='Site 1', slug='site-1'),
|
||||
@ -163,9 +174,9 @@ class CircuitTerminationTest(APIViewTestCases.APIViewTestCase):
|
||||
ProviderNetwork.objects.bulk_create(provider_networks)
|
||||
|
||||
circuits = (
|
||||
Circuit(cid='Circuit 1', provider=provider, type=circuit_type),
|
||||
Circuit(cid='Circuit 2', provider=provider, type=circuit_type),
|
||||
Circuit(cid='Circuit 3', provider=provider, type=circuit_type),
|
||||
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.objects.bulk_create(circuits)
|
||||
|
||||
|
@ -192,6 +192,12 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
|
||||
)
|
||||
Provider.objects.bulk_create(providers)
|
||||
|
||||
provider_accounts = (
|
||||
ProviderAccount(name='Provider Account 1', provider=providers[0], account='1234'),
|
||||
ProviderAccount(name='Provider Account 2', provider=providers[1], account='2345'),
|
||||
)
|
||||
ProviderAccount.objects.bulk_create(provider_accounts)
|
||||
|
||||
provider_networks = (
|
||||
ProviderNetwork(name='Provider Network 1', provider=providers[1]),
|
||||
ProviderNetwork(name='Provider Network 2', provider=providers[1]),
|
||||
@ -200,12 +206,12 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
|
||||
ProviderNetwork.objects.bulk_create(provider_networks)
|
||||
|
||||
circuits = (
|
||||
Circuit(provider=providers[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], 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], 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], 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], 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], 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_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.objects.bulk_create(circuits)
|
||||
|
||||
@ -242,6 +248,11 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
|
||||
params = {'provider': [provider.slug]}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
|
||||
|
||||
def test_provider_account(self):
|
||||
provider = ProviderAccount.objects.first()
|
||||
params = {'provider_id': [provider.pk]}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
|
||||
|
||||
def test_provider_network(self):
|
||||
provider_networks = ProviderNetwork.objects.all()[:2]
|
||||
params = {'provider_network_id': [provider_networks[0].pk, provider_networks[1].pk]}
|
||||
@ -322,6 +333,11 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests):
|
||||
)
|
||||
Provider.objects.bulk_create(providers)
|
||||
|
||||
provider_accounts = (
|
||||
ProviderAccount(name='Provider Account 1', provider=providers[0], account='1234'),
|
||||
)
|
||||
ProviderAccount.objects.bulk_create(provider_accounts)
|
||||
|
||||
provider_networks = (
|
||||
ProviderNetwork(name='Provider Network 1', provider=providers[0]),
|
||||
ProviderNetwork(name='Provider Network 2', provider=providers[0]),
|
||||
@ -330,13 +346,13 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests):
|
||||
ProviderNetwork.objects.bulk_create(provider_networks)
|
||||
|
||||
circuits = (
|
||||
Circuit(provider=providers[0], type=circuit_types[0], cid='Circuit 1'),
|
||||
Circuit(provider=providers[0], type=circuit_types[0], cid='Circuit 2'),
|
||||
Circuit(provider=providers[0], type=circuit_types[0], cid='Circuit 3'),
|
||||
Circuit(provider=providers[0], type=circuit_types[0], cid='Circuit 4'),
|
||||
Circuit(provider=providers[0], type=circuit_types[0], cid='Circuit 5'),
|
||||
Circuit(provider=providers[0], type=circuit_types[0], cid='Circuit 6'),
|
||||
Circuit(provider=providers[0], type=circuit_types[0], cid='Circuit 7'),
|
||||
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.objects.bulk_create(circuits)
|
||||
|
||||
|
@ -122,6 +122,12 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
)
|
||||
Provider.objects.bulk_create(providers)
|
||||
|
||||
provider_accounts = (
|
||||
ProviderAccount(name='Provider Account 1', provider=providers[0], account='1234'),
|
||||
ProviderAccount(name='Provider Account 2', provider=providers[1], account='2345'),
|
||||
)
|
||||
ProviderAccount.objects.bulk_create(provider_accounts)
|
||||
|
||||
circuittypes = (
|
||||
CircuitType(name='Circuit Type 1', slug='circuit-type-1'),
|
||||
CircuitType(name='Circuit Type 2', slug='circuit-type-2'),
|
||||
@ -129,9 +135,9 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
CircuitType.objects.bulk_create(circuittypes)
|
||||
|
||||
circuits = (
|
||||
Circuit(cid='Circuit 1', provider=providers[0], type=circuittypes[0]),
|
||||
Circuit(cid='Circuit 2', provider=providers[0], type=circuittypes[0]),
|
||||
Circuit(cid='Circuit 3', provider=providers[0], type=circuittypes[0]),
|
||||
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.objects.bulk_create(circuits)
|
||||
@ -140,7 +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,
|
||||
'tenant': None,
|
||||
@ -153,10 +159,10 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
}
|
||||
|
||||
cls.csv_data = (
|
||||
"cid,provider,type,status",
|
||||
"Circuit 4,Provider 1,Circuit Type 1,active",
|
||||
"Circuit 5,Provider 1,Circuit Type 1,active",
|
||||
"Circuit 6,Provider 1,Circuit Type 1,active",
|
||||
"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",
|
||||
)
|
||||
|
||||
cls.csv_update_data = (
|
||||
@ -167,7 +173,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,
|
||||
'tenant': None,
|
||||
@ -297,11 +303,12 @@ class CircuitTerminationTestCase(
|
||||
Site.objects.bulk_create(sites)
|
||||
provider = Provider.objects.create(name='Provider 1', slug='provider-1')
|
||||
circuittype = CircuitType.objects.create(name='Circuit Type 1', slug='circuit-type-1')
|
||||
account = ProviderAccount.objects.create(name='Provider Account 1', provider=provider, account='1234')
|
||||
|
||||
circuits = (
|
||||
Circuit(cid='Circuit 1', provider=provider, type=circuittype),
|
||||
Circuit(cid='Circuit 2', provider=provider, type=circuittype),
|
||||
Circuit(cid='Circuit 3', provider=provider, type=circuittype),
|
||||
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.objects.bulk_create(circuits)
|
||||
|
||||
|
@ -18,7 +18,7 @@ from .models import *
|
||||
|
||||
class ProviderListView(generic.ObjectListView):
|
||||
queryset = Provider.objects.annotate(
|
||||
count_circuits=count_related(Circuit, 'provider')
|
||||
count_circuits=count_related(Circuit, 'provider_account__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=instance), 'provider_id'),
|
||||
(Circuit.objects.restrict(request.user, 'view').filter(provider_account__provider=instance), 'provider_id'),
|
||||
)
|
||||
|
||||
return {
|
||||
@ -59,7 +59,7 @@ class ProviderBulkImportView(generic.BulkImportView):
|
||||
|
||||
class ProviderBulkEditView(generic.BulkEditView):
|
||||
queryset = Provider.objects.annotate(
|
||||
count_circuits=count_related(Circuit, 'provider')
|
||||
count_circuits=count_related(Circuit, 'provider_account__provider')
|
||||
)
|
||||
filterset = filtersets.ProviderFilterSet
|
||||
table = tables.ProviderTable
|
||||
@ -68,7 +68,7 @@ class ProviderBulkEditView(generic.BulkEditView):
|
||||
|
||||
class ProviderBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = Provider.objects.annotate(
|
||||
count_circuits=count_related(Circuit, 'provider')
|
||||
count_circuits=count_related(Circuit, 'provider_account__provider')
|
||||
)
|
||||
filterset = filtersets.ProviderFilterSet
|
||||
table = tables.ProviderTable
|
||||
@ -79,7 +79,9 @@ class ProviderBulkDeleteView(generic.BulkDeleteView):
|
||||
#
|
||||
|
||||
class ProviderAccountListView(generic.ObjectListView):
|
||||
queryset = ProviderAccount.objects.all()
|
||||
queryset = ProviderAccount.objects.annotate(
|
||||
count_circuits=count_related(Circuit, 'provider_account')
|
||||
)
|
||||
filterset = filtersets.ProviderAccountFilterSet
|
||||
filterset_form = forms.ProviderAccountFilterForm
|
||||
table = tables.ProviderAccountTable
|
||||
@ -89,6 +91,15 @@ class ProviderAccountListView(generic.ObjectListView):
|
||||
class ProviderAccountView(generic.ObjectView):
|
||||
queryset = ProviderAccount.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
related_models = (
|
||||
(Circuit.objects.restrict(request.user, 'view').filter(provider_account=instance), 'provider_account_id'),
|
||||
)
|
||||
|
||||
return {
|
||||
'related_models': related_models,
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(ProviderAccount, 'edit')
|
||||
class ProviderAccountEditView(generic.ObjectEditView):
|
||||
@ -108,14 +119,18 @@ class ProviderAccountBulkImportView(generic.BulkImportView):
|
||||
|
||||
|
||||
class ProviderAccountBulkEditView(generic.BulkEditView):
|
||||
queryset = ProviderAccount.objects.all()
|
||||
queryset = ProviderAccount.objects.annotate(
|
||||
count_circuits=count_related(Circuit, 'provider_account')
|
||||
)
|
||||
filterset = filtersets.ProviderAccountFilterSet
|
||||
table = tables.ProviderAccountTable
|
||||
form = forms.ProviderAccountBulkEditForm
|
||||
|
||||
|
||||
class ProviderAccountBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = ProviderAccount.objects.all()
|
||||
queryset = ProviderAccount.objects.annotate(
|
||||
count_circuits=count_related(Circuit, 'provider_account')
|
||||
)
|
||||
filterset = filtersets.ProviderAccountFilterSet
|
||||
table = tables.ProviderAccountTable
|
||||
|
||||
|
@ -16,7 +16,11 @@
|
||||
<table class="table table-hover attr-table">
|
||||
<tr>
|
||||
<th scope="row">Provider</th>
|
||||
<td>{{ object.provider|linkify }}</td>
|
||||
<td>{{ object.provider_account.provider|linkify }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Provider Account</th>
|
||||
<td>{{ object.provider_account|linkify }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Circuit ID</th>
|
||||
|
@ -8,6 +8,7 @@
|
||||
<h5 class="offset-sm-3">Circuit Termination</h5>
|
||||
</div>
|
||||
{% render_field form.provider %}
|
||||
{% render_field form.provider_account %}
|
||||
{% render_field form.circuit %}
|
||||
{% render_field form.term_side %}
|
||||
{% render_field form.tags %}
|
||||
|
@ -43,5 +43,16 @@
|
||||
{% include 'inc/panels/contacts.html' %}
|
||||
{% plugin_right_page object %}
|
||||
</div>
|
||||
|
||||
<div class="col col-md-12">
|
||||
<div class="card">
|
||||
<h5 class="card-header">Circuits</h5>
|
||||
<div class="card-body htmx-container table-responsive"
|
||||
hx-get="{% url 'circuits:circuit_list' %}?provider_id={{ object.pk }}"
|
||||
hx-trigger="load"
|
||||
></div>
|
||||
</div>
|
||||
{% plugin_full_width_page object %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
Loading…
Reference in New Issue
Block a user