mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Added CBVs for RIRs
This commit is contained in:
@ -45,6 +45,21 @@ class VRFBulkDeleteForm(ConfirmationForm):
|
|||||||
pk = forms.ModelMultipleChoiceField(queryset=VRF.objects.all(), widget=forms.MultipleHiddenInput)
|
pk = forms.ModelMultipleChoiceField(queryset=VRF.objects.all(), widget=forms.MultipleHiddenInput)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# RIRs
|
||||||
|
#
|
||||||
|
|
||||||
|
class RIRForm(forms.ModelForm, BootstrapMixin):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = RIR
|
||||||
|
fields = ['name', 'slug']
|
||||||
|
|
||||||
|
|
||||||
|
class RIRBulkDeleteForm(ConfirmationForm):
|
||||||
|
pk = forms.ModelMultipleChoiceField(queryset=RIR.objects.all(), widget=forms.MultipleHiddenInput)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Aggregates
|
# Aggregates
|
||||||
#
|
#
|
||||||
|
@ -91,6 +91,9 @@ class RIR(models.Model):
|
|||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return "{}?rir={}".format(reverse('ipam:aggregate_list'), self.slug)
|
||||||
|
|
||||||
|
|
||||||
class Aggregate(models.Model):
|
class Aggregate(models.Model):
|
||||||
"""
|
"""
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
from django_tables2.utils import Accessor
|
from django_tables2.utils import Accessor
|
||||||
|
|
||||||
from .models import Aggregate, Prefix, IPAddress, VLAN, VRF
|
from .models import VRF, RIR, Aggregate, Prefix, IPAddress, VLAN
|
||||||
|
|
||||||
|
|
||||||
|
RIR_EDIT_LINK = """
|
||||||
|
{% if perms.ipam.change_rir %}<a href="{% url 'ipam:rir_edit' slug=record.slug %}">Edit</a>{% endif %}
|
||||||
|
"""
|
||||||
|
|
||||||
UTILIZATION_GRAPH = """
|
UTILIZATION_GRAPH = """
|
||||||
{% with record.get_utilization as percentage %}
|
{% with record.get_utilization as percentage %}
|
||||||
<div class="progress text-center">
|
<div class="progress text-center">
|
||||||
@ -59,6 +63,26 @@ class VRFTable(tables.Table):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# RIRs
|
||||||
|
#
|
||||||
|
|
||||||
|
class RIRTable(tables.Table):
|
||||||
|
pk = tables.CheckBoxColumn(visible=False, default='')
|
||||||
|
name = tables.LinkColumn(verbose_name='Name')
|
||||||
|
aggregate_count = tables.Column(verbose_name='Aggregates')
|
||||||
|
slug = tables.Column(verbose_name='Slug')
|
||||||
|
edit = tables.TemplateColumn(template_code=RIR_EDIT_LINK, verbose_name='')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = RIR
|
||||||
|
fields = ('pk', 'name', 'aggregate_count', 'slug', 'edit')
|
||||||
|
empty_text = "No aggregates were found."
|
||||||
|
attrs = {
|
||||||
|
'class': 'table table-hover',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Aggregates
|
# Aggregates
|
||||||
#
|
#
|
||||||
|
@ -3,6 +3,8 @@ from django.conf.urls import url
|
|||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
|
||||||
|
# VRFs
|
||||||
url(r'^vrfs/$', views.VRFListView.as_view(), name='vrf_list'),
|
url(r'^vrfs/$', views.VRFListView.as_view(), name='vrf_list'),
|
||||||
url(r'^vrfs/add/$', views.VRFEditView.as_view(), name='vrf_add'),
|
url(r'^vrfs/add/$', views.VRFEditView.as_view(), name='vrf_add'),
|
||||||
url(r'^vrfs/import/$', views.VRFBulkImportView.as_view(), name='vrf_import'),
|
url(r'^vrfs/import/$', views.VRFBulkImportView.as_view(), name='vrf_import'),
|
||||||
@ -12,6 +14,13 @@ urlpatterns = [
|
|||||||
url(r'^vrfs/(?P<pk>\d+)/edit/$', views.VRFEditView.as_view(), name='vrf_edit'),
|
url(r'^vrfs/(?P<pk>\d+)/edit/$', views.VRFEditView.as_view(), name='vrf_edit'),
|
||||||
url(r'^vrfs/(?P<pk>\d+)/delete/$', views.VRFDeleteView.as_view(), name='vrf_delete'),
|
url(r'^vrfs/(?P<pk>\d+)/delete/$', views.VRFDeleteView.as_view(), name='vrf_delete'),
|
||||||
|
|
||||||
|
# RIRs
|
||||||
|
url(r'^rirs/$', views.RIRListView.as_view(), name='rir_list'),
|
||||||
|
url(r'^rirs/add/$', views.RIREditView.as_view(), name='rir_add'),
|
||||||
|
url(r'^rirs/delete/$', views.RIRBulkDeleteView.as_view(), name='rir_bulk_delete'),
|
||||||
|
url(r'^rirs/(?P<slug>[\w-]+)/edit/$', views.RIREditView.as_view(), name='rir_edit'),
|
||||||
|
|
||||||
|
# Aggregates
|
||||||
url(r'^aggregates/$', views.AggregateListView.as_view(), name='aggregate_list'),
|
url(r'^aggregates/$', views.AggregateListView.as_view(), name='aggregate_list'),
|
||||||
url(r'^aggregates/add/$', views.AggregateEditView.as_view(), name='aggregate_add'),
|
url(r'^aggregates/add/$', views.AggregateEditView.as_view(), name='aggregate_add'),
|
||||||
url(r'^aggregates/import/$', views.AggregateBulkImportView.as_view(), name='aggregate_import'),
|
url(r'^aggregates/import/$', views.AggregateBulkImportView.as_view(), name='aggregate_import'),
|
||||||
@ -21,6 +30,7 @@ urlpatterns = [
|
|||||||
url(r'^aggregates/(?P<pk>\d+)/edit/$', views.AggregateEditView.as_view(), name='aggregate_edit'),
|
url(r'^aggregates/(?P<pk>\d+)/edit/$', views.AggregateEditView.as_view(), name='aggregate_edit'),
|
||||||
url(r'^aggregates/(?P<pk>\d+)/delete/$', views.AggregateDeleteView.as_view(), name='aggregate_delete'),
|
url(r'^aggregates/(?P<pk>\d+)/delete/$', views.AggregateDeleteView.as_view(), name='aggregate_delete'),
|
||||||
|
|
||||||
|
# Prefixes
|
||||||
url(r'^prefixes/$', views.PrefixListView.as_view(), name='prefix_list'),
|
url(r'^prefixes/$', views.PrefixListView.as_view(), name='prefix_list'),
|
||||||
url(r'^prefixes/add/$', views.PrefixEditView.as_view(), name='prefix_add'),
|
url(r'^prefixes/add/$', views.PrefixEditView.as_view(), name='prefix_add'),
|
||||||
url(r'^prefixes/import/$', views.PrefixBulkImportView.as_view(), name='prefix_import'),
|
url(r'^prefixes/import/$', views.PrefixBulkImportView.as_view(), name='prefix_import'),
|
||||||
@ -31,6 +41,7 @@ urlpatterns = [
|
|||||||
url(r'^prefixes/(?P<pk>\d+)/delete/$', views.PrefixDeleteView.as_view(), name='prefix_delete'),
|
url(r'^prefixes/(?P<pk>\d+)/delete/$', views.PrefixDeleteView.as_view(), name='prefix_delete'),
|
||||||
url(r'^prefixes/(?P<pk>\d+)/ip-addresses/$', views.prefix_ipaddresses, name='prefix_ipaddresses'),
|
url(r'^prefixes/(?P<pk>\d+)/ip-addresses/$', views.prefix_ipaddresses, name='prefix_ipaddresses'),
|
||||||
|
|
||||||
|
# IP addresses
|
||||||
url(r'^ip-addresses/$', views.IPAddressListView.as_view(), name='ipaddress_list'),
|
url(r'^ip-addresses/$', views.IPAddressListView.as_view(), name='ipaddress_list'),
|
||||||
url(r'^ip-addresses/add/$', views.IPAddressEditView.as_view(), name='ipaddress_add'),
|
url(r'^ip-addresses/add/$', views.IPAddressEditView.as_view(), name='ipaddress_add'),
|
||||||
url(r'^ip-addresses/import/$', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'),
|
url(r'^ip-addresses/import/$', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'),
|
||||||
@ -40,6 +51,7 @@ urlpatterns = [
|
|||||||
url(r'^ip-addresses/(?P<pk>\d+)/edit/$', views.IPAddressEditView.as_view(), name='ipaddress_edit'),
|
url(r'^ip-addresses/(?P<pk>\d+)/edit/$', views.IPAddressEditView.as_view(), name='ipaddress_edit'),
|
||||||
url(r'^ip-addresses/(?P<pk>\d+)/delete/$', views.IPAddressDeleteView.as_view(), name='ipaddress_delete'),
|
url(r'^ip-addresses/(?P<pk>\d+)/delete/$', views.IPAddressDeleteView.as_view(), name='ipaddress_delete'),
|
||||||
|
|
||||||
|
# VLANs
|
||||||
url(r'^vlans/$', views.VLANListView.as_view(), name='vlan_list'),
|
url(r'^vlans/$', views.VLANListView.as_view(), name='vlan_list'),
|
||||||
url(r'^vlans/add/$', views.VLANEditView.as_view(), name='vlan_add'),
|
url(r'^vlans/add/$', views.VLANEditView.as_view(), name='vlan_add'),
|
||||||
url(r'^vlans/import/$', views.VLANBulkImportView.as_view(), name='vlan_import'),
|
url(r'^vlans/import/$', views.VLANBulkImportView.as_view(), name='vlan_import'),
|
||||||
@ -48,4 +60,5 @@ urlpatterns = [
|
|||||||
url(r'^vlans/(?P<pk>\d+)/$', views.vlan, name='vlan'),
|
url(r'^vlans/(?P<pk>\d+)/$', views.vlan, name='vlan'),
|
||||||
url(r'^vlans/(?P<pk>\d+)/edit/$', views.VLANEditView.as_view(), name='vlan_edit'),
|
url(r'^vlans/(?P<pk>\d+)/edit/$', views.VLANEditView.as_view(), name='vlan_edit'),
|
||||||
url(r'^vlans/(?P<pk>\d+)/delete/$', views.VLANDeleteView.as_view(), name='vlan_delete'),
|
url(r'^vlans/(?P<pk>\d+)/delete/$', views.VLANDeleteView.as_view(), name='vlan_delete'),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
from netaddr import IPSet
|
from netaddr import IPSet
|
||||||
|
|
||||||
from django_tables2 import RequestConfig
|
from django_tables2 import RequestConfig
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||||
|
from django.db.models import Count
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
|
|
||||||
from dcim.models import Device
|
from dcim.models import Device
|
||||||
@ -16,10 +17,10 @@ from .forms import AggregateForm, AggregateImportForm, AggregateBulkEditForm, Ag
|
|||||||
AggregateFilterForm, PrefixForm, PrefixImportForm, PrefixBulkEditForm, PrefixBulkDeleteForm, PrefixFilterForm,\
|
AggregateFilterForm, PrefixForm, PrefixImportForm, PrefixBulkEditForm, PrefixBulkDeleteForm, PrefixFilterForm,\
|
||||||
IPAddressForm, IPAddressImportForm, IPAddressBulkEditForm, IPAddressBulkDeleteForm, IPAddressFilterForm, VLANForm,\
|
IPAddressForm, IPAddressImportForm, IPAddressBulkEditForm, IPAddressBulkDeleteForm, IPAddressFilterForm, VLANForm,\
|
||||||
VLANImportForm, VLANBulkEditForm, VLANBulkDeleteForm, VRFForm, VRFImportForm, VRFBulkEditForm, VRFBulkDeleteForm,\
|
VLANImportForm, VLANBulkEditForm, VLANBulkDeleteForm, VRFForm, VRFImportForm, VRFBulkEditForm, VRFBulkDeleteForm,\
|
||||||
VLANFilterForm
|
VLANFilterForm, RIRForm, RIRBulkDeleteForm
|
||||||
from .models import VRF, Aggregate, Prefix, IPAddress, VLAN
|
from .models import VRF, RIR, Aggregate, Prefix, IPAddress, VLAN
|
||||||
from .tables import AggregateTable, PrefixTable, PrefixBriefTable, IPAddressBriefTable, IPAddressTable, VLANTable,\
|
from .tables import VRFTable, RIRTable, AggregateTable, PrefixTable, PrefixBriefTable, IPAddressBriefTable,\
|
||||||
VRFTable
|
IPAddressTable, VLANTable
|
||||||
|
|
||||||
|
|
||||||
def add_available_prefixes(parent, prefix_list):
|
def add_available_prefixes(parent, prefix_list):
|
||||||
@ -107,6 +108,32 @@ class VRFBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
default_redirect_url = 'ipam:vrf_list'
|
default_redirect_url = 'ipam:vrf_list'
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# RIRs
|
||||||
|
#
|
||||||
|
|
||||||
|
class RIRListView(ObjectListView):
|
||||||
|
queryset = RIR.objects.annotate(aggregate_count=Count('aggregates'))
|
||||||
|
table = RIRTable
|
||||||
|
edit_permissions = ['ipam.change_rir', 'ipam.delete_rir']
|
||||||
|
template_name = 'ipam/rir_list.html'
|
||||||
|
|
||||||
|
|
||||||
|
class RIREditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
|
permission_required = 'ipam.change_rir'
|
||||||
|
model = RIR
|
||||||
|
form_class = RIRForm
|
||||||
|
success_url = 'ipam:rir_list'
|
||||||
|
cancel_url = 'ipam:rir_list'
|
||||||
|
|
||||||
|
|
||||||
|
class RIRBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
|
permission_required = 'ipam.delete_rir'
|
||||||
|
cls = RIR
|
||||||
|
form = RIRBulkDeleteForm
|
||||||
|
default_redirect_url = 'ipam:rir_list'
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Aggregates
|
# Aggregates
|
||||||
#
|
#
|
||||||
|
@ -101,7 +101,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown{% if '/ipam/ip-addresses/' in request.path or '/prefixes/' in request.path or '/aggregates/' in request.path %} active{% endif %}">
|
<li class="dropdown{% if '/ipam/ip-addresses/' in request.path or '/prefixes/' in request.path or '/aggregates/' in request.path or '/vrfs/' in request.path or '/rirs/' in request.path %} active{% endif %}">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">IP Space <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">IP Space <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="{% url 'ipam:ipaddress_list' %}"><i class="glyphicon glyphicon-search" aria-hidden="true"></i> IP Addresses</a></li>
|
<li><a href="{% url 'ipam:ipaddress_list' %}"><i class="glyphicon glyphicon-search" aria-hidden="true"></i> IP Addresses</a></li>
|
||||||
@ -133,6 +133,11 @@
|
|||||||
<li><a href="{% url 'ipam:vrf_add' %}"><i class="glyphicon glyphicon-plus" aria-hidden="true"></i> Add a VRF</a></li>
|
<li><a href="{% url 'ipam:vrf_add' %}"><i class="glyphicon glyphicon-plus" aria-hidden="true"></i> Add a VRF</a></li>
|
||||||
<li><a href="{% url 'ipam:vrf_import' %}"><i class="glyphicon glyphicon-import" aria-hidden="true"></i> Import VRFs</a></li>
|
<li><a href="{% url 'ipam:vrf_import' %}"><i class="glyphicon glyphicon-import" aria-hidden="true"></i> Import VRFs</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<li class="divider"></li>
|
||||||
|
<li><a href="{% url 'ipam:rir_list' %}"><i class="glyphicon glyphicon-search" aria-hidden="true"></i> RIRs</a></li>
|
||||||
|
{% if perms.ipam.add_rir %}
|
||||||
|
<li><a href="{% url 'ipam:rir_add' %}"><i class="glyphicon glyphicon-plus" aria-hidden="true"></i> Add a RIR</a></li>
|
||||||
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown{% if '/vlans/' in request.path %} active{% endif %}">
|
<li class="dropdown{% if '/vlans/' in request.path %} active{% endif %}">
|
||||||
|
14
netbox/templates/ipam/inc/rir_table.html
Normal file
14
netbox/templates/ipam/inc/rir_table.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{% load render_table from django_tables2 %}
|
||||||
|
{% if perms.ipam.delete_rir %}
|
||||||
|
<form method="post" class="form form-horizontal">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
|
||||||
|
{% render_table table table_template|default:'table.html' %}
|
||||||
|
<button type="submit" name="_delete" formaction="{% url 'ipam:rir_bulk_delete' %}" class="btn btn-danger btn-sm">
|
||||||
|
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
|
||||||
|
Delete Selected
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
{% render_table table table_template|default:'table.html' %}
|
||||||
|
{% endif %}
|
21
netbox/templates/ipam/rir_list.html
Normal file
21
netbox/templates/ipam/rir_list.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{% extends '_base.html' %}
|
||||||
|
{% load helpers %}
|
||||||
|
|
||||||
|
{% block title %}RIRs{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="pull-right">
|
||||||
|
{% if perms.dcim.add_devicerole %}
|
||||||
|
<a href="{% url 'ipam:rir_add' %}" class="btn btn-primary">
|
||||||
|
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
||||||
|
Add a RIR
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<h1>RIRs</h1>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
{% include 'ipam/inc/rir_table.html' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
Reference in New Issue
Block a user