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',
|
'IPAddressForm',
|
||||||
'IPRangeForm',
|
'IPRangeForm',
|
||||||
'PrefixForm',
|
'PrefixForm',
|
||||||
|
'PrefixAssignForm',
|
||||||
'RIRForm',
|
'RIRForm',
|
||||||
'RoleForm',
|
'RoleForm',
|
||||||
'RouteTargetForm',
|
'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):
|
class IPRangeForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
|
||||||
vrf = DynamicModelChoiceField(
|
vrf = DynamicModelChoiceField(
|
||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
|
@ -16,6 +16,7 @@ __all__ = (
|
|||||||
'IPAddressTable',
|
'IPAddressTable',
|
||||||
'IPRangeTable',
|
'IPRangeTable',
|
||||||
'PrefixTable',
|
'PrefixTable',
|
||||||
|
'PrefixAssignTable',
|
||||||
'RIRTable',
|
'RIRTable',
|
||||||
'RoleTable',
|
'RoleTable',
|
||||||
)
|
)
|
||||||
@ -43,6 +44,10 @@ PREFIXFLAT_LINK = """
|
|||||||
{% endif %}
|
{% 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 = """
|
IPADDRESS_LINK = """
|
||||||
{% if record.pk %}
|
{% if record.pk %}
|
||||||
<a href="{{ record.get_absolute_url }}">{{ record.address }}</a>
|
<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
|
# IP ranges
|
||||||
#
|
#
|
||||||
|
@ -71,6 +71,7 @@ urlpatterns = [
|
|||||||
path('prefixes/import/', views.PrefixBulkImportView.as_view(), name='prefix_import'),
|
path('prefixes/import/', views.PrefixBulkImportView.as_view(), name='prefix_import'),
|
||||||
path('prefixes/edit/', views.PrefixBulkEditView.as_view(), name='prefix_bulk_edit'),
|
path('prefixes/edit/', views.PrefixBulkEditView.as_view(), name='prefix_bulk_edit'),
|
||||||
path('prefixes/delete/', views.PrefixBulkDeleteView.as_view(), name='prefix_bulk_delete'),
|
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>/', views.PrefixView.as_view(), name='prefix'),
|
||||||
path('prefixes/<int:pk>/edit/', views.PrefixEditView.as_view(), name='prefix_edit'),
|
path('prefixes/<int:pk>/edit/', views.PrefixEditView.as_view(), name='prefix_edit'),
|
||||||
path('prefixes/<int:pk>/delete/', views.PrefixDeleteView.as_view(), name='prefix_delete'),
|
path('prefixes/<int:pk>/delete/', views.PrefixDeleteView.as_view(), name='prefix_delete'),
|
||||||
|
@ -494,6 +494,47 @@ class PrefixIPAddressesView(generic.ObjectView):
|
|||||||
class PrefixEditView(generic.ObjectEditView):
|
class PrefixEditView(generic.ObjectEditView):
|
||||||
queryset = Prefix.objects.all()
|
queryset = Prefix.objects.all()
|
||||||
model_form = forms.PrefixForm
|
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):
|
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