mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-21 03:27:21 -06:00
Closes #1512: Added a view to search for an IP address being assigned to an interface
This commit is contained in:
parent
e1d655cb23
commit
a0bb7b08bd
@ -688,6 +688,11 @@ class IPAddressBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
||||
nullable_fields = ['vrf', 'role', 'tenant', 'description']
|
||||
|
||||
|
||||
class IPAddressAssignForm(BootstrapMixin, forms.Form):
|
||||
vrf = forms.ModelChoiceField(queryset=VRF.objects.all(), required=False, label='VRF')
|
||||
address = forms.CharField(label='IP Address')
|
||||
|
||||
|
||||
def ipaddress_status_choices():
|
||||
status_counts = {}
|
||||
for status in IPAddress.objects.values('status').annotate(count=Count('status')).order_by('status'):
|
||||
|
@ -76,6 +76,10 @@ IPADDRESS_LINK = """
|
||||
{% endif %}
|
||||
"""
|
||||
|
||||
IPADDRESS_ASSIGN_LINK = """
|
||||
<a href="{% url 'ipam:ipaddress_edit' pk=record.pk %}?interface={{ request.GET.interface }}&return_url={{ request.GET.return_url }}">{{ record }}</a>
|
||||
"""
|
||||
|
||||
IPADDRESS_PARENT = """
|
||||
{% if record.interface %}
|
||||
<a href="{{ record.interface.parent.get_absolute_url }}">{{ record.interface.parent }}</a>
|
||||
@ -268,8 +272,8 @@ class PrefixDetailTable(PrefixTable):
|
||||
class IPAddressTable(BaseTable):
|
||||
pk = ToggleColumn()
|
||||
address = tables.TemplateColumn(IPADDRESS_LINK, verbose_name='IP Address')
|
||||
status = tables.TemplateColumn(STATUS_LABEL)
|
||||
vrf = tables.TemplateColumn(VRF_LINK, verbose_name='VRF')
|
||||
status = tables.TemplateColumn(STATUS_LABEL)
|
||||
tenant = tables.TemplateColumn(TENANT_LINK)
|
||||
parent = tables.TemplateColumn(IPADDRESS_PARENT, orderable=False)
|
||||
interface = tables.Column(orderable=False)
|
||||
@ -293,6 +297,18 @@ class IPAddressDetailTable(IPAddressTable):
|
||||
)
|
||||
|
||||
|
||||
class IPAddressAssignTable(BaseTable):
|
||||
address = tables.TemplateColumn(IPADDRESS_ASSIGN_LINK, verbose_name='IP Address')
|
||||
status = tables.TemplateColumn(STATUS_LABEL)
|
||||
parent = tables.TemplateColumn(IPADDRESS_PARENT, orderable=False)
|
||||
interface = tables.Column(orderable=False)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = IPAddress
|
||||
fields = ('address', 'vrf', 'status', 'role', 'tenant', 'parent', 'interface')
|
||||
orderable = False
|
||||
|
||||
|
||||
#
|
||||
# VLAN groups
|
||||
#
|
||||
|
@ -60,6 +60,7 @@ urlpatterns = [
|
||||
url(r'^ip-addresses/import/$', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'),
|
||||
url(r'^ip-addresses/edit/$', views.IPAddressBulkEditView.as_view(), name='ipaddress_bulk_edit'),
|
||||
url(r'^ip-addresses/delete/$', views.IPAddressBulkDeleteView.as_view(), name='ipaddress_bulk_delete'),
|
||||
url(r'^ip-addresses/assign/$', views.IPAddressAssignView.as_view(), name='ipaddress_assign'),
|
||||
url(r'^ip-addresses/(?P<pk>\d+)/$', views.IPAddressView.as_view(), name='ipaddress'),
|
||||
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'),
|
||||
|
@ -4,7 +4,7 @@ import netaddr
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
from django.db.models import Count, Q
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse
|
||||
from django.views.generic import View
|
||||
from django_tables2 import RequestConfig
|
||||
@ -686,6 +686,51 @@ class IPAddressEditView(IPAddressCreateView):
|
||||
permission_required = 'ipam.change_ipaddress'
|
||||
|
||||
|
||||
class IPAddressAssignView(PermissionRequiredMixin, View):
|
||||
"""
|
||||
Search for IPAddresses to be assigned to an Interface.
|
||||
"""
|
||||
permission_required = 'ipam.change_ipaddress'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
|
||||
# Redirect user if an interface has not been provided
|
||||
if 'interface' not in request.GET:
|
||||
return redirect('ipam:ipaddress_add')
|
||||
|
||||
return super(IPAddressAssignView, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
def get(self, request):
|
||||
|
||||
form = forms.IPAddressAssignForm()
|
||||
|
||||
return render(request, 'ipam/ipaddress_assign.html', {
|
||||
'form': form,
|
||||
'return_url': request.GET.get('return_url', ''),
|
||||
})
|
||||
|
||||
def post(self, request):
|
||||
|
||||
form = forms.IPAddressAssignForm(request.POST)
|
||||
table = None
|
||||
|
||||
if form.is_valid():
|
||||
|
||||
queryset = IPAddress.objects.select_related(
|
||||
'vrf', 'tenant', 'interface__device', 'interface__virtual_machine'
|
||||
).filter(
|
||||
vrf=form.cleaned_data['vrf'],
|
||||
address__net_host=form.cleaned_data['address'],
|
||||
)
|
||||
table = tables.IPAddressAssignTable(queryset)
|
||||
|
||||
return render(request, 'ipam/ipaddress_assign.html', {
|
||||
'form': form,
|
||||
'table': table,
|
||||
'return_url': request.GET.get('return_url', ''),
|
||||
})
|
||||
|
||||
|
||||
class IPAddressDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
||||
permission_required = 'ipam.delete_ipaddress'
|
||||
model = IPAddress
|
||||
|
@ -1,4 +1,16 @@
|
||||
{% load helpers %}
|
||||
|
||||
<ul class="nav nav-tabs" style="margin-bottom: 20px">
|
||||
<li role="presentation"{% if active_tab == 'add' %} class="active"{% endif %}><a href="{% url 'ipam:ipaddress_add' %}">Individual</a></li>
|
||||
<li role="presentation"{% if active_tab == 'bulk_add' %} class="active"{% endif %}><a href="{% url 'ipam:ipaddress_bulk_add' %}">Bulk</a></li>
|
||||
<li role="presentation"{% if active_tab == 'add' %} class="active"{% endif %}>
|
||||
<a href="{% url 'ipam:ipaddress_add' %}{% querystring request %}">New IP</a>
|
||||
</li>
|
||||
{% if 'interface' in request.GET %}
|
||||
<li role="presentation"{% if active_tab == 'assign' %} class="active"{% endif %}>
|
||||
<a href="{% url 'ipam:ipaddress_assign' %}{% querystring request %}">Assign IP</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li role="presentation"{% if active_tab == 'bulk_add' %} class="active"{% endif %}>
|
||||
<a href="{% url 'ipam:ipaddress_bulk_add' %}{% querystring request %}">Bulk Create</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
48
netbox/templates/ipam/ipaddress_assign.html
Normal file
48
netbox/templates/ipam/ipaddress_assign.html
Normal file
@ -0,0 +1,48 @@
|
||||
{% extends 'utilities/obj_edit.html' %}
|
||||
{% load static from staticfiles %}
|
||||
{% load form_helpers %}
|
||||
{% load helpers %}
|
||||
|
||||
{% block content %}
|
||||
<form action="{% querystring request %}" method="post" class="form form-horizontal">
|
||||
{% csrf_token %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<h3>Assign an IP Address</h3>
|
||||
{% include 'ipam/inc/ipadress_edit_header.html' with active_tab='assign' %}
|
||||
{% if form.non_field_errors %}
|
||||
<div class="panel panel-danger">
|
||||
<div class="panel-heading"><strong>Errors</strong></div>
|
||||
<div class="panel-body">
|
||||
{{ form.non_field_errors }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><strong>Select IP Address</strong></div>
|
||||
<div class="panel-body">
|
||||
{% render_field form.vrf %}
|
||||
{% render_field form.address %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3 text-right">
|
||||
<button type="submit" class="btn btn-primary">Search</button>
|
||||
<a href="{{ return_url }}" class="btn btn-default">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% if table %}
|
||||
<div class="row">
|
||||
<div class="col-md-10 col-md-offset-1" style="margin-top: 20px">
|
||||
<h3>Search Results</h3>
|
||||
{% include 'utilities/obj_table.html' with table_template='panel_table.html' %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
@ -132,7 +132,7 @@ def querystring(request, **kwargs):
|
||||
querydict[k] = v
|
||||
elif k in querydict:
|
||||
querydict.pop(k)
|
||||
querystring = querydict.urlencode()
|
||||
querystring = querydict.urlencode(safe='/')
|
||||
if querystring:
|
||||
return '?' + querystring
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user