mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-13 11:08:18 -06:00
netbox-community/netbox#6905: Add prefix-vlan assignment view
This commit is contained in:
parent
e8d6281007
commit
8b510b3b5e
@ -20,6 +20,7 @@ __all__ = (
|
||||
'IPAddressForm',
|
||||
'IPRangeForm',
|
||||
'PrefixForm',
|
||||
'PrefixAssignForm',
|
||||
'RIRForm',
|
||||
'RoleForm',
|
||||
'RouteTargetForm',
|
||||
@ -203,6 +204,23 @@ class PrefixForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
|
||||
}
|
||||
|
||||
|
||||
class PrefixAssignForm(BootstrapMixin, forms.Form):
|
||||
site_id = DynamicModelChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
required=False,
|
||||
label='Site'
|
||||
)
|
||||
vrf_id = DynamicModelChoiceField(
|
||||
queryset=VRF.objects.all(),
|
||||
required=False,
|
||||
label='VRF'
|
||||
)
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
label='Search',
|
||||
)
|
||||
|
||||
|
||||
class IPRangeForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
|
||||
vrf = DynamicModelChoiceField(
|
||||
queryset=VRF.objects.all(),
|
||||
|
@ -16,6 +16,7 @@ __all__ = (
|
||||
'IPAddressTable',
|
||||
'IPRangeTable',
|
||||
'PrefixTable',
|
||||
'PrefixAssignTable',
|
||||
'RIRTable',
|
||||
'RoleTable',
|
||||
)
|
||||
@ -43,6 +44,10 @@ PREFIXFLAT_LINK = """
|
||||
{% endif %}
|
||||
"""
|
||||
|
||||
PREFIX_ASSIGN_LINK = """
|
||||
<a href="{% url 'ipam:prefix_edit' pk=record.pk %}?{% if request.GET.vlan %}vlan={{ request.GET.vlan }}{% endif %}&return_url={{ request.GET.return_url }}">{{ record }}</a>
|
||||
"""
|
||||
|
||||
IPADDRESS_LINK = """
|
||||
{% if record.pk %}
|
||||
<a href="{{ record.get_absolute_url }}">{{ record.address }}</a>
|
||||
@ -246,6 +251,23 @@ class PrefixTable(BaseTable):
|
||||
}
|
||||
|
||||
|
||||
class PrefixAssignTable(BaseTable):
|
||||
prefix = tables.TemplateColumn(
|
||||
template_code=PREFIX_ASSIGN_LINK,
|
||||
verbose_name='Prefix'
|
||||
)
|
||||
status = ChoiceFieldColumn()
|
||||
is_pool = BooleanColumn(
|
||||
verbose_name='Pool'
|
||||
)
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = Prefix
|
||||
fields = ('prefix', 'site', 'vrf', 'tenant', 'status', 'role', 'vlan', 'is_pool', 'description')
|
||||
exclude = ('id', )
|
||||
orderable = False
|
||||
|
||||
|
||||
#
|
||||
# IP ranges
|
||||
#
|
||||
|
@ -71,6 +71,7 @@ urlpatterns = [
|
||||
path('prefixes/import/', views.PrefixBulkImportView.as_view(), name='prefix_import'),
|
||||
path('prefixes/edit/', views.PrefixBulkEditView.as_view(), name='prefix_bulk_edit'),
|
||||
path('prefixes/delete/', views.PrefixBulkDeleteView.as_view(), name='prefix_bulk_delete'),
|
||||
path('prefixes/assign/', views.PrefixAssignView.as_view(), name='prefix_assign'),
|
||||
path('prefixes/<int:pk>/', views.PrefixView.as_view(), name='prefix'),
|
||||
path('prefixes/<int:pk>/edit/', views.PrefixEditView.as_view(), name='prefix_edit'),
|
||||
path('prefixes/<int:pk>/delete/', views.PrefixDeleteView.as_view(), name='prefix_delete'),
|
||||
|
@ -494,6 +494,47 @@ class PrefixIPAddressesView(generic.ObjectView):
|
||||
class PrefixEditView(generic.ObjectEditView):
|
||||
queryset = Prefix.objects.all()
|
||||
model_form = forms.PrefixForm
|
||||
template_name = 'ipam/prefix_edit.html'
|
||||
|
||||
|
||||
# TODO: Standardize or remove this view
|
||||
class PrefixAssignView(generic.ObjectView):
|
||||
"""
|
||||
Search for Prefixes to assign to a VLAN
|
||||
"""
|
||||
queryset = Prefix.objects.all()
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
|
||||
# Redirect the user if a VLAN has not been provided
|
||||
if 'vlan' not in request.GET:
|
||||
return redirect('ipam:prefix_add')
|
||||
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get(self, request):
|
||||
form = forms.PrefixAssignForm()
|
||||
|
||||
return render(request, 'ipam/prefix_assign.html', {
|
||||
'form': form,
|
||||
'return_url': request.GET.get('return_url', ''),
|
||||
})
|
||||
|
||||
def post(self, request):
|
||||
form = forms.PrefixAssignForm(request.POST)
|
||||
table = None
|
||||
|
||||
if form.is_valid():
|
||||
prefixes = self.queryset.prefetch_related('site', 'vrf', 'tenant')
|
||||
# Limit to 100 results
|
||||
prefixes = filtersets.PrefixFilterSet(request.POST, prefixes).qs[:100]
|
||||
table = tables.PrefixAssignTable(prefixes)
|
||||
|
||||
return render(request, 'ipam/prefix_assign.html', {
|
||||
'form': form,
|
||||
'table': table,
|
||||
'return_url': request.GET.get('return_url'),
|
||||
})
|
||||
|
||||
|
||||
class PrefixDeleteView(generic.ObjectDeleteView):
|
||||
|
22
netbox/templates/ipam/inc/prefix_edit_header.html
Normal file
22
netbox/templates/ipam/inc/prefix_edit_header.html
Normal file
@ -0,0 +1,22 @@
|
||||
{% load helpers %}
|
||||
|
||||
<ul class="nav nav-tabs px-3">
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link {% if active_tab == 'add' %}active{% endif %}"
|
||||
href="{% url 'ipam:prefix_add' %}{% querystring request %}"
|
||||
>
|
||||
{% if obj.pk %}Edit{% else %}Create{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% if 'vlan' in request.GET %}
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link {% if active_tab == 'assign' %}active{% endif %}"
|
||||
href="{% url 'ipam:prefix_assign' %}{% querystring request %}"
|
||||
>
|
||||
Assign Prefix
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
46
netbox/templates/ipam/prefix_assign.html
Normal file
46
netbox/templates/ipam/prefix_assign.html
Normal file
@ -0,0 +1,46 @@
|
||||
{% extends 'generic/object_edit.html' %}
|
||||
{% load static %}
|
||||
{% load form_helpers %}
|
||||
{% load helpers %}
|
||||
|
||||
{% block title %}Assign a Prefix{% endblock title %}
|
||||
|
||||
{% block tabs %}
|
||||
{% include 'ipam/inc/prefix_edit_header.html' with active_tab='assign' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block form %}
|
||||
<form action="{% querystring request %}" method="post" class="form form-horizontal">
|
||||
{% csrf_token %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
<div class="row mb-3">
|
||||
<div class="col col-md-8 offset-md-2">
|
||||
<div class="field-group">
|
||||
<h6>Select Prefix</h6>
|
||||
{% render_field form.site_id %}
|
||||
{% render_field form.vrf_id %}
|
||||
{% render_field form.q %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col col-md-8 offset-md-2 text-end">
|
||||
<a href="{{ return_url }}" class="btn btn-outline-danger">Cancel</a>
|
||||
<button type="submit" class="btn btn-primary">Search</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% if table %}
|
||||
<div class="row mb-3">
|
||||
<div class="col col-md-12">
|
||||
<h3>Search Results</h3>
|
||||
{% include 'utilities/obj_table.html' %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock form %}
|
||||
|
||||
{% block buttons %}
|
||||
{% endblock buttons%}
|
8
netbox/templates/ipam/prefix_edit.html
Normal file
8
netbox/templates/ipam/prefix_edit.html
Normal file
@ -0,0 +1,8 @@
|
||||
{% extends 'generic/object_edit.html' %}
|
||||
{% load static %}
|
||||
{% load form_helpers %}
|
||||
{% load helpers %}
|
||||
|
||||
{% block tabs %}
|
||||
{% include 'ipam/inc/prefix_edit_header.html' with active_tab='add' %}
|
||||
{% endblock tabs %}
|
Loading…
Reference in New Issue
Block a user