diff --git a/netbox/ipam/forms.py b/netbox/ipam/forms.py index 483ed7221..db8ff7a85 100644 --- a/netbox/ipam/forms.py +++ b/netbox/ipam/forms.py @@ -45,6 +45,21 @@ class VRFBulkDeleteForm(ConfirmationForm): 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 # diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index 35c8e702b..b00f16104 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -91,6 +91,9 @@ class RIR(models.Model): def __unicode__(self): return self.name + def get_absolute_url(self): + return "{}?rir={}".format(reverse('ipam:aggregate_list'), self.slug) + class Aggregate(models.Model): """ diff --git a/netbox/ipam/tables.py b/netbox/ipam/tables.py index bb5418f54..adf8617b2 100644 --- a/netbox/ipam/tables.py +++ b/netbox/ipam/tables.py @@ -1,9 +1,13 @@ import django_tables2 as tables 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 %}Edit{% endif %} +""" + UTILIZATION_GRAPH = """ {% with record.get_utilization as percentage %}
@@ -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 # diff --git a/netbox/ipam/urls.py b/netbox/ipam/urls.py index a97ee030a..97d7d7543 100644 --- a/netbox/ipam/urls.py +++ b/netbox/ipam/urls.py @@ -3,6 +3,8 @@ from django.conf.urls import url from . import views urlpatterns = [ + + # VRFs url(r'^vrfs/$', views.VRFListView.as_view(), name='vrf_list'), url(r'^vrfs/add/$', views.VRFEditView.as_view(), name='vrf_add'), url(r'^vrfs/import/$', views.VRFBulkImportView.as_view(), name='vrf_import'), @@ -12,6 +14,13 @@ urlpatterns = [ url(r'^vrfs/(?P\d+)/edit/$', views.VRFEditView.as_view(), name='vrf_edit'), url(r'^vrfs/(?P\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[\w-]+)/edit/$', views.RIREditView.as_view(), name='rir_edit'), + + # Aggregates url(r'^aggregates/$', views.AggregateListView.as_view(), name='aggregate_list'), url(r'^aggregates/add/$', views.AggregateEditView.as_view(), name='aggregate_add'), url(r'^aggregates/import/$', views.AggregateBulkImportView.as_view(), name='aggregate_import'), @@ -21,6 +30,7 @@ urlpatterns = [ url(r'^aggregates/(?P\d+)/edit/$', views.AggregateEditView.as_view(), name='aggregate_edit'), url(r'^aggregates/(?P\d+)/delete/$', views.AggregateDeleteView.as_view(), name='aggregate_delete'), + # Prefixes url(r'^prefixes/$', views.PrefixListView.as_view(), name='prefix_list'), url(r'^prefixes/add/$', views.PrefixEditView.as_view(), name='prefix_add'), url(r'^prefixes/import/$', views.PrefixBulkImportView.as_view(), name='prefix_import'), @@ -31,6 +41,7 @@ urlpatterns = [ url(r'^prefixes/(?P\d+)/delete/$', views.PrefixDeleteView.as_view(), name='prefix_delete'), url(r'^prefixes/(?P\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/add/$', views.IPAddressEditView.as_view(), name='ipaddress_add'), url(r'^ip-addresses/import/$', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'), @@ -40,6 +51,7 @@ urlpatterns = [ url(r'^ip-addresses/(?P\d+)/edit/$', views.IPAddressEditView.as_view(), name='ipaddress_edit'), url(r'^ip-addresses/(?P\d+)/delete/$', views.IPAddressDeleteView.as_view(), name='ipaddress_delete'), + # VLANs url(r'^vlans/$', views.VLANListView.as_view(), name='vlan_list'), url(r'^vlans/add/$', views.VLANEditView.as_view(), name='vlan_add'), url(r'^vlans/import/$', views.VLANBulkImportView.as_view(), name='vlan_import'), @@ -48,4 +60,5 @@ urlpatterns = [ url(r'^vlans/(?P\d+)/$', views.vlan, name='vlan'), url(r'^vlans/(?P\d+)/edit/$', views.VLANEditView.as_view(), name='vlan_edit'), url(r'^vlans/(?P\d+)/delete/$', views.VLANDeleteView.as_view(), name='vlan_delete'), + ] diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index e5be9ed37..9a0f53414 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -1,9 +1,10 @@ from netaddr import IPSet - from django_tables2 import RequestConfig + from django.conf import settings from django.contrib import messages from django.contrib.auth.mixins import PermissionRequiredMixin +from django.db.models import Count from django.shortcuts import get_object_or_404, render from dcim.models import Device @@ -16,10 +17,10 @@ from .forms import AggregateForm, AggregateImportForm, AggregateBulkEditForm, Ag AggregateFilterForm, PrefixForm, PrefixImportForm, PrefixBulkEditForm, PrefixBulkDeleteForm, PrefixFilterForm,\ IPAddressForm, IPAddressImportForm, IPAddressBulkEditForm, IPAddressBulkDeleteForm, IPAddressFilterForm, VLANForm,\ VLANImportForm, VLANBulkEditForm, VLANBulkDeleteForm, VRFForm, VRFImportForm, VRFBulkEditForm, VRFBulkDeleteForm,\ - VLANFilterForm -from .models import VRF, Aggregate, Prefix, IPAddress, VLAN -from .tables import AggregateTable, PrefixTable, PrefixBriefTable, IPAddressBriefTable, IPAddressTable, VLANTable,\ - VRFTable + VLANFilterForm, RIRForm, RIRBulkDeleteForm +from .models import VRF, RIR, Aggregate, Prefix, IPAddress, VLAN +from .tables import VRFTable, RIRTable, AggregateTable, PrefixTable, PrefixBriefTable, IPAddressBriefTable,\ + IPAddressTable, VLANTable def add_available_prefixes(parent, prefix_list): @@ -107,6 +108,32 @@ class VRFBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): 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 # diff --git a/netbox/templates/_base.html b/netbox/templates/_base.html index 46652e63c..c37f8dcce 100644 --- a/netbox/templates/_base.html +++ b/netbox/templates/_base.html @@ -101,7 +101,7 @@ {% endif %} -