mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-27 10:58:37 -06:00
Move bind exports to specific views with download links
This commit is contained in:
parent
955910b97b
commit
4080c16dd3
@ -24,7 +24,8 @@ urlpatterns = [
|
|||||||
url(r'^records/(?P<pk>\d+)/edit/$', views.RecordEditView.as_view(), name='record_edit'),
|
url(r'^records/(?P<pk>\d+)/edit/$', views.RecordEditView.as_view(), name='record_edit'),
|
||||||
url(r'^records/(?P<pk>\d+)/delete/$', views.RecordDeleteView.as_view(), name='record_delete'),
|
url(r'^records/(?P<pk>\d+)/delete/$', views.RecordDeleteView.as_view(), name='record_delete'),
|
||||||
|
|
||||||
# Full Reverse
|
# BIND Exports
|
||||||
url(r'^reverse/$', views.full_reverse, name='full_reverse'),
|
url(r'^bind/forward/$', views.full_forward, name='full_forward'),
|
||||||
|
url(r'^bind/reverse/$', views.full_reverse, name='full_reverse'),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
@ -15,6 +15,8 @@ from . import filters, forms, tables
|
|||||||
from .models import Zone, Record
|
from .models import Zone, Record
|
||||||
from .tables import RecordZoneTable
|
from .tables import RecordZoneTable
|
||||||
|
|
||||||
|
import StringIO, zipfile, time
|
||||||
|
|
||||||
#
|
#
|
||||||
# Zones
|
# Zones
|
||||||
#
|
#
|
||||||
@ -32,29 +34,17 @@ def zone(request, pk):
|
|||||||
zone = get_object_or_404(Zone.objects.all(), pk=pk)
|
zone = get_object_or_404(Zone.objects.all(), pk=pk)
|
||||||
records = Record.objects.filter(zone=zone)
|
records = Record.objects.filter(zone=zone)
|
||||||
record_count = len(records)
|
record_count = len(records)
|
||||||
bind_export = zone.to_bind(records)
|
|
||||||
|
|
||||||
# DNS records
|
# DNS records
|
||||||
dns_records = Record.objects.filter(zone=zone)
|
dns_records = Record.objects.filter(zone=zone)
|
||||||
dns_records_table = RecordZoneTable(dns_records)
|
dns_records_table = RecordZoneTable(dns_records)
|
||||||
|
|
||||||
if request.GET.get('bind_export'):
|
return render(request, 'dns/zone.html', {
|
||||||
response = HttpResponse(
|
'zone': zone,
|
||||||
bind_export,
|
'records': records,
|
||||||
content_type='text/plain'
|
'record_count': record_count,
|
||||||
)
|
'dns_records_table': dns_records_table,
|
||||||
response['Content-Disposition'] = 'attachment; filename="netbox_{}.txt"'\
|
})
|
||||||
.format(zone.name)
|
|
||||||
return response
|
|
||||||
|
|
||||||
else:
|
|
||||||
return render(request, 'dns/zone.html', {
|
|
||||||
'zone': zone,
|
|
||||||
'records': records,
|
|
||||||
'record_count': record_count,
|
|
||||||
'dns_records_table': dns_records_table,
|
|
||||||
'bind_export': bind_export,
|
|
||||||
})
|
|
||||||
|
|
||||||
class ZoneEditView(PermissionRequiredMixin, ObjectEditView):
|
class ZoneEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
permission_required = 'dns.change_zone'
|
permission_required = 'dns.change_zone'
|
||||||
@ -167,9 +157,57 @@ class RecordBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
default_redirect_url = 'dns:record_list'
|
default_redirect_url = 'dns:record_list'
|
||||||
|
|
||||||
#
|
#
|
||||||
# Full Reverse
|
# BIND Exports
|
||||||
#
|
#
|
||||||
|
|
||||||
|
def bind_export(request, zones_list, context):
|
||||||
|
download = request.GET.get('download')
|
||||||
|
if download:
|
||||||
|
if download == 'all':
|
||||||
|
zbuf = StringIO.StringIO()
|
||||||
|
zfile = zipfile.ZipFile(zbuf, mode='w')
|
||||||
|
temp = []
|
||||||
|
for z in zones_list:
|
||||||
|
temp.append(StringIO.StringIO())
|
||||||
|
temp[len(temp)-1].write(z['content'])
|
||||||
|
zfile.writestr(z['id'],str(temp[len(temp)-1].getvalue()))
|
||||||
|
zfile.close()
|
||||||
|
response = HttpResponse(
|
||||||
|
zbuf.getvalue(),
|
||||||
|
content_type = 'application/zip'
|
||||||
|
)
|
||||||
|
response['Content-Disposition'] = 'attachment; filename="netbox_dns_{}_{}.zip"'.format(context, str(int(time.time())))
|
||||||
|
return response
|
||||||
|
else:
|
||||||
|
response = HttpResponse(
|
||||||
|
zones_list[int(download)]['content'],
|
||||||
|
content_type='text/plain'
|
||||||
|
)
|
||||||
|
response['Content-Disposition'] = 'attachment; filename="{}"'.format(zones_list[int(download)]['id'])
|
||||||
|
return response
|
||||||
|
|
||||||
|
else:
|
||||||
|
return render(request, 'dns/bind_export.html', {
|
||||||
|
'context': context[0].upper() + context[1:],
|
||||||
|
'zones': zones_list,
|
||||||
|
'bind_export_count': len(zones_list),
|
||||||
|
})
|
||||||
|
|
||||||
|
def full_forward(request):
|
||||||
|
|
||||||
|
zones = Zone.objects.all()
|
||||||
|
|
||||||
|
zones_list = []
|
||||||
|
for z in zones:
|
||||||
|
records = Record.objects.filter(zone=z)
|
||||||
|
zones_list.append({
|
||||||
|
'num': len(zones_list),
|
||||||
|
'id': z.name,
|
||||||
|
'content': z.to_bind(records)
|
||||||
|
})
|
||||||
|
|
||||||
|
return bind_export(request, zones_list, 'forward')
|
||||||
|
|
||||||
def full_reverse(request):
|
def full_reverse(request):
|
||||||
|
|
||||||
zones = {}
|
zones = {}
|
||||||
@ -191,7 +229,5 @@ def full_reverse(request):
|
|||||||
'content': zc,
|
'content': zc,
|
||||||
})
|
})
|
||||||
|
|
||||||
return render(request, 'dns/full_reverse.html', {
|
return bind_export(request, zones_list, 'reverse')
|
||||||
'zones': zones_list,
|
|
||||||
'bind_export_count': len(zones_list),
|
|
||||||
})
|
|
||||||
|
@ -281,10 +281,6 @@ def prefix(request, pk):
|
|||||||
# Count child IP addresses
|
# Count child IP addresses
|
||||||
ipaddress_count = child_ip.count()
|
ipaddress_count = child_ip.count()
|
||||||
|
|
||||||
# BIND reverse export
|
|
||||||
bind_export = prefix.to_bind(child_ip)
|
|
||||||
bind_export_count = len(bind_export)
|
|
||||||
|
|
||||||
# Parent prefixes table
|
# Parent prefixes table
|
||||||
parent_prefixes = Prefix.objects.filter(vrf=prefix.vrf, prefix__net_contains=str(prefix.prefix))\
|
parent_prefixes = Prefix.objects.filter(vrf=prefix.vrf, prefix__net_contains=str(prefix.prefix))\
|
||||||
.select_related('site', 'role').annotate_depth()
|
.select_related('site', 'role').annotate_depth()
|
||||||
@ -313,8 +309,6 @@ def prefix(request, pk):
|
|||||||
'parent_prefix_table': parent_prefix_table,
|
'parent_prefix_table': parent_prefix_table,
|
||||||
'child_prefix_table': child_prefix_table,
|
'child_prefix_table': child_prefix_table,
|
||||||
'duplicate_prefix_table': duplicate_prefix_table,
|
'duplicate_prefix_table': duplicate_prefix_table,
|
||||||
'bind_export': bind_export,
|
|
||||||
'bind_export_count': bind_export_count,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,7 +171,8 @@
|
|||||||
<li><a href="{% url 'dns:zone_import' %}"><i class="glyphicon glyphicon-import" aria-hidden="true"></i> Import zones</a></li>
|
<li><a href="{% url 'dns:zone_import' %}"><i class="glyphicon glyphicon-import" aria-hidden="true"></i> Import zones</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="{% url 'dns:full_reverse' %}"><i class="glyphicon glyphicon-search" aria-hidden="true"></i> Full Reverse Export</a></li>
|
<li><a href="{% url 'dns:full_forward' %}"><i class="glyphicon glyphicon-export" aria-hidden="true"></i> BIND Export Forward</a></li>
|
||||||
|
<li><a href="{% url 'dns:full_reverse' %}"><i class="glyphicon glyphicon-export" aria-hidden="true"></i> BIND Export Reverse</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown{% if request.path|startswith:'/ipam/vlan' %} active{% endif %}">
|
<li class="dropdown{% if request.path|startswith:'/ipam/vlan' %} active{% endif %}">
|
||||||
|
@ -1,17 +1,33 @@
|
|||||||
{% extends '_base.html' %}
|
{% extends '_base.html' %}
|
||||||
{% load render_table from django_tables2 %}
|
{% load render_table from django_tables2 %}
|
||||||
|
|
||||||
{% block title %}Full Reverse DNS{% endblock %}
|
{% block title %}BIND Export {{context}}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Full Reverse DNS</h1>
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<a href="?{% if request.GET %}{{ request.GET.urlencode }}&{% endif %}download=all" class="btn btn-success pull-right">
|
||||||
|
<span class="glyphicon glyphicon-export" aria-hidden="true"></span>
|
||||||
|
Download ZIP
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h1 style="margin-bottom: 35px;">BIND Export {{context}}</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{% for z in zones %}
|
{% for z in zones %}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<strong class="text-md-left">{{ z.id }}</strong>
|
<strong class="text-md-left">{{ z.id }}</strong>
|
||||||
<a class="pull-right" id="bind_export_select_{{ z.num }}" href="#">Select</a>
|
<span class="pull-right">
|
||||||
|
<a href="?{% if request.GET %}{{ request.GET.urlencode }}&{% endif %}download={{ z.num }}">Download</a>
|
||||||
|
-
|
||||||
|
<a id="bind_export_select_{{ z.num }}" href="#">Select</a>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<table class="table table-hover panel-body">
|
<table class="table table-hover panel-body">
|
||||||
<tr><td>
|
<tr><td>
|
@ -25,10 +25,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<a href="?{% if request.GET %}{{ request.GET.urlencode }}&{% endif %}bind_export=yes" class="btn btn-success">
|
|
||||||
<span class="glyphicon glyphicon-export" aria-hidden="true"></span>
|
|
||||||
BIND Export
|
|
||||||
</a>
|
|
||||||
{% if perms.dns.change_zone %}
|
{% if perms.dns.change_zone %}
|
||||||
<a href="{% url 'dns:zone_edit' pk=zone.pk %}" class="btn btn-warning">
|
<a href="{% url 'dns:zone_edit' pk=zone.pk %}" class="btn btn-warning">
|
||||||
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
|
||||||
@ -117,36 +113,4 @@
|
|||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<strong class="text-md-left">BIND Export</strong>
|
|
||||||
<a class="pull-right" id="bind_export_select" href="#">Select</a>
|
|
||||||
</div>
|
|
||||||
<table class="table table-hover panel-body">
|
|
||||||
<tr>
|
|
||||||
<td><pre id="bind_export" style="max-width: 100%;">{{ bind_export }}</pre></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
{% block javascript %}
|
|
||||||
<script>
|
|
||||||
$('#bind_export_select').click(function(e){
|
|
||||||
e.preventDefault();
|
|
||||||
if(document.selection) {
|
|
||||||
var range = document.body.createTextRange();
|
|
||||||
range.moveToElementText(document.getElementById('bind_export'));
|
|
||||||
range.select();
|
|
||||||
}
|
|
||||||
else if(window.getSelection) {
|
|
||||||
var range = document.createRange();
|
|
||||||
range.selectNode(document.getElementById('bind_export'));
|
|
||||||
window.getSelection().addRange(range);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -145,47 +145,5 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" style="margin-top: 30px;">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<strong class="text-md-left">BIND Reverse Exports</strong>
|
|
||||||
</div>
|
|
||||||
<table class="table table-hover panel-body">
|
|
||||||
{% for z in bind_export %}
|
|
||||||
<tr><td>
|
|
||||||
<strong class="text-md-left">{{ z.id }}</strong>
|
|
||||||
<a class="pull-right" id="bind_export_select_{{ z.num }}" href="#">Select</a>
|
|
||||||
</td></tr>
|
|
||||||
<tr><td>
|
|
||||||
<pre id="bind_export_{{ z.num }}" style="overflow: auto;">{{ z.content }}</pre>
|
|
||||||
</td></tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
{% block javascript %}
|
|
||||||
<script>
|
|
||||||
for(var i=0;i<{{ bind_export_count }};i++) {
|
|
||||||
$('#bind_export_select_'+i).click(function(e){
|
|
||||||
var i_str = $(this).attr('id');
|
|
||||||
i_str = i_str.substr(i_str.lastIndexOf('_')+1);
|
|
||||||
e.preventDefault();
|
|
||||||
if(document.selection) {
|
|
||||||
var range = document.body.createTextRange();
|
|
||||||
var id='bind_export_'+i_str;
|
|
||||||
range.moveToElementText(document.getElementById(id));
|
|
||||||
range.select();
|
|
||||||
}
|
|
||||||
else if(window.getSelection) {
|
|
||||||
var range = document.createRange();
|
|
||||||
var id='bind_export_'+i_str;
|
|
||||||
range.selectNode(document.getElementById(id));
|
|
||||||
window.getSelection().addRange(range);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user