2020-01-09 20:10:51 +00:00
|
|
|
from django.conf import settings
|
2016-12-14 13:47:22 -05:00
|
|
|
from django.contrib import messages
|
|
|
|
from django.db import transaction
|
2020-05-21 14:34:40 -04:00
|
|
|
from django.db.models import Count, OuterRef
|
2016-12-14 13:47:22 -05:00
|
|
|
from django.shortcuts import get_object_or_404, redirect, render
|
2020-01-09 20:10:51 +00:00
|
|
|
from django_tables2 import RequestConfig
|
2016-03-01 11:23:03 -05:00
|
|
|
|
2019-12-06 10:32:59 -05:00
|
|
|
from extras.models import Graph
|
2016-12-14 13:47:22 -05:00
|
|
|
from utilities.forms import ConfirmationForm
|
2020-01-09 20:10:51 +00:00
|
|
|
from utilities.paginator import EnhancedPaginator
|
2016-05-18 15:17:58 -04:00
|
|
|
from utilities.views import (
|
2020-05-21 15:39:07 -04:00
|
|
|
BulkDeleteView, BulkEditView, BulkImportView, ObjectView, ObjectDeleteView, ObjectEditView, ObjectListView,
|
2016-05-18 15:17:58 -04:00
|
|
|
)
|
2016-05-18 16:35:35 -04:00
|
|
|
from . import filters, forms, tables
|
2019-11-21 21:28:59 -05:00
|
|
|
from .choices import CircuitTerminationSideChoices
|
2017-11-07 11:08:23 -05:00
|
|
|
from .models import Circuit, CircuitTermination, CircuitType, Provider
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# Providers
|
|
|
|
#
|
|
|
|
|
2020-05-21 13:22:09 -04:00
|
|
|
class ProviderListView(ObjectListView):
|
2016-03-01 11:23:03 -05:00
|
|
|
queryset = Provider.objects.annotate(count_circuits=Count('circuits'))
|
2020-01-09 20:57:13 -05:00
|
|
|
filterset = filters.ProviderFilterSet
|
|
|
|
filterset_form = forms.ProviderFilterForm
|
2020-04-28 16:20:11 -04:00
|
|
|
table = tables.ProviderTable
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2020-05-21 15:39:07 -04:00
|
|
|
class ProviderView(ObjectView):
|
|
|
|
queryset = Provider.objects.all()
|
2016-03-01 11:23:03 -05:00
|
|
|
|
2017-05-18 17:00:57 -04:00
|
|
|
def get(self, request, slug):
|
2016-03-01 11:23:03 -05:00
|
|
|
|
2020-05-21 15:39:07 -04:00
|
|
|
provider = get_object_or_404(self.queryset, slug=slug)
|
2020-06-01 11:43:49 -04:00
|
|
|
circuits = Circuit.objects.restrict(request.user, 'view').filter(
|
2020-02-26 16:41:59 -05:00
|
|
|
provider=provider
|
|
|
|
).prefetch_related(
|
|
|
|
'type', 'tenant', 'terminations__site'
|
|
|
|
).annotate_sites()
|
2019-12-06 10:32:59 -05:00
|
|
|
show_graphs = Graph.objects.filter(type__model='provider').exists()
|
2017-05-18 17:00:57 -04:00
|
|
|
|
2020-02-26 16:41:59 -05:00
|
|
|
circuits_table = tables.CircuitTable(circuits)
|
2020-01-09 20:15:22 +00:00
|
|
|
circuits_table.columns.hide('provider')
|
|
|
|
|
2020-01-09 20:10:51 +00:00
|
|
|
paginate = {
|
|
|
|
'paginator_class': EnhancedPaginator,
|
|
|
|
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
|
|
|
|
}
|
|
|
|
RequestConfig(request, paginate).configure(circuits_table)
|
|
|
|
|
2017-05-18 17:00:57 -04:00
|
|
|
return render(request, 'circuits/provider.html', {
|
|
|
|
'provider': provider,
|
2020-01-09 20:10:51 +00:00
|
|
|
'circuits_table': circuits_table,
|
2017-05-18 17:00:57 -04:00
|
|
|
'show_graphs': show_graphs,
|
|
|
|
})
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2020-05-21 13:59:19 -04:00
|
|
|
class ProviderEditView(ObjectEditView):
|
2020-05-11 12:37:22 -04:00
|
|
|
queryset = Provider.objects.all()
|
2017-09-12 13:54:44 -04:00
|
|
|
model_form = forms.ProviderForm
|
2016-05-03 15:46:30 -04:00
|
|
|
template_name = 'circuits/provider_edit.html'
|
2017-01-23 14:07:26 -05:00
|
|
|
default_return_url = 'circuits:provider_list'
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2020-05-21 14:34:40 -04:00
|
|
|
class ProviderDeleteView(ObjectDeleteView):
|
2020-05-11 12:47:01 -04:00
|
|
|
queryset = Provider.objects.all()
|
2017-01-18 13:30:19 -05:00
|
|
|
default_return_url = 'circuits:provider_list'
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2020-05-21 14:43:27 -04:00
|
|
|
class ProviderBulkImportView(BulkImportView):
|
2020-05-21 11:58:27 -04:00
|
|
|
queryset = Provider.objects.all()
|
2017-06-02 13:40:52 -04:00
|
|
|
model_form = forms.ProviderCSVForm
|
2016-05-18 16:35:35 -04:00
|
|
|
table = tables.ProviderTable
|
2017-01-23 14:07:26 -05:00
|
|
|
default_return_url = 'circuits:provider_list'
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2020-05-21 15:07:20 -04:00
|
|
|
class ProviderBulkEditView(BulkEditView):
|
2020-04-28 16:20:11 -04:00
|
|
|
queryset = Provider.objects.annotate(count_circuits=Count('circuits'))
|
2020-01-09 20:57:13 -05:00
|
|
|
filterset = filters.ProviderFilterSet
|
2017-07-13 16:31:47 -04:00
|
|
|
table = tables.ProviderTable
|
2016-05-18 15:17:58 -04:00
|
|
|
form = forms.ProviderBulkEditForm
|
2017-01-23 14:07:26 -05:00
|
|
|
default_return_url = 'circuits:provider_list'
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2020-05-21 15:14:29 -04:00
|
|
|
class ProviderBulkDeleteView(BulkDeleteView):
|
2020-04-28 16:20:11 -04:00
|
|
|
queryset = Provider.objects.annotate(count_circuits=Count('circuits'))
|
2020-01-09 20:57:13 -05:00
|
|
|
filterset = filters.ProviderFilterSet
|
2017-07-13 16:31:47 -04:00
|
|
|
table = tables.ProviderTable
|
2017-01-23 14:07:26 -05:00
|
|
|
default_return_url = 'circuits:provider_list'
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2016-05-13 12:44:03 -04:00
|
|
|
#
|
|
|
|
# Circuit Types
|
|
|
|
#
|
|
|
|
|
2020-05-21 13:22:09 -04:00
|
|
|
class CircuitTypeListView(ObjectListView):
|
2016-05-13 12:44:03 -04:00
|
|
|
queryset = CircuitType.objects.annotate(circuit_count=Count('circuits'))
|
2016-05-18 16:35:35 -04:00
|
|
|
table = tables.CircuitTypeTable
|
2016-05-13 12:44:03 -04:00
|
|
|
|
|
|
|
|
2020-05-21 13:59:19 -04:00
|
|
|
class CircuitTypeEditView(ObjectEditView):
|
2020-05-11 12:37:22 -04:00
|
|
|
queryset = CircuitType.objects.all()
|
2017-09-12 13:54:44 -04:00
|
|
|
model_form = forms.CircuitTypeForm
|
2018-07-02 11:54:41 -04:00
|
|
|
default_return_url = 'circuits:circuittype_list'
|
2016-05-13 12:44:03 -04:00
|
|
|
|
|
|
|
|
2020-05-21 14:43:27 -04:00
|
|
|
class CircuitTypeBulkImportView(BulkImportView):
|
2020-05-21 11:58:27 -04:00
|
|
|
queryset = CircuitType.objects.all()
|
2017-10-09 15:52:22 -04:00
|
|
|
model_form = forms.CircuitTypeCSVForm
|
|
|
|
table = tables.CircuitTypeTable
|
|
|
|
default_return_url = 'circuits:circuittype_list'
|
|
|
|
|
|
|
|
|
2020-05-21 15:14:29 -04:00
|
|
|
class CircuitTypeBulkDeleteView(BulkDeleteView):
|
2017-07-13 17:39:28 -04:00
|
|
|
queryset = CircuitType.objects.annotate(circuit_count=Count('circuits'))
|
2017-07-13 16:31:47 -04:00
|
|
|
table = tables.CircuitTypeTable
|
2017-01-23 14:07:26 -05:00
|
|
|
default_return_url = 'circuits:circuittype_list'
|
2016-05-13 12:44:03 -04:00
|
|
|
|
|
|
|
|
2016-03-01 11:23:03 -05:00
|
|
|
#
|
|
|
|
# Circuits
|
|
|
|
#
|
|
|
|
|
2020-05-21 13:22:09 -04:00
|
|
|
class CircuitListView(ObjectListView):
|
2019-06-27 12:30:17 -04:00
|
|
|
_terminations = CircuitTermination.objects.filter(circuit=OuterRef('pk'))
|
2019-08-19 01:53:39 -04:00
|
|
|
queryset = Circuit.objects.prefetch_related(
|
|
|
|
'provider', 'type', 'tenant', 'terminations__site'
|
2020-02-26 16:41:59 -05:00
|
|
|
).annotate_sites()
|
2020-01-09 20:57:13 -05:00
|
|
|
filterset = filters.CircuitFilterSet
|
|
|
|
filterset_form = forms.CircuitFilterForm
|
2016-05-18 16:35:35 -04:00
|
|
|
table = tables.CircuitTable
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2020-05-21 15:39:07 -04:00
|
|
|
class CircuitView(ObjectView):
|
|
|
|
queryset = Circuit.objects.prefetch_related('provider', 'type', 'tenant__group')
|
2017-05-18 17:00:57 -04:00
|
|
|
|
|
|
|
def get(self, request, pk):
|
2020-05-21 15:39:07 -04:00
|
|
|
circuit = get_object_or_404(self.queryset, pk=pk)
|
2020-06-16 14:00:43 -04:00
|
|
|
|
2020-06-01 11:43:49 -04:00
|
|
|
termination_a = CircuitTermination.objects.restrict(request.user, 'view').prefetch_related(
|
2018-10-30 12:16:22 -04:00
|
|
|
'site__region', 'connected_endpoint__device'
|
2017-05-18 17:00:57 -04:00
|
|
|
).filter(
|
2019-11-21 21:28:59 -05:00
|
|
|
circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_A
|
2017-05-18 17:00:57 -04:00
|
|
|
).first()
|
2020-06-16 14:00:43 -04:00
|
|
|
if termination_a and termination_a.connected_endpoint:
|
|
|
|
termination_a.ip_addresses = termination_a.connected_endpoint.ip_addresses.restrict(request.user, 'view')
|
|
|
|
|
2020-06-01 11:43:49 -04:00
|
|
|
termination_z = CircuitTermination.objects.restrict(request.user, 'view').prefetch_related(
|
2018-10-30 12:16:22 -04:00
|
|
|
'site__region', 'connected_endpoint__device'
|
2017-05-18 17:00:57 -04:00
|
|
|
).filter(
|
2019-11-21 21:28:59 -05:00
|
|
|
circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_Z
|
2017-05-18 17:00:57 -04:00
|
|
|
).first()
|
2020-06-16 14:00:43 -04:00
|
|
|
if termination_z and termination_z.connected_endpoint:
|
|
|
|
termination_z.ip_addresses = termination_z.connected_endpoint.ip_addresses.restrict(request.user, 'view')
|
2017-05-18 17:00:57 -04:00
|
|
|
|
|
|
|
return render(request, 'circuits/circuit.html', {
|
|
|
|
'circuit': circuit,
|
|
|
|
'termination_a': termination_a,
|
|
|
|
'termination_z': termination_z,
|
|
|
|
})
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2020-05-21 13:59:19 -04:00
|
|
|
class CircuitEditView(ObjectEditView):
|
2020-05-11 12:37:22 -04:00
|
|
|
queryset = Circuit.objects.all()
|
2017-09-12 13:54:44 -04:00
|
|
|
model_form = forms.CircuitForm
|
2016-05-03 15:46:30 -04:00
|
|
|
template_name = 'circuits/circuit_edit.html'
|
2017-01-23 14:07:26 -05:00
|
|
|
default_return_url = 'circuits:circuit_list'
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2020-05-21 14:34:40 -04:00
|
|
|
class CircuitDeleteView(ObjectDeleteView):
|
2020-05-11 12:47:01 -04:00
|
|
|
queryset = Circuit.objects.all()
|
2017-01-18 13:30:19 -05:00
|
|
|
default_return_url = 'circuits:circuit_list'
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2020-05-21 14:43:27 -04:00
|
|
|
class CircuitBulkImportView(BulkImportView):
|
2020-05-21 11:58:27 -04:00
|
|
|
queryset = Circuit.objects.all()
|
2017-06-02 13:40:52 -04:00
|
|
|
model_form = forms.CircuitCSVForm
|
2016-05-18 16:35:35 -04:00
|
|
|
table = tables.CircuitTable
|
2017-01-23 14:07:26 -05:00
|
|
|
default_return_url = 'circuits:circuit_list'
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2020-05-21 15:07:20 -04:00
|
|
|
class CircuitBulkEditView(BulkEditView):
|
2019-08-19 01:53:39 -04:00
|
|
|
queryset = Circuit.objects.prefetch_related('provider', 'type', 'tenant').prefetch_related('terminations__site')
|
2020-01-09 20:57:13 -05:00
|
|
|
filterset = filters.CircuitFilterSet
|
2017-07-13 16:31:47 -04:00
|
|
|
table = tables.CircuitTable
|
2016-05-18 15:17:58 -04:00
|
|
|
form = forms.CircuitBulkEditForm
|
2017-01-23 14:07:26 -05:00
|
|
|
default_return_url = 'circuits:circuit_list'
|
2016-03-01 11:23:03 -05:00
|
|
|
|
|
|
|
|
2020-05-21 15:14:29 -04:00
|
|
|
class CircuitBulkDeleteView(BulkDeleteView):
|
2019-08-19 01:53:39 -04:00
|
|
|
queryset = Circuit.objects.prefetch_related('provider', 'type', 'tenant').prefetch_related('terminations__site')
|
2020-01-09 20:57:13 -05:00
|
|
|
filterset = filters.CircuitFilterSet
|
2017-07-13 16:31:47 -04:00
|
|
|
table = tables.CircuitTable
|
2017-01-23 14:07:26 -05:00
|
|
|
default_return_url = 'circuits:circuit_list'
|
2016-12-14 13:47:22 -05:00
|
|
|
|
|
|
|
|
2020-05-22 09:45:29 -04:00
|
|
|
class CircuitSwapTerminations(ObjectEditView):
|
|
|
|
"""
|
|
|
|
Swap the A and Z terminations of a circuit.
|
|
|
|
"""
|
|
|
|
queryset = Circuit.objects.all()
|
|
|
|
|
|
|
|
def get(self, request, pk):
|
|
|
|
circuit = get_object_or_404(self.queryset, pk=pk)
|
|
|
|
form = ConfirmationForm()
|
2016-12-14 13:47:22 -05:00
|
|
|
|
2020-05-22 09:45:29 -04:00
|
|
|
# Circuit must have at least one termination to swap
|
|
|
|
if not circuit.termination_a and not circuit.termination_z:
|
|
|
|
messages.error(request, "No terminations have been defined for circuit {}.".format(circuit))
|
|
|
|
return redirect('circuits:circuit', pk=circuit.pk)
|
|
|
|
|
|
|
|
return render(request, 'circuits/circuit_terminations_swap.html', {
|
|
|
|
'circuit': circuit,
|
|
|
|
'termination_a': circuit.termination_a,
|
|
|
|
'termination_z': circuit.termination_z,
|
|
|
|
'form': form,
|
|
|
|
'panel_class': 'default',
|
|
|
|
'button_class': 'primary',
|
|
|
|
'return_url': circuit.get_absolute_url(),
|
|
|
|
})
|
2016-12-14 13:47:22 -05:00
|
|
|
|
2020-05-22 09:45:29 -04:00
|
|
|
def post(self, request, pk):
|
|
|
|
circuit = get_object_or_404(self.queryset, pk=pk)
|
2016-12-14 13:47:22 -05:00
|
|
|
form = ConfirmationForm(request.POST)
|
2020-05-22 09:45:29 -04:00
|
|
|
|
2016-12-14 13:47:22 -05:00
|
|
|
if form.is_valid():
|
2020-05-22 09:45:29 -04:00
|
|
|
|
|
|
|
termination_a = CircuitTermination.objects.filter(
|
|
|
|
circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_A
|
|
|
|
).first()
|
|
|
|
termination_z = CircuitTermination.objects.filter(
|
|
|
|
circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_Z
|
|
|
|
).first()
|
|
|
|
|
2016-12-14 13:47:22 -05:00
|
|
|
if termination_a and termination_z:
|
|
|
|
# Use a placeholder to avoid an IntegrityError on the (circuit, term_side) unique constraint
|
2020-05-22 09:45:29 -04:00
|
|
|
print('swapping')
|
2016-12-14 13:47:22 -05:00
|
|
|
with transaction.atomic():
|
|
|
|
termination_a.term_side = '_'
|
|
|
|
termination_a.save()
|
|
|
|
termination_z.term_side = 'A'
|
|
|
|
termination_z.save()
|
|
|
|
termination_a.term_side = 'Z'
|
|
|
|
termination_a.save()
|
|
|
|
elif termination_a:
|
|
|
|
termination_a.term_side = 'Z'
|
|
|
|
termination_a.save()
|
|
|
|
else:
|
|
|
|
termination_z.term_side = 'A'
|
|
|
|
termination_z.save()
|
2020-05-22 09:45:29 -04:00
|
|
|
|
2016-12-14 13:47:22 -05:00
|
|
|
messages.success(request, "Swapped terminations for circuit {}.".format(circuit))
|
|
|
|
return redirect('circuits:circuit', pk=circuit.pk)
|
|
|
|
|
2020-05-22 09:45:29 -04:00
|
|
|
return render(request, 'circuits/circuit_terminations_swap.html', {
|
|
|
|
'circuit': circuit,
|
|
|
|
'termination_a': circuit.termination_a,
|
|
|
|
'termination_z': circuit.termination_z,
|
|
|
|
'form': form,
|
|
|
|
'panel_class': 'default',
|
|
|
|
'button_class': 'primary',
|
|
|
|
'return_url': circuit.get_absolute_url(),
|
|
|
|
})
|
2016-12-14 13:47:22 -05:00
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# Circuit terminations
|
|
|
|
#
|
|
|
|
|
2020-05-21 13:59:19 -04:00
|
|
|
class CircuitTerminationEditView(ObjectEditView):
|
2020-05-11 12:37:22 -04:00
|
|
|
queryset = CircuitTermination.objects.all()
|
2017-09-12 13:54:44 -04:00
|
|
|
model_form = forms.CircuitTerminationForm
|
2016-12-14 13:47:22 -05:00
|
|
|
template_name = 'circuits/circuittermination_edit.html'
|
|
|
|
|
2017-02-15 15:03:31 -05:00
|
|
|
def alter_obj(self, obj, request, url_args, url_kwargs):
|
|
|
|
if 'circuit' in url_kwargs:
|
|
|
|
obj.circuit = get_object_or_404(Circuit, pk=url_kwargs['circuit'])
|
2016-12-14 13:47:22 -05:00
|
|
|
return obj
|
|
|
|
|
2017-04-13 13:11:23 -04:00
|
|
|
def get_return_url(self, request, obj):
|
2017-01-18 14:07:46 -05:00
|
|
|
return obj.circuit.get_absolute_url()
|
|
|
|
|
2016-12-14 13:47:22 -05:00
|
|
|
|
2020-05-21 14:34:40 -04:00
|
|
|
class CircuitTerminationDeleteView(ObjectDeleteView):
|
2020-05-11 12:47:01 -04:00
|
|
|
queryset = CircuitTermination.objects.all()
|