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
 # Aggregates
 #
 #
 
 

+ 3 - 0
netbox/ipam/models.py

@@ -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):
     """
     """

+ 25 - 1
netbox/ipam/tables.py

@@ -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">
@@ -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
 # Aggregates
 #
 #
 
 

+ 13 - 0
netbox/ipam/urls.py

@@ -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'),
+
 ]
 ]

+ 32 - 5
netbox/ipam/views.py

@@ -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
-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):
 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
 # Aggregates
 #
 #
 
 

+ 6 - 1
netbox/templates/_base.html

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