Browse Source

Added CBVs for RIRs

Jeremy Stretch 9 years ago
parent
commit
e1a0b8fee6

+ 15 - 0
netbox/ipam/forms.py

@@ -46,6 +46,21 @@ class VRFBulkDeleteForm(ConfirmationForm):
 
 
 #
+# 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
 #
 

+ 3 - 0
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):
     """

+ 25 - 1
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 %}<a href="{% url 'ipam:rir_edit' slug=record.slug %}">Edit</a>{% endif %}
+"""
+
 UTILIZATION_GRAPH = """
 {% with record.get_utilization as percentage %}
 <div class="progress text-center">
@@ -60,6 +64,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
 #
 

+ 13 - 0
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<pk>\d+)/edit/$', views.VRFEditView.as_view(), name='vrf_edit'),
     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/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<pk>\d+)/edit/$', views.AggregateEditView.as_view(), name='aggregate_edit'),
     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/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<pk>\d+)/delete/$', views.PrefixDeleteView.as_view(), name='prefix_delete'),
     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/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<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'),
 
+    # 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<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+)/delete/$', views.VLANDeleteView.as_view(), name='vlan_delete'),
+
 ]

+ 32 - 5
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):
@@ -108,6 +109,32 @@ class VRFBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 
 
 #
+# 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
 #
 

+ 6 - 1
netbox/templates/_base.html

@@ -101,7 +101,7 @@
                             {% endif %}
                         </ul>
                     </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>
                         <ul class="dropdown-menu">
                             <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_import' %}"><i class="glyphicon glyphicon-import" aria-hidden="true"></i> Import VRFs</a></li>
                             {% 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>
                     </li>
                     <li class="dropdown{% if '/vlans/' in request.path %} active{% endif %}">

+ 14 - 0
netbox/templates/ipam/inc/rir_table.html

@@ -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 - 0
netbox/templates/ipam/rir_list.html

@@ -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 %}